【甘道夫】通过Mahout构建贝叶斯文本分类器案例详解


背景&目标: 1、sport.tar 是体育类的文章,一共有10个类别;    用这些原始材料构造一个体育类的文本分类器,并测试对比bayes和cbayes的效果;    记录分类器的构造过程和测试结果。 2、user-sport.tar 是用户浏览的文章,每个文件夹对应一个用户;    利用上题构造的文本分类器,计算每个用户浏览各类文章的占比;    记录计算过程和结果。

实验环境: Hadoop-1.2.1 Mahout0.6 Pig0.12.1 Ubuntu12 Jdk1.7

原理&流程 建立文本分类器 1.分类体系的确定 2.文本样本的积累 3.文本的预处理(分词) 4.划分训练集,测试集 5.对模型的训练 6.对模型准确性测试
测试分类器模型时,如果觉得模型效果不够满意,可以对过程进行调整,然后重新生成模型。 可调整的方面包括: 不断重复以上过程,直到得到满意的模型为止。
对文本进行分类: 建立完文本分类器以后,就可以输入一个文本,输出一个分类。

Step1:将所需用到的原始数据sport和user-sport文件夹上传到hdfs
sport文件夹:
  • 用于训练文本分类器
  • 包含了多个子文件夹,每个子文件夹都是一个分类的文章
  • 在现实项目中,该原始数据需要人工收集
user-sport:
  • 待分类的文本





注意:user-sport文件夹下的子文件夹名称是用户id,子文件夹内包含了多个文本文件,都是该用户浏览过的文章。


step2:对sport文件夹进行分词 用到MRTokenize.jar中的tokenize.TokenizeDriver








到此为止,原始数据已经分好词,并且已经处理成Mahout训练文本分类器要求的输入格式:
  • 每行一篇文章
  • 每行的格式为:分类名称 文章分词结果


Step3:划分训练集和测试集 我们把经过分词处理的原始数据划分为训练集和测试集,训练集用于训练模型,测试集用于测试模型效果。 该过程通过pig实现: grunt> processed = load'/dataguru/hadoopdev/week8/fenciout/part-r-00000' as (category:chararray,doc:chararray); grunt> test = sample processed 0.2; grunt> jnt = join processed by (category,doc) left outer, test by (category,doc); grunt> filt_test = filter jnt by test::category is null; grunt> train = foreach filt_test generate processed::category as category,processed::doc as doc; grunt> store test into '/dataguru/hadoopdev/week8/test';
grunt> store train into '/dataguru/hadoopdev/week8/train';
结果截图:  

Step4:训练贝叶斯模型 我们分别训练bayes模型和cbayes模型,后面测试两者的效果做对比。
首先训练bayes模型: casliyang@singlehadoop:~$ mahout trainclassifier -i /dataguru/hadoopdev/week8/train -o /dataguru/hadoopdev/week8/model-bayes -type bayes -ng 1 -source hdfs
  然后训练cbayes模型: casliyang@singlehadoop:~$ mahout trainclassifier -i /dataguru/hadoopdev/week8/train -o /dataguru/hadoopdev/week8/model-cbayes -type cbayes -ng 1 -source hdfs
训练结果:  

Step5:测试模型 测试贝叶斯模型命令如下: casliyang@singlehadoop:~$ mahout testclassifier -d /dataguru/hadoopdev/week8/test -m /dataguru/hadoopdev/week8/model-bayes -type bayes -ng 1 -source hdfs -method mapreduce
测试结果:  
测试C贝叶斯模型命令如下: casliyang@singlehadoop:~$ mahout testclassifier -d /dataguru/hadoopdev/week8/test -m /dataguru/hadoopdev/week8/model-cbayes -type cbayes -ng 1 -source hdfs -method mapreduce
测试结果:  

Step5:处理待分类数据 我们的待分类数据全存储在user-sport文件夹下,每个子文件夹都存储了一个用户浏览过的文章,子文件夹的名称就是用户id:  


Mahout的文本分类器要求输入数据为分词后的文章,我们直接使用训练分类器时用到的MRTokenize.jar中的tokenize.TokenizeDriver来对文章进行分词,输出格式为:
  • 每行一篇文章
  • 每行的格式为:用户ID 文章分词结果

执行命令对待分类数据进行分词: casliyang@singlehadoop:~/Myfiles$ hadoop jar MRTokenize.jar tokenize.TokenizeDriver /dataguru/hadoopdev/week8/user-sport /dataguru/hadoopdev/week8/user-sport-fenciout
结果:  

Step6:Hadoop环境下,对待分类数据进行分类,并统计每个用户浏览每个分类的次数 Hadoop环境下调用Mahout分类器的程序细节参见: 第八周(4)文本挖掘-贝叶斯-Mahout 将程序打jar包后拷贝到集群上执行。
执行命令对待分类数据进行分类: casliyang@singlehadoop:~/Myfiles$ hadoop jar MRClassify.jar classifier.ClassifierDriver /dataguru/hadoopdev/week8/user-sport-fenciout /dataguru/hadoopdev/week8/user-sport-bayesout /dataguru/hadoopdev/week8/model-bayes bayes
说明: 参数1:输入路径,即上一步分词处理好的待分类的文章存储路径 参数2:输出路径,即统计好的用户浏览各个分类的数量 参数3:模型所在路径 参数4:模型的算法


分类并统计的结果:   结果的每行格式:用户ID | 分类 | 浏览次数


Step6:处理上一步的输出数据,得到每个用户访问次数最多的分类 使用pig处理: grunt> u_ct = load'/dataguru/hadoopdev/week8/user-sport-bayesout' using PigStorage('|') as (user:chararray, category:chararray, times:int); grunt> u_stat = foreach(group u_ct by user) >> { >> sorted = order u_ct by times desc; >> top = limit sorted 1; >> generate flatten(top),SUM(u_ct.times); >> }; grunt> store u_stat into '/dataguru/hadoopdev/week8/user-sport-pigout'; 
结果(第一列是用户id,第二列是浏览量最多的类别,第三列是该类别的浏览次数,第四列是该用户总共的浏览量):  

相关内容

    暂无相关文章