赞
踩
最近在学习过程中,需要对文本进行分词,而且数据量比较大,在 Windows上使用NLPIR处理小文件基本上没有问题( 可以看这里),看NLPIR的开发文档是支持分布式的,因而考虑在Linux上实现hadoop+NLPIR对大量文本数据进行分词和标注。这个过程让我经历了焦头烂额,所以记录下来,便于自己查看,也可以帮助有需要的伙伴~
NLPIR原名 ICTCLAS,下载点这里,我下载的是2016-10-9发布的NLPIR2016,同时支持Windows和Linux,且有Java/C/C++/C# 多种语言,我这里使用的是Java语言。项目中需要两个文件:一是Data文件夹下的所有内容,二是libNLPIR.so文件
NLPIR配置
- package com.katoa.segment;
-
- import com.katoa.util.CLibrary;
- import com.sun.jna.Native;
-
- public class NLPIR {
-
- CLibrary Instance = (CLibrary) Native.loadLibrary("<span style="color:#FF0000;">/usr/local/workspace/NLPIR2015/libNLPIR.so</span>", CLibrary.class);
-
- private boolean initFlag = false;
-
- public boolean init() {
- System.out.println("jna.library.path");
- String argu = "/usr/local/workspace/NLPIR2015/";
- // String system_charset = "GBK";//GBK----0
- int charset_type = 1; //UTF-8
-
- int init_flag = Instance.NLPIR_Init(argu, charset_type, "0");
- String nativeBytes = null;
-
- if (0 == init_flag) {
- nativeBytes = Instance.NLPIR_GetLastErrorMsg();
- System.err.println("初始化失败!fail reason is " + nativeBytes);
- return false;
- }
- initFlag = true;
- Instance.NLPIR_SetPOSmap(1); // 计算所一级标注
- return true;
- }
- public boolean unInit() {
- try {
- Instance.NLPIR_Exit();
- } catch (Exception e) {
- System.out.println(e);
- return false;
- }
- initFlag = false;
- return true;
- }
- public CLibrary getInstance() {
- return Instance;
- }
- public boolean isInitFlag() {
- return initFlag;
- }
-
- /**
- * 分词,1表示标注,0表示不标注
- *
- * @param context
- * 字符串
- * @param bPOSTagged
- * 是否标注
- * @return String
- */
- public String segment(String context, int bPOSTagged) {
- // 分词和标注处理,1表示标注,0表示不标注
- String result = Instance.NLPIR_ParagraphProcess(context, bPOSTagged);
- return result;
- }
-
- /**
- * 分词
- *
- * @param context
- * 字符串
- * @param reduce
- * 是否抽取
- * @return String
- */
- public String segment(String context, boolean reduce) {
- // 分词和标注处理,1表示标注,0表示不标注
- String result = Instance.NLPIR_ParagraphProcess(context, 1);
- String line = "";
- if (reduce) {
- String[] words = result.split(" ");
- for (String word : words) {
- word = word.replaceAll(" ", "");
- int index = word.lastIndexOf("/");
- if (word.substring(index + 1).equals("n") || word.substring(index + 1).equals("v")
- || word.substring(index + 1).equals("a") || word.substring(index + 1).equals("ad")
- || word.substring(index + 1).equals("d") || word.substring(index + 1).equals("o")
- || word.substring(index + 1).equals("other") || word.substring(index + 1).equals("xm")) {
-
- if (!word.substring(0, index).equals("")) {
- line = line + word.substring(0, index) + " ";
- }
- }
- }
- }
- return line;
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- package com.katoa.tuple;
-
- /**
- * @author 作者 : monkey
- * @version 创建时间:2016年10月9日 下午8:12:15
- * 类说明:语料预处理 mapper
- */
- import java.io.IOException;
- import java.util.ArrayList;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.apache.hadoop.io.LongWritable;
- import org.apache.hadoop.io.Text;
- import org.apache.hadoop.mapreduce.Mapper;
-
- import com.katoa.segment.NLPIR;
-
- public class FilterMapper extends Mapper<LongWritable, Text, Text, Text> {
- private static NLPIR nlpir = new NLPIR();
-
- <span style="color:#FF0000;">protected void setup(Context context) {
- nlpir.init();
- }</span>
-
- @Override
- public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
- ArrayList<String> phraselist = new ArrayList<String>();
-
- String id = null;
- String v = null;
-
- String temp = value.toString();
-
- String[] contents = temp.split("\t");
- id= contents[0];
- v= contents[1];
-
- if (v!= null) {
- String str = posTagging(v);
-
- context.write(new Text(id), new Text(str));
- }
-
- }
- }
-
- <span style="color:#FF0000;">protected void cleanup(Context context) {
- nlpir.unInit();
- }</span>
-
- /**
- * POS Tagging
- *
- * @param text
- * The word to be marked
- * @return String
- */
- public static String posTagging(String text) {
- // text = Main.getNlpir().segment(text, 1);
- text = nlpir.segment(text, 1);
- String[] words = text.split(" ");
- String temp = "";
- int i = 0;
- for (String word : words) {
- if (!word.equals("")) { // Remove the extra spaces
- if (i == words.length - 1) {
- temp = temp + word;
- } else {
- temp = temp + word + " ";
- }
- }
-
- i++;
- }
- return temp;
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
将NLPIR的Data文件夹和libNLPIRso文件放到/usr/local/workspace/NLPIR2015下(路径根据自己的设置),然后使用fatjar将程序打成jar包并放到/usr/local/workspace目录下,使用hadoop jar 命令运行程序。
常见错误:
java.lang.UnsatisfiedLinkError:Unable to load library 'win64/NLPIR': Native library(linux-x86-64/libwin64/NLPIR.so) not found in resource path
或
java.lang.UnsatisfiedLinkError: Unable to load library 'libNLPIR.so':Can't obtain InputStream for linux-x86-64/libNLPIR.so
原因:Native.loadLibrary 加载的路径不正确,或没有使用libNLPIR.so,而是Windows下的NLPIR文件。
修改后建议重启Hadoop集群。
Exceptionfrom container-launch: ExitCodeException exitCode=134: /bin/bash: line 1: 41729已放弃
原因:MR程序问题,对于要加载其他配置文件的,如这里的libNLPIR.so文件,应该在MR中进行初始化,而不是在主程序中。这里用在mapper端,因此需要在mapper端使用setup()方法进行加载配置文件初始化,map做完任务后使用cleanup()方法结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。