hadoop学习【8】——基于hadoop的分词程序二(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、测试程序

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、结果:(注意这里句子太长,图没有截取完)


三、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里面就可以了。

程序如下:

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下跑的时间了!!!

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

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值