自然 言的处理的第一步是分词。近期使用了中科院分词系统NLPIR/ICTCLAS 2016。在2014版本以及之前称为ICTCLAS,之后的版本都更名为NLPIR。 新版简介如下:
词法分析是自然语言处理的基础与关键。 张华平博士在多年研究工作积累的基础上, 研制出了 NLPIR 分词系统, 主要功能包括中文分词; 英文分词; 词性标注; 命名实体识别; 新词识别; 关键词提取; 支持用户专业词典与微博分析。 NLPIR系统支持多种编码(GBK 编码、 UTF8 编码、 BIG5 编码) 、 多种操作系统(Windows,Linux, FreeBSD 等所有主流操作系统)、多种开发语言与平台(包括:C/C++/C#,Java,Python,Hadoop 等)。
我的开发环境是eclipse,win10 64位操作系统。
首先下载两个压缩包,一个是分词包一个接口包,ICTCLAS是纯C编写,在java上使用需要JNI也就是c语言加一个java接口,NLPIR有java版本,我使用的是ICTCLAS加一个接口的方法。分词包下载地址:http://ictclas.nlpir.org/downloads,接口包下载地址(JNI):http://ictclas.nlpir.org/newsdownloads?DocId=384 。
分别解压后待用。
新建一个eclipse项目,将分词包中Data目录拷贝到file目录;解压开JNI包将NLPIR.dll动态链接库放到项目目录下,与file目录同级。
自己修改编写的测试及使用代码如下:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import com.sun.jna.Library;
import com.sun.jna.Native;
import nlpir_SplitWord.NlpirTest.CLibrary;
/**
* @title NlpirTest.java
* @package nlpir_SplitWord
* @description
* @author huanggschn
* @modifier huanggschn
* @since:2016年8月17日
* @version:1.0.0
*/
public class NlpirTest {
// 定义接口 CLibrary,继承自 com.sun.jna.Library
public interface CLibrary extends Library {
// 定义并初始化接口的静态变量 这一个语句是来加载 dll 的,注意 dll 文件的路径可以是绝对路径也可以是相对路径,只需要填写 dll 的文件名,不能加后缀。
CLibrary Instance = (CLibrary) Native.loadLibrary("D:\\workspace\\PreProcessWord\\NLPIR", CLibrary.class);
/**
* 初始化函数声明
* @param sDataPath
* @param encoding 编码类型
* @param sLicenceCode
* @return
*/
public int NLPIR_Init(byte[] sDataPath, int encoding, byte[] sLicenceCode);
/**
* 导入用户词典函数声明
* @param sFilename 用户词典文件名
* @param bOverwrite true:覆盖已存在的词典;false:补充已存在的词典。默认为true
* @return 成功导入的词条数目
*/
public int NLPIR_ImportUserDict(String sFilename,boolean bOverwrite);
/**
* 执行分词函数声明
* @param sSrc 待分词的字符串
* @param bPOSTagged 判断是否需要标注,0没有标注,1有标签,默认为1
* @return
*/
public String NLPIR_ParagraphProcess(String sSrc, int bPOSTagged);
/**
* 处理txt文件分词
* @param sSourceFilename 待处理文件名
* @param sResultFilename 处理结果
* @param bPOStagged 是否需要POS标签,0:没有标签,1:有标签。默认为1
* @return
*/
public double NLPIR_FileProcess(String sSourceFilename,String sResultFilename,int bPOStagged) ;
/**
* 获得分词数目
* @param sParagraph 待分词字符串
* @return
*/
public int NLPIR_GetParagraphProcessAWordCount(String sParagraph) ;
//public result_t NLPIR_ParagraphProcessA(String sParagraph,int pResultCount,boolean bUserDict);
/**
* 提取关键词函数声明
* @param sLine 待处理字符串
* @param nMaxKeyLimit 关键词个数最大值,默认50
* @param bWeightOut 关键词的权重是否输出,默认false
* @return
*/
public String NLPIR_GetKeyWords(String sLine, int nMaxKeyLimit, boolean bWeightOut);
/**
*
* @param sTextFile 待处理文件名
* @param nMaxKeyLimit 关键词个数最大值,默认50
* @param bWeightOut 是否输出权重
* @return 关键字列表
*/
public String NLPIR_GetFileKeyWords(String sTextFile, int nMaxKeyLimit, boolean bWeightOut);
/**
* 增加用户词声明
* @param sWord 要增加的用户词
* @return 增加成功返回1,否则返回0
*/
public int NLPIR_AddUserWord(String sWord);
/**
* 保存用户词典
* @return 保存成功返回1,失败返回0
*/
public int NLPIR_SaveTheUsrDic();
/**
* 删除用户词
* @param sWord
* @return sWord不存在用户词典中,返回-1;否则删除该词
*/
public int NLPIR_DelUsrWord(String sWord);
/**
* 导入关键词黑名单:永远不作为关键词输出
* @param sFilename
* @return
*/
public int NLPIR_ImportKeyBlackList(String sFilename);
/**
* 退出函数声明
*/
public void NLPIR_Exit();
}
public static String getDevideWords(String sInput) throws Exception{
String argu = "";
String system_charset = "UTF-8";
int charset_type = 1;
int init_flag = CLibrary.Instance.NLPIR_Init(argu.getBytes(system_charset), charset_type,
"0".getBytes(system_charset));
if (0 == init_flag) {
System.err.println("初始化失败!");
return "";
}
String devideWords = null;
try {
devideWords = CLibrary.Instance.NLPIR_ParagraphProcess(sInput, 3);
CLibrary.Instance.NLPIR_Exit();//退出
} catch (Exception ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
return devideWords;
}
public static String getKeyWords(String sInput,int maxkeynum) throws Exception{
String argu = "";
String system_charset = "UTF-8";
int charset_type = 1;
int init_flag = CLibrary.Instance.NLPIR_Init(argu.getBytes(system_charset), charset_type,
"0".getBytes(system_charset));
if (0 == init_flag) {
System.err.println("初始化失败!");
return "";
}
String keyWords = null;
try {
keyWords= CLibrary.Instance.NLPIR_GetKeyWords(sInput, maxkeynum, true);
CLibrary.Instance.NLPIR_Exit();//退出
} catch (Exception ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
return keyWords;
}
/**
* 添加用户词典并进行词性标注
* @param filePath
*/
public static void AddUserWords(String filePath){
try{
String encoding = "UTF-8";
File file = new File(filePath);
if(file.isFile()&&file.exists()){
InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);
BufferedReader bufferReader = new BufferedReader(read);
String lineText = "";
while((lineText = bufferReader.readLine()) != null){
CLibrary.Instance.NLPIR_AddUserWord(lineText);
}
}
else{
System.out.println("词典文件不存在!");
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
long bs = Calendar.getInstance().getTimeInMillis();
String path = "D:\\DataResult\\result.txt";
List source = new ArrayList();
source=ReadTxt.readOneTxt(path);
String sInput =source.get(0);
String devideWords=getDevideWords(sInput);
System.out.println("分词结果是:" + devideWords);
String keyWords=getKeyWords(sInput,10);
System.out.println("关键词提取结果是:" + keyWords);
System.out.print("time : ");
System.out.println(Calendar.getInstance().getTimeInMillis() - bs);
}
}
新版本有离线导入用户词典的小工具,使用起来也极为方便。相应文件夹内容如下:点开Readme.txt按照指示即可完成用户词典的导入。
下面简要介绍另外几款开源中文分词系统。
1、HTTPCWS – 基于HTTP协议的开源中文分词系统
HTTPCWS 是一款基于HTTP协议的开源中文分词系统,目前仅支持Linux系统。HTTPCWS 使用“ICTCLAS 3.0 2009共享版中文分词算法”的API进行分词处理,得出分词结果。
ICTCLAS是中国科学院计算技术研究所在多年研究工作积累的基础上,基于多层隐马模型研制出的汉语词法分析系统,主要功能包括中文分词;词性标注;命 名实体识别;新词识别;同时支持用户词典。ICTCLAS经过五年精心打造,内核升级6次,目前已经升级到了ICTCLAS3.0,分词精度 98.45%,各种词典数据压缩后不到3M。ICTCLAS在国内973专家组组织的评测中活动获得了第一名,在第一届国际中文处理研究机构SigHan 组织的评测中都获得了多项第一名,是当前世界上最好的汉语词法分析器。
ICTCLAS 3.0 商业版是收费的,而免费提供的 ICTCLAS 3.0 共享版不开源,词库是根据人民日报一个月的语料得出的,很多词语不存在。所以本人补充的一个19万条词语的自定义词库,对ICTCLAS分词结果进行合并 处理,输出最终分词结果。
由于 ICTCLAS 3.0 2009 共享版只支持GBK编码,因此,如果是UTF-8编码的字符串,可以先用iconv函数转换成GBK编码,再用httpcws进行分词处理,最后转换回UTF-8编码。
HTTPCWS 软件自身(包括httpcws.cpp源文件、dict/httpcws_dict.txt自定义词库)采用NewBSD开源协议,可以自由修改。 HTTPCWS 使用的 ICTCLAS 共享版 API 及 dict/Data/ 目录内的语料库,版权及著作权归中国科学院计算技术研究所、ictclas.org所有,使用需遵循其相关协议。
系统平台:Linux
开发语言:C++
使用方式:HTTP服务
演示网址:http://blog.s135.com/demo/httpcws/
开源官网:http://blog.s135.com/httpcws_v100/
2、SCWS – 简易中文分词系统
SCWS 在概念上并无创新成分,采用的是自行采集的词频词典,并辅以一定程度上的专有名称、人名、地名、数字年代等规则集,经小范围测试大概准确率在 90% ~ 95% 之间,已能基本满足一些中小型搜索引擎、关键字提取等场合运用。 SCWS 采用纯 C 代码开发,以 Unix-Like OS 为主要平台环境,提供共享函数库,方便植入各种现有软件系统。此外它支持 GBK,UTF-8,BIG5 等汉字编码,切词效率高。
系统平台:Windows/Unix
开发语言:C
使用方式:PHP扩展
演示网址:http://www.ftphp.com/scws/demo.php
开源官网:http://www.ftphp.com/scws/
3、PhpanAlysis - PHP无组件分词系统
PhpanAlysis分词系统是基于字符串匹配的分词方法 ,这种方法又叫做机械分词方法,它是按照一定的策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行配,若在词典中找到某个字符串,则匹配成功 (识别出一个词)。按照扫描方向的不同,串匹配分词方法可以分为正向匹配 和逆向匹配;按照不同长度优先匹配的情况,可以分为最大(最长)匹配和最小(最短)匹配;按照是否与词性标注过程相结合,又可以分为单纯分词方法和分词与 标注相结合的一体化方法。
系统平台:PHP环境
开发语言:PHP
使用方式:HTTP服务
演示网址:http://www.itgrass.com/phpanalysis/
开源官网:http://www.itgrass.com/phpanalysis/