Mahout0.9版本第八周作业

书面作业那边修改不了,就发个帖子把作业做了吧我用的是Hadoop2.4.0+Mahout0.9+Pig0.13.0,所以课件中的方法都不适用了,要全部重新搞

首先是用sport构造bayes和cbayes分类器,这步可以直接参照examples/binclassify-20newsgroups.sh通过Mahout脚本实现
  1. ##1.将分类文章序列化
  2. mahout seqdirectory 
  3. -i /bayes/sport 
  4. -o /bayes/sport-seq -ow

  5. ##2.分词处理
  6. mahout seq2sparse 
  7. -i /bayes/sport-seq 
  8. -o /bayes/sport-vectors  -lnorm -nv  -wt tfidf

  9. ##3.拆分成训练集和测试集
  10. mahout split 
  11. -i /bayes/sport-vectors/tfidf-vectors 
  12. --trainingOutput /bayes/sport-train-vectors 
  13. --testOutput /bayes/sport-test-vectors  
  14. --randomSelectionPct 40 --overwrite --sequenceFiles -xm sequential

  15. ##4.训练bayes分类器
  16. mahout trainnb 
  17. -i /bayes/sport-train-vectors -el 
  18. -o /bayes/model 
  19. -li /bayes/labelindex 
  20. -ow

  21. ##5.测试bayes分类器
  22. mahout testnb 
  23. -i /bayes/sport-test-vectors 
  24. -m /bayes/model 
  25. -l /bayes/labelindex 
  26. -ow -o /bayes/sport-testing

  27. /*
  28. =======================================================
  29. Summary
  30. -------------------------------------------------------
  31. Correctly Classified Instances          :       3824       95.5761%
  32. Incorrectly Classified Instances        :        177        4.4239%
  33. Total Classified Instances              :       4001

  34. =======================================================
  35. Confusion Matrix
  36. -------------------------------------------------------
  37. a       b       c       d       e       f       g       h       i       j       <--Classified as
  38. 372     0       0       0       0       3       2       2       0       0        |  379         a     = badminton
  39. 3       376     4       3       6       11      1       4       1       2        |  411         b     = basketball
  40. 16      0       428     1       2       15      1       1       6       2        |  472         c     = billiards
  41. 1       0       1       390     0       7       0       0       1       0        |  400         d     = f1
  42. 0       0       0       0       405     2       1       0       3       0        |  411         e     = football
  43. 2       0       3       2       3       350     0       0       7       0        |  367         f     = golf
  44. 0       0       0       0       1       1       381     1       0       0        |  384         g     = pingpong
  45. 4       0       0       1       0       5       0       372     0       1        |  383         h     = swim
  46. 7       1       1       2       0       12      3       7       372     1        |  406         i     = tennis
  47. 1       1       0       0       1       1       0       2       4       378      |  388         j     = volleyball

  48. =======================================================
  49. Statistics
  50. -------------------------------------------------------
  51. Kappa                                       0.9346
  52. Accuracy                                   95.5761%
  53. Reliability                                87.0107%
  54. Reliability (standard deviation)            0.2902
  55. */

  56. ##6.训练cbayes分类器
  57. mahout trainnb 
  58. -i /bayes/sport-train-vectors -el 
  59. -o /bayes/model-cbayes 
  60. -li /bayes/labelindex 
  61. -ow -c

  62. ##7.测试cbayes分类器
  63. mahout testnb 
  64. -i /bayes/sport-test-vectors 
  65. -m /bayes/model-cbayes 
  66. -l /bayes/labelindex 
  67. -ow -o /bayes/sport-c-testing 
  68. -c

  69. /*
  70. =======================================================
  71. Summary
  72. -------------------------------------------------------
  73. Correctly Classified Instances          :       3815       95.3512%
  74. Incorrectly Classified Instances        :        186        4.6488%
  75. Total Classified Instances              :       4001

  76. =======================================================
  77. Confusion Matrix
  78. -------------------------------------------------------
  79. a       b       c       d       e       f       g       h       i       j       <--Classified as
  80. 375     0       0       1       0       1       0       2       0       0        |  379         a     = badminton
  81. 0       387     1       6       10      4       1       2       0       0        |  411         b     = basketball
  82. 10      1       435     0       4       13      2       0       6       1        |  472         c     = billiards
  83. 1       0       1       394     1       3       0       0       0       0        |  400         d     = f1
  84. 0       0       1       2       406     1       0       0       0       1        |  411         e     = football
  85. 1       0       1       4       10      348     0       0       3       0        |  367         f     = golf
  86. 0       0       0       0       1       0       382     1       0       0        |  384         g     = pingpong
  87. 1       0       0       1       0       3       0       378     0       0        |  383         h     = swim
  88. 6       3       5       7       11      17      2       6       349     0        |  406         i     = tennis
  89. 2       3       0       3       6       2       5       2       4       361      |  388         j     = volleyball

  90. =======================================================
  91. Statistics
  92. -------------------------------------------------------
  93. Kappa                                       0.9329
  94. Accuracy                                   95.3512%
  95. Reliability                                86.7771%
  96. Reliability (standard deviation)            0.2907
  97. */
复制代码


构造好分类器,接下来就是如何用它去进行分类,这一步浪费了好多时间搜资料、看源代码,中间也遇到了很多问题,就不细说了,最终在老师提供的源码基础上做了些修改终于整出一个结果,当然还有许多需要优化的地方,欢迎大家共同讨论完善
1、先对user-sport序列化并进行分词处理
  1. mahout seqdirectory 
  2. -i /bayes/user-sport 
  3. -o /bayes/us-seq -ow

  4. mahout seq2sparse 
  5. -i /bayes/us-seq 
  6. -o /bayes/us-vectors  -lnorm -nv  -wt tfidf
复制代码
2、修改 ClassifierDriver类,可参照mahout0.9源码中core里的 org.apache.mahout.classifier.naivebayes.test.TestNaiveBayesDriver
这步本来想像mahout一样通过-i、-o这种方式传参数进去的,但是 getOption的时候总是报空指针异常,也没找到是哪的问题,所以直接把参数都写死在程序里了
  1. public class ClassifierDriver extends AbstractJob {

  2.         public static void main(String[] args) throws Exception {
  3.                 ToolRunner.run(new Configuration(), new ClassifierDriver(),args); 
  4.         }

  5.         @Override
  6.         public int run(String[] args) throws Exception {
  7.                 // set bayes parameter
  8.                 addInputOption();
  9.                 addOutputOption();
  10.                 addOption("model", "m", "The path to the model built during training",
  11.                                 true);
  12.                 addOption("labelIndex","labelIndex", "The file where the index store ");
  13.                 addOption("labelNumber", "ln", "The labels number ");

  14.                 //Path input = getInputPath();
  15.                 //Path output = getOutputPath();
  16.                 Path input = new Path("/bayes/us-vectors/tfidf-vectors");//分词后的user-sport
  17.                 Path output = new Path("/bayes/user-output");
  18.                 //String labelNumber = getOption("labelNumber");
  19.                 String labelNumber = "10";//分类个数
  20.                 //String modelPath = getOption("model");
  21.                 String modelPath = "/bayes/model-cbayes";//贝叶斯分类器模型
  22.                 String labelIndex = "/bayes/labelindex";
  23.                 Configuration conf = getConf();
  24.                 conf.set(WeightsMapper.class.getName() + ".numLabels", labelNumber);
  25.                 conf.set("labelIndex", labelIndex);
  26.                 HadoopUtil.cacheFiles(new Path(modelPath), conf);
  27.                 HadoopUtil.delete(conf, output);
  28.                 Job job = new Job(conf);
  29.                 job.setJobName("Use bayesian model to classify the  input:"
  30.                                 + input.getName());
  31.                 job.setJarByClass(ClassifierDriver.class);

  32.                 job.setInputFormatClass(SequenceFileInputFormat.class);

  33.                 //set Map&Reduce
  34.                 job.setMapperClass(ClassifierMapper.class);
  35.                 job.setReducerClass(ClassifierReducer.class);
  36.                 
  37.                 job.setOutputKeyClass(NullWritable.class);
  38.                 job.setOutputValueClass(Text.class);
  39.                 job.setMapOutputKeyClass(Text.class);
  40.                 job.setMapOutputValueClass(IntWritable.class);
  41.                 
  42.                 SequenceFileInputFormat.setInputPaths(job, input);
  43.                 SequenceFileOutputFormat.setOutputPath(job, output);

  44.                 if (job.waitForCompletion(true)) {
  45.                         return 0;
  46.                 }
  47.                 return -1;
  48.         }
  49. }
复制代码
3、修改Mapper,调用模型分类,并且按用户、类别进行计数
  1. public class ClassifierMapper extends Mapper<Text, VectorWritable, Text, IntWritable> {

  2.         private Text outKey = new Text();
  3.         private static final IntWritable ONE = new IntWritable(1);

  4.         private AbstractNaiveBayesClassifier classifier;
  5.         private String labelIndex;
  6.         private Map<Integer, String> labelMap;
  7.         /**
  8.          * Parallel Classification
  9.          * 
  10.          * @param key
  11.          *            The label
  12.          * @param value
  13.          *            the features (all unique) associated w/ this label
  14.          * @param context
  15.          */
  16.         public void map(Text key, VectorWritable value, Context context) throws IOException,
  17.                         InterruptedException {

  18.                 String userID = key.toString().split("/")[1];
  19.                 Vector result = classifier.classifyFull(value.get());
  20.                 String label = BayesUtil.classifyVector(result, labelMap);                
  21.                 // key is userID and label
  22.                 outKey.set(userID + "|" + label);
  23.                 context.write(outKey, ONE);
  24.         }

  25.         /**
  26.          * read the model
  27.          * 
  28.          * @throws IOException
  29.          */
  30.         @Override
  31.         public void setup(Context context) throws IOException {
  32.                 System.out.println("Setup");  
  33.         Configuration conf = context.getConfiguration();  
  34.         Path modelPath = HadoopUtil.getSingleCachedFile(conf);  
  35.         labelIndex=conf.get("labelIndex");
  36.         labelMap = BayesUtils.readLabelIndex(conf, new Path(labelIndex)); 
  37.         NaiveBayesModel model = NaiveBayesModel.materialize(modelPath, conf);          
  38.         classifier = new StandardNaiveBayesClassifier(model);  
  39.         }
复制代码
4、Reducer部分没有修改,输出格式跟讲课内容一致,用户ID|类别|次数,部分输出结果如下
  1. 10511838|badminton|19
  2. 10511838|basketball|1
  3. 10511838|f1|10
  4. 10511838|football|4
  5. 10511838|golf|25
  6. 10511838|swim|1
  7. 10511838|tennis|1
  8. 10511838|volleyball|1
  9. 10564290|badminton|25
  10. 10564290|basketball|3
  11. 10564290|f1|5
  12. 10564290|football|2
  13. 10564290|golf|46
  14. 10564290|pingpong|5
  15. 10564290|tennis|1
  16. 10564290|volleyball|1
复制代码
5、接下来就没什么难度了,用Pig计算每个用户浏览各类文章的占比
  1. --读入数据
  2. u_ct = load '/bayes/user-output' using PigStorage('|') as (user:chararray, category:chararray, times:int);

  3. --分用户计数
  4. u_count = foreach(group u_ct by user)
  5. {
  6.         generate flatten(group) as user, SUM(u_ct.times) as sum;
  7. };

  8. --表连接
  9. u_join = join u_ct by user,u_count by user USING 'replicated';

  10. --计算百分比
  11. u_out = foreach u_join 
  12. generate u_ct::user as user,u_ct::category as category,u_ct::times as times,
  13. (double)u_ct::times/(double)u_count::sum*100 as p;

  14. --输出结果
  15. store u_out into '/bayes/user-sport-out';
复制代码
部分输出结果
  1. 10511838        badminton        19        30.64516129032258
  2. 10511838        basketball        1        1.6129032258064515
  3. 10511838        f1        10        16.129032258064516
  4. 10511838        football        4        6.451612903225806
  5. 10511838        golf        25        40.32258064516129
  6. 10511838        swim        1        1.6129032258064515
  7. 10511838        tennis        1        1.6129032258064515
  8. 10511838        volleyball        1        1.6129032258064515
  9. 10564290        badminton        25        28.40909090909091
  10. 10564290        basketball        3        3.4090909090909087
  11. 10564290        f1        5        5.681818181818182
  12. 10564290        football        2        2.272727272727273
  13. 10564290        golf        46        52.27272727272727
  14. 10564290        pingpong        5        5.681818181818182
  15. 10564290        tennis        1        1.1363636363636365
  16. 10564290        volleyball        1        1.1363636363636365
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值