执行步骤:
数据准备
将新闻文件解压后整个放到hdfs中去:
1
hadoop fs -put mini_newsgroups ./newsgroups
将文本文件转换为序列化文件:
1
mahout seqdirectory -i ./newsgroups -o ./newsgroups_seq
将序列化文件转换为向量化文件:
1
mahout seq2sparse -i ./newsgroups_seq -o ./newsgroups_vector -lnorm -nv -wt tfidf
将向量数据集分为训练数据和检测数据,以随机40-60拆分
1
2
3
4
5mahout split -i ./newsgroups_vector/tfidf-vectors \
--trainingOutput ./newsgroups_train \
--testOutput ./newsgroups_test \
--randomSelectionPct 40 --overwrite \
--sequenceFiles -xm sequential
训练
- 训练朴素贝叶斯模型:
1
2mahout trainnb -i ./newsgroups_train -el -o ./model \
-li ./labelindex -ow -c
- 训练朴素贝叶斯模型:
检验
检验朴素贝叶斯模型:
1
2mahout testnb -i ./newsgroups_train -m ./model \
-l ./labelindex -ow -o newsgroups_result1检验模型分类效果:
1
2mahout testnb -i ./newsgroups_test -m ./model
-l ./labelindex -ow -o ./newsgroups_result2
打印结果
- 将检验结果的序列化文件转换为文本文件
1
mahout seqdumper -i ./newsgroups_result2/part-m-00000 -o ./newsgroups.res
- 将检验结果的序列化文件转换为文本文件
其中:
第1步所需的数据集从http://www.cs.cmu.edu/afs/cs/project/theo-11/www/naive-bayes.html下载
第1步生成的向量化文件的目录结构是这样的:
df-count 目录:保存着文本的频率信息
tf-vectors 目录:保存着以 TF 作为权值的文本向量
tfidf-vectors 目录:保存着以 TFIDF 作为权值的文本向量
tokenized-documents 目录:保存着分词过后的文本信息
wordcount 目录:保存着全局的词汇出现的次数
dictionary.file-0 目录:保存着这些文本的词汇表
frequcency-file-0 目录 : 保存着词汇表对应的频率信息。
来源: http://blog.csdn.net/aidayei/article/details/6674135
第3步正常运行的结果应该会看到一个矩阵,叫confision matrix,即混合矩阵,包含了分类的结果。
此外,每一个命令,可以通过加上“-h”来查看所需参数及含义,如
mahout seqdirectory -h
在此过程中我遇到的错误如下:
Caused by: java.io.IOException: Task process exit with nonzero status of 1
解决:情况不明,换了一个集群就没有这个错误了,网上有说或是hadoop的日志文件需要清除,或是日志文件夹的权限不够需要赋权限777,或是hdfs下的temp目录已满需要清除,或是内存不足需要设置hadoop参数的值或者运行命令改变java的内存限制,或是程序本身有问题。Caused by: java.io.IOException: Task process exit with nonzero status of 126
解决:情况不明,貌似是内存不足的问题。在出现第一个问题之后换了一个集群才出现这个错误,但有时又不出现,而出现的时候我用free命令看了下,貌似内存确实在变小,但我上网一查,发现linux有个机制——内存不用白不用,因此它尽可能的cache和buffer一些数据,以方便下次使用。但实际上这些内存也是可以立刻拿来使用的。
至于为什么会出现以上提示,经上网查询得到如下结果:
通过分析hadoop 1.0.1代码,发现map/reduce task在执行的时候,hadoop系统会先把要执行的java 命令已经一些环境变量写到一个本地的sh文件taskjvm.sh中,然后使用bash -c file的方式执行这个sh脚本,如果出错当然后抛出异常,进而导致看到
Caused by: java.io.IOException: Task process exit with nonzero status of 126.
at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:258)
这样的错误
所以,这个exitcode实际就是bash执行时的推出代码,bash的exitcode是有特殊含义的,通过google可以知道126表明是permission的问题,具体为啥是这样的,不是很清楚了~~
上面的那个文件在创建的是权限是700(rwx——), 而这个文件在执行的过程中又被以setsid的方式exec,会不会这中间有些permission上的问题那~~~ 源码里说了,这样做是为了防止special character attacks
好吧水平有限,看不出来这里有什么竞争条件导致出现那样的错误
bash的退出码含义可以在下面的地方查到
http://tldp.org/LDP/abs/html/exitcodes.html
这个问题可以修改hadoop源码DefaultTaskControl加入重试机制,或者对task启用reuse=-1得到缓解(reuse和非reuse执行逻辑不一样),因为涉及到文件系统,不太容易根治。
来源: http://hi.baidu.com/liusc/item/e54bcd1778ded225f7625c4e