赞
踩
0、【前言】今天下午坑了我一下午,总算在hadoop上把ICTCLAS分词器跑起来了,其实不是mapreduce化困难,而是一个很小的问题,我是很早就完过ICTCLAS分词器的,因为现在需要分词的内容太多,所以才想这把java程序mapreduce化的,但是这就意味着要在linux下的eclipse跑ICTCLAS分词系统,我一直没发现在windows下和linux下用的包不一样,就这样坑了我一下午,一直报一个纠结的错误空指针异常,看了良久源代码也没解决,最终百度了一下,还不少人跟我犯过同样的错误,不过最终百经周折算是解决了,分词速度还可以,等会会跟庖丁的分词作下比较的。
- 全球最受欢迎的汉语分词开源系统
- 获得首届国际分词大赛综合排名第一,国家973评测第一名
- 人名识别、地名识别、组织机构名识别
- 支持行业词典、用户自定义词典
- 多级词性标注
- 关键词提取、指纹提取
——摘自官方的介绍
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、测试程序
package test; import org.ictclas4j.bean.SegResult; import org.ictclas4j.segment.SegTag; /** * @author jonsen_hb */ public class Test { /** * @param args */ public static void main(String[] args) { Long start = System.currentTimeMillis();//时间测试开始 String src_line = "这个世界复杂,其实只是人心复杂;生活,慢慢地走,慢慢地过,在不经意间就串起了流年。总有些追逐会化成云烟,总有些故事会写成诗篇,总有些话语会留下悸动,总有些记忆会美在心间。"; SegTag segTag = new SegTag(1);// 分词路径的数目, SegResult segResult = segTag.split(src_line.trim());//进行分词 String classifyContent = segResult.getFinalResult(); Long end = System.currentTimeMillis(); System.out.println("分词时间花费:"+(end-start)); System.out.println(classifyContent); } }
2.5、结果:(注意这里句子太长,图没有截取完)
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里面就可以了。程序如下:
package test; import ICTCLAS.I3S.AC.ICTCLAS50; public class Test { public static void main(String[] args) { try { long start = System.currentTimeMillis(); ICTCLAS50 testICTCLAS50 = new ICTCLAS50(); // 分词所需库(即Data文件夹)的路径 String argu = "."; // 初始化 if (testICTCLAS50.ICTCLAS_Init(argu.getBytes("GB2312")) == false) { System.out.println("Init Fail!"); return; } else { System.out.println("Init Succeed!"); } String sInput = "这个世界复杂,其实只是人心复杂;生活,慢慢地走,慢慢地过,在不经意间就串起了流年。总有些追逐会化成云烟,总有些故事会写成诗篇,总有些话语会留下悸动,总有些记忆会美在心间。"; byte nativeBytes[] = testICTCLAS50.ICTCLAS_ParagraphProcess( sInput.getBytes("GB2312"), 0, 0); // System.out.println(nativeBytes.length); String nativeStr = new String(nativeBytes, 0, nativeBytes.length, "GB2312"); // System.out.println("The result is :" + nativeStr); String[] rest = nativeStr.split("\\s+"); StringBuilder sb = new StringBuilder(""); for (int i = 0; i < rest.length; i++) sb.append(rest[i]+" "); System.out.println(sb.toString()); Long end = System.currentTimeMillis(); System.out.println("all time:" + (end-start)); testICTCLAS50.ICTCLAS_Exit(); } catch (Exception e) { } } }
测试时间如下截图: 对比来看,windows下跑一句的时间已经远远甩出了在linux下跑的时间了!!!
4.1、开发环境
hadoop1.1.2(伪分布式)
linux:centos 5.3 32位
开发工具:eclipse
4.2、所需要的包,上面已经提到了,或者参考官网给的说明
4.3、程序:
主要程序,其中调用的一个类见我的上一篇文章中,给出了源代码了已经。
package test; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; import ICTCLAS.I3S.AC.ICTCLAS50; public class TestICTCLAS extends Configured implements Tool { public static class Map extends Mapper<LongWritable, Text, Text, Text> { public static void main(String[] args) throws Exception { int res = ToolRunner.run(new Configuration(), new TestICTCLAS(), args); System.exit(res); } enum Counter { LINESKIP, } public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); try { String[] lineSplit = line.split("[\\s]+"); String anum = lineSplit[0]; String bnum = lineSplit[1]; ICTCLAS50 testICTCLAS50 = new ICTCLAS50(); // 分词所需库(即Data文件夹)的路径 String argu = "."; // 初始化 if (testICTCLAS50.ICTCLAS_Init(argu.getBytes("GB2312")) == false) { System.out.println("Init Fail!"); return; } else { System.out.println("Init Succeed!"); } StringBuilder sb = new StringBuilder(); String resultString = ""; byte nativeBytes[] = testICTCLAS50.ICTCLAS_ParagraphProcess( bnum.getBytes("GB2312"), 0, 0); // System.out.println(nativeBytes.length); String nativeStr = new String(nativeBytes, 0, nativeBytes.length, "GB2312"); // System.out.println("The result is :" + nativeStr); String[] rest = nativeStr.split("\\s+"); for (int i = 0; i < rest.length; i++) sb.append(rest[i] + " "); FileExcludeStopWord fileExcludeStopWord = new FileExcludeStopWord(); resultString = fileExcludeStopWord.fileExcludeStopWord(sb .toString()); context.write(new Text(anum), new Text(resultString)); } catch (java.lang.ArrayIndexOutOfBoundsException e) { context.getCounter(Counter.LINESKIP).increment(1); return; } } } public int run(String[] args) throws Exception { Configuration conf = getConf(); Job job = new Job(conf, "TestICTCLAS"); job.setJarByClass(TestICTCLAS.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setMapperClass(Map.class); job.setOutputFormatClass(org.apache.hadoop.mapreduce.lib.output.TextOutputFormat.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); job.waitForCompletion(true); System.out.println("job's name"+job.getJobName()); System.out.println("job status"+(job.isSuccessful()?"yes":"no")); return job.isSuccessful()?0:1; } }4.4、上传数据:这里跑了10条数据
4.5、分词结果:(已去除部分停用词,这里的停用词表不是太好,有待改进)
4.6、测试结果:
4.7、对比来看,hadoop对于小文件其实是没有什么优势的,但对于大文件(上TB/PB级别)来说就是优势明显了!
庖丁在hadoop上跑的速度比ICTCLAS略好一点点!!!
5.1、从性能上来看,其实ICTCLAS的效率还是不错的,在windows上可能是我用的不是官网的包,感觉慢好多,在linux下的确是速度很快,应该在庖丁之上。如果用hadoop分布式平台来跑这两个分词程序的话还不好说,毕竟没有真正的测试过,后面测试了再写。
5.2、庖丁的分词器缺点明显,给出的各种可能的词好是好,但是增加了程序员的负担。而且问题是,人也除了手工分出来,准确率高一些外,用写程序的方式分其实准确率还是不高的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。