当前位置:   article > 正文

hadoop学习【8】——基于hadoop的分词程序二(ICTCLAS分词器)_ictclas停用词

ictclas停用词

0、【前言今天下午坑了我一下午,总算在hadoop上把ICTCLAS分词器跑起来了,其实不是mapreduce化困难,而是一个很小的问题,我是很早就完过ICTCLAS分词器的,因为现在需要分词的内容太多,所以才想这把java程序mapreduce化的,但是这就意味着要在linux下的eclipse跑ICTCLAS分词系统,我一直没发现在windows下和linux下用的包不一样,就这样坑了我一下午,一直报一个纠结的错误空指针异常,看了良久源代码也没解决,最终百度了一下,还不少人跟我犯过同样的错误,不过最终百经周折算是解决了,分词速度还可以,等会会跟庖丁的分词作下比较的。


一、ICTCLAS分词器简介

  • 全球最受欢迎的汉语分词开源系统
  • 获得首届国际分词大赛综合排名第一,国家973评测第一名
  • 人名识别、地名识别、组织机构名识别
  • 支持行业词典、用户自定义词典
  • 多级词性标注
  • 关键词提取、指纹提取

                                     ——摘自官方的介绍

二、windows下开发基于ICTCLAS分词器的分词程序

2.1、环境准备

        eclipse开发环境

        相关的包:

         ICTCLAS:http://pan.baidu.com/s/1mg2vbny

         commons.lang2.4:http://pan.baidu.com/s/1tlWWu

2.2、开发java项目

          首先把ICTCLAS解压,然后把Data文件夹整个拷贝到eclipse项目的文件夹下,而bin目录下的org文件整个拷贝到你eclipse项目的src目录下。

2.3、项目结构图:


2.4、测试程序

  1. package test;
  2. import org.ictclas4j.bean.SegResult;
  3. import org.ictclas4j.segment.SegTag;
  4. /**
  5. * @author jonsen_hb
  6. */
  7. public class Test {
  8. /**
  9. * @param args
  10. */
  11. public static void main(String[] args) {
  12. Long start = System.currentTimeMillis();//时间测试开始
  13. String src_line = "这个世界复杂,其实只是人心复杂;生活,慢慢地走,慢慢地过,在不经意间就串起了流年。总有些追逐会化成云烟,总有些故事会写成诗篇,总有些话语会留下悸动,总有些记忆会美在心间。";
  14. SegTag segTag = new SegTag(1);// 分词路径的数目,
  15. SegResult segResult = segTag.split(src_line.trim());//进行分词
  16. String classifyContent = segResult.getFinalResult();
  17. Long end = System.currentTimeMillis();
  18. System.out.println("分词时间花费:"+(end-start));
  19. System.out.println(classifyContent);
  20. }
  21. }

2.5、结果:(注意这里句子太长,图没有截取完)


三、linux下开发基于ICTCLAS分词器的分词程序

3.1、直接把windows下用的一套东西照搬到linux下的痛苦:(就一直报这个错)

3.2、在官网下下载linux 32版后就没问题了

相关包下载:http://www.ictclas.org/ictclas_download.aspx

3.3、linux下的eclipse中开发基于ICTCLAS分词器的分词程序

首先下载ICTCLAS2011_Linux_32_jni ,解压后是ICTCLAS50_Linux_RHAS_32_JNI文件夹。

在Eclipse里面新建一个Java Project,把ICTCLAS50_Linux_RHAS_32_JNI/API下的ICTCLAS放到Java Project的src目录下,把ICTCLAS50_Linux_RHAS_32_JNI/API下的其他所有内容放到Java Project的根目录下,新建一下java class,取名Test。在ICTCLAS50_Linux_RHAS_32_JNI/Doc下有个ICTCLAS50的API使用说明,第22页是第一个JNI示例程序,把该程序的见容拷贝到我们的Test.java里面就可以了。

程序如下:

  1. package test;
  2. import ICTCLAS.I3S.AC.ICTCLAS50;
  3. public class Test {
  4. public static void main(String[] args) {
  5. try {
  6. long start = System.currentTimeMillis();
  7. ICTCLAS50 testICTCLAS50 = new ICTCLAS50();
  8. // 分词所需库(即Data文件夹)的路径
  9. String argu = ".";
  10. // 初始化
  11. if (testICTCLAS50.ICTCLAS_Init(argu.getBytes("GB2312")) == false) {
  12. System.out.println("Init Fail!");
  13. return;
  14. } else {
  15. System.out.println("Init Succeed!");
  16. }
  17. String sInput = "这个世界复杂,其实只是人心复杂;生活,慢慢地走,慢慢地过,在不经意间就串起了流年。总有些追逐会化成云烟,总有些故事会写成诗篇,总有些话语会留下悸动,总有些记忆会美在心间。";
  18. byte nativeBytes[] = testICTCLAS50.ICTCLAS_ParagraphProcess(
  19. sInput.getBytes("GB2312"), 0, 0);
  20. // System.out.println(nativeBytes.length);
  21. String nativeStr = new String(nativeBytes, 0, nativeBytes.length,
  22. "GB2312");
  23. // System.out.println("The result is :" + nativeStr);
  24. String[] rest = nativeStr.split("\\s+");
  25. StringBuilder sb = new StringBuilder("");
  26. for (int i = 0; i < rest.length; i++)
  27. sb.append(rest[i]+" ");
  28. System.out.println(sb.toString());
  29. Long end = System.currentTimeMillis();
  30. System.out.println("all time:" + (end-start));
  31. testICTCLAS50.ICTCLAS_Exit();
  32. } catch (Exception e) {
  33. }
  34. }
  35. }

测试时间如下截图:

对比来看,windows下跑一句的时间已经远远甩出了在linux下跑的时间了!!!

四、hadoop平台下开发基于ICTCLAS分词器的mapreduce分词程序

4.1、开发环境

hadoop1.1.2(伪分布式

linux:centos 5.3  32位

开发工具:eclipse

4.2、所需要的包,上面已经提到了,或者参考官网给的说明

4.3、程序:

主要程序,其中调用的一个类见我的上一篇文章中,给出了源代码了已经。

  1. package test;
  2. import java.io.IOException;
  3. import org.apache.hadoop.conf.Configuration;
  4. import org.apache.hadoop.conf.Configured;
  5. import org.apache.hadoop.fs.Path;
  6. import org.apache.hadoop.io.LongWritable;
  7. import org.apache.hadoop.io.Text;
  8. import org.apache.hadoop.mapreduce.Job;
  9. import org.apache.hadoop.mapreduce.Mapper;
  10. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  11. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  12. import org.apache.hadoop.util.Tool;
  13. import org.apache.hadoop.util.ToolRunner;
  14. import ICTCLAS.I3S.AC.ICTCLAS50;
  15. public class TestICTCLAS extends Configured implements Tool {
  16. public static class Map extends Mapper<LongWritable, Text, Text, Text> {
  17. public static void main(String[] args) throws Exception {
  18. int res = ToolRunner.run(new Configuration(), new TestICTCLAS(),
  19. args);
  20. System.exit(res);
  21. }
  22. enum Counter {
  23. LINESKIP,
  24. }
  25. public void map(LongWritable key, Text value, Context context)
  26. throws IOException, InterruptedException {
  27. String line = value.toString();
  28. try {
  29. String[] lineSplit = line.split("[\\s]+");
  30. String anum = lineSplit[0];
  31. String bnum = lineSplit[1];
  32. ICTCLAS50 testICTCLAS50 = new ICTCLAS50();
  33. // 分词所需库(即Data文件夹)的路径
  34. String argu = ".";
  35. // 初始化
  36. if (testICTCLAS50.ICTCLAS_Init(argu.getBytes("GB2312")) == false) {
  37. System.out.println("Init Fail!");
  38. return;
  39. } else {
  40. System.out.println("Init Succeed!");
  41. }
  42. StringBuilder sb = new StringBuilder();
  43. String resultString = "";
  44. byte nativeBytes[] = testICTCLAS50.ICTCLAS_ParagraphProcess(
  45. bnum.getBytes("GB2312"), 0, 0);
  46. // System.out.println(nativeBytes.length);
  47. String nativeStr = new String(nativeBytes, 0,
  48. nativeBytes.length, "GB2312");
  49. // System.out.println("The result is :" + nativeStr);
  50. String[] rest = nativeStr.split("\\s+");
  51. for (int i = 0; i < rest.length; i++)
  52. sb.append(rest[i] + " ");
  53. FileExcludeStopWord fileExcludeStopWord = new FileExcludeStopWord();
  54. resultString = fileExcludeStopWord.fileExcludeStopWord(sb
  55. .toString());
  56. context.write(new Text(anum), new Text(resultString));
  57. } catch (java.lang.ArrayIndexOutOfBoundsException e) {
  58. context.getCounter(Counter.LINESKIP).increment(1);
  59. return;
  60. }
  61. }
  62. }
  63. public int run(String[] args) throws Exception {
  64. Configuration conf = getConf();
  65. Job job = new Job(conf, "TestICTCLAS");
  66. job.setJarByClass(TestICTCLAS.class);
  67. FileInputFormat.addInputPath(job, new Path(args[0]));
  68. FileOutputFormat.setOutputPath(job, new Path(args[1]));
  69. job.setMapperClass(Map.class);
  70. job.setOutputFormatClass(org.apache.hadoop.mapreduce.lib.output.TextOutputFormat.class);
  71. job.setOutputKeyClass(Text.class);
  72. job.setOutputValueClass(Text.class);
  73. job.waitForCompletion(true);
  74. System.out.println("job's name"+job.getJobName());
  75. System.out.println("job status"+(job.isSuccessful()?"yes":"no"));
  76. return job.isSuccessful()?0:1;
  77. }
  78. }

4.4、上传数据:这里跑了10条数据



4.5、分词结果:(已去除部分停用词,这里的停用词表不是太好,有待改进)



4.6、测试结果:

4.7、对比来看,hadoop对于小文件其实是没有什么优势的,但对于大文件(上TB/PB级别)来说就是优势明显了!

五、和庖丁分词器简单对比:

庖丁在hadoop上跑的速度比ICTCLAS略好一点点!!!

六、总结:

5.1、从性能上来看,其实ICTCLAS的效率还是不错的,在windows上可能是我用的不是官网的包,感觉慢好多,在linux下的确是速度很快,应该在庖丁之上。如果用hadoop分布式平台来跑这两个分词程序的话还不好说,毕竟没有真正的测试过,后面测试了再写。

5.2、庖丁的分词器缺点明显,给出的各种可能的词好是好,但是增加了程序员的负担。而且问题是,人也除了手工分出来,准确率高一些外,用写程序的方式分其实准确率还是不高的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/851378
推荐阅读
相关标签
  

闽ICP备14008679号