分享

Hadoop上的中文分词与词频统计实践

本帖最后由 坎蒂丝_Swan 于 2015-1-23 17:43 编辑
问题导读

1.本文使用的是什么框架?
2.IKAnalyzer与中文分词方法有什么不同?





首先来推荐相关材料:http://xiaoxia.org/2011/12/18/map-reduce-program-of-rmm-word-count-on-hadoop/。小虾的这个统计武侠小说人名热度的段子很有意思,照虎画猫来实践一下。

与其不同的地方有:
  0)其使用Hadoop Streaming,这里使用MapReduce框架。
  1)不同的中文分词方法,这里使用IKAnalyzer,主页在http://code.google.com/p/ik-analyzer/
  2)这里的材料为《射雕英雄传》。哈哈,总要来一些改变。

0)使用WordCount源代码,修改其Map,在Map中使用IKAnalyzer的分词功能。
  1. import java.io.IOException;
  2. import java.io.InputStream;
  3. import java.io.InputStreamReader;
  4. import java.io.Reader;
  5. import java.io.ByteArrayInputStream;
  6. import org.wltea.analyzer.core.IKSegmenter;
  7. import org.wltea.analyzer.core.Lexeme;
  8. import org.apache.hadoop.conf.Configuration;
  9. import org.apache.hadoop.fs.Path;
  10. import org.apache.hadoop.io.IntWritable;
  11. import org.apache.hadoop.io.Text;
  12. import org.apache.hadoop.mapreduce.Job;
  13. import org.apache.hadoop.mapreduce.Mapper;
  14. import org.apache.hadoop.mapreduce.Reducer;
  15. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  16. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  17. import org.apache.hadoop.util.GenericOptionsParser;
  18. public class ChineseWordCount {
  19.    
  20.       public static class TokenizerMapper
  21.            extends Mapper<Object, Text, Text, IntWritable>{
  22.         
  23.         private final static IntWritable one = new IntWritable(1);
  24.         private Text word = new Text();
  25.          
  26.         public void map(Object key, Text value, Context context
  27.                         ) throws IOException, InterruptedException {
  28.             
  29.             byte[] bt = value.getBytes();
  30.             InputStream ip = new ByteArrayInputStream(bt);
  31.             Reader read = new InputStreamReader(ip);
  32.             IKSegmenter iks = new IKSegmenter(read,true);
  33.             Lexeme t;
  34.             while ((t = iks.next()) != null)
  35.             {
  36.                 word.set(t.getLexemeText());
  37.                 context.write(word, one);
  38.             }
  39.         }
  40.       }
  41.   
  42.   public static class IntSumReducer
  43.        extends Reducer<Text,IntWritable,Text,IntWritable> {
  44.     private IntWritable result = new IntWritable();
  45.     public void reduce(Text key, Iterable<IntWritable> values,
  46.                        Context context
  47.                        ) throws IOException, InterruptedException {
  48.       int sum = 0;
  49.       for (IntWritable val : values) {
  50.         sum += val.get();
  51.       }
  52.       result.set(sum);
  53.       context.write(key, result);
  54.     }
  55.   }
  56.   public static void main(String[] args) throws Exception {
  57.     Configuration conf = new Configuration();
  58.     String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
  59.     if (otherArgs.length != 2) {
  60.       System.err.println("Usage: wordcount <in> <out>");
  61.       System.exit(2);
  62.     }
  63.     Job job = new Job(conf, "word count");
  64.     job.setJarByClass(ChineseWordCount.class);
  65.     job.setMapperClass(TokenizerMapper.class);
  66.     job.setCombinerClass(IntSumReducer.class);
  67.     job.setReducerClass(IntSumReducer.class);
  68.     job.setOutputKeyClass(Text.class);
  69.     job.setOutputValueClass(IntWritable.class);
  70.     FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
  71.     FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
  72.     System.exit(job.waitForCompletion(true) ? 0 : 1);
  73.   }
  74. }
复制代码

1)So,完成了,本地插件模拟环境OK。打包(带上分词包)扔到集群上。
  1. hadoop fs -put chinese_in.txt chinese_in.txt
  2. hadoop jar WordCount.jar chinese_in.txt out0
  3. ...mapping reducing...
  4. hadoop fs -ls ./out0
  5. hadoop fs -get part-r-00000 words.txt
复制代码

2)数据后处理:
2.1)数据排序
  1. head words.txt
  2. tail words.txt
  3. sort -k2 words.txt >0.txt
  4. head 0.txt
  5. tail 0.txt
  6. sort -k2r words.txt>0.txt
  7. head 0.txt
  8. tail 0.txt
  9. sort -k2rn words.txt>0.txt
  10. head -n 50 0.txt
复制代码

2.2)目标提取
  1. awk '{if(length($1)>=2) print $0}' 0.txt >1.txt
复制代码

2.3)结果呈现
  1. head 1.txt -n 50 | sed = | sed 'N;s/\n//'
复制代码
  1. 1郭靖   6427
  2. 2黄蓉   4621
  3. 3欧阳   1660
  4. 4甚么   1430
  5. 5说道   1287
  6. 6洪七公 1225
  7. 7笑道   1214
  8. 8自己   1193
  9. 9一个   1160
  10. 10师父  1080
  11. 11黄药师        1059
  12. 12心中  1046
  13. 13两人  1016
  14. 14武功  950
  15. 15咱们  925
  16. 16一声  912
  17. 17只见  827
  18. 18他们  782
  19. 19心想  780
  20. 20周伯通        771
  21. 21功夫  758
  22. 22不知  755
  23. 23欧阳克        752
  24. 24听得  741
  25. 25丘处机        732
  26. 26当下  668
  27. 27爹爹  664
  28. 28只是  657
  29. 29知道  654
  30. 30这时  639
  31. 31之中  621
  32. 32梅超风        586
  33. 33身子  552
  34. 34都是  540
  35. 35不是  534
  36. 36如此  531
  37. 37柯镇恶        528
  38. 38到了  523
  39. 39不敢  522
  40. 40裘千仞        521
  41. 41杨康  520
  42. 42你们  509
  43. 43这一  495
  44. 44却是  478
  45. 45众人  476
  46. 46二人  475
  47. 47铁木真        469
  48. 48怎么  464
  49. 49左手  452
  50. 50地下  448
复制代码

在非人名词中有很多很有意思,如:5说道7笑道12心中17只见22不知30这时49左手。



欢迎加入about云群90371779322273151432264021 ,云计算爱好者群,亦可关注about云腾讯认证空间||关注本站微信

已有(4)人评论

跳转到指定楼层
pengsuyun 发表于 2015-1-23 19:28:39
好东西,先收下了。
回复

使用道具 举报

hery 发表于 2015-1-24 09:36:58
回复

使用道具 举报

stark_summer 发表于 2015-1-24 10:00:26
回复

使用道具 举报

Joker 发表于 2015-1-24 17:59:03
可以提供数据源的下载地址?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条