}
最近有用一个中科院的中文分词系统,感觉蛮颇爽。
NLPIR汉语分词系统(又名ICTCLAS2013),主要功能包括中文分词;词性标注;命名实体识别;用户词典功能;支持GBK编码、UTF8编码、BIG5编码(此处是个坑,我的txt文件都是默认ASC编码,不转码的话就会出现乱码。上万个文件,目前尚没有找到满意的解决方案)。新增微博分词、新词发现与关键词提取;张华平博士先后倾力打造十余年,内核升级10次。
全球用户突破20万,先后获得了2010年钱伟长中文信息处理科学技术奖一等奖,2003年国际SIGHAN分词大赛综合第一名,2002年国内973评测综合第一名。
下载传送门http://ictclas.nlpir.org/。
文件包介绍
bin: 里面有文档语义抽取系统和分词系统。还有win下的可视化操作界面,可以演示用,interesting~
Data:系统核心词库(很重要!),另还包含文英文处理的支持知识库,如果不需要英文处理的功能,可以不加载。
doc:相关文档支持
include:系统头文件
lib:不同环境下的支撑库,包括c/c++/Java
sample:NLPIR2014示例程序(我用的是Java,直接从这里面导入包),看到2015的文件,已经有对Python的支持了。我下的是14所以没有。
test: NLPIR2014测试文档集合
调试使用
首先在全世界最好用的Java IDE –IDEA导入sample里面的 JnaTest_NLPIR 项目。并且需要将上一级目录的Data文件夹copy过来。导入成功之后的文件结构如下(注意 NLPIR.dll这个动态模块库文件, 需要在.\ lib\win64里面copy过来如果你用的是32位,那就在win里面):
创建应用的接口 CLibrary 继承Library,这里面提供了可用java实现的具体方法。
package code;
/**
* Created by Administrator on 2016/11/21.
*/
import com.sun.jna.Library;
public interface CLibrary extends Library{
//初始化
public int NLPIR_Init(String sDataPath, int encoding, String sLicenceCode);
//对字符串进行分词
public String NLPIR_ParagraphProcess(String sSrc, int bPOSTagged);
//对TXT文件内容进行分词
public double NLPIR_FileProcess(String sSourceFilename,String sResultFilename, int bPOStagged);
//从字符串中提取关键词
public String NLPIR_GetKeyWords(String sLine, int nMaxKeyLimit,boolean bWeightOut);
//从TXT文件中提取关键词
public String NLPIR_GetFileKeyWords(String sLine, int nMaxKeyLimit,boolean bWeightOut);
//添加单条用户词典
public int NLPIR_AddUserWord(String sWord);
//删除单条用户词典
public int NLPIR_DelUsrWord(String sWord);
//从TXT文件中导入用户词典
public int NLPIR_ImportUserDict(String sFilename);
//将用户词典保存至硬盘
public int NLPIR_SaveTheUsrDic();
//从字符串中获取新词
public String NLPIR_GetNewWords(String sLine, int nMaxKeyLimit, boolean bWeightOut);
//从TXT文件中获取新词
public String NLPIR_GetFileNewWords(String sTextFile,int nMaxKeyLimit, boolean bWeightOut);
//获取一个字符串的指纹值
public long NLPIR_FingerPrint(String sLine);
//设置要使用的POS map
public int NLPIR_SetPOSmap(int nPOSmap);
//获取报错日志
public String NLPIR_GetLastErrorMsg();
//退出
public void NLPIR_Exit();
然后创建一个类去实现以上的接口
package code;
import java.io.*;
import java.util.Arrays;
import utils.SystemParas;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class NlpirTest {
// 定义接口CLibrary,继承自com.sun.jna.Library
public interface CLibrary extends Library {
// 定义并初始化接口的静态变量
CLibrary Instance = (CLibrary) Native.loadLibrary(
"F:\\ICTCLAS\\sample\\JnaTest_NLPIR\\src\\code\\NLPIR", CLibrary.class);
// printf函数声明
public int NLPIR_Init(byte[] sDataPath, int encoding,
byte[] sLicenceCode);
//对字符串进行分词
public String NLPIR_ParagraphProcess(String sSrc, int bPOSTagged);
//对TXT文件内容进行分词
public double NLPIR_FileProcess(String sSourceFilename,String sResultFilename, int bPOStagged);
public String NLPIR_GetKeyWords(String sLine, int nMaxKeyLimit,
boolean bWeightOut);
//从TXT文件中提取关键词
public String NLPIR_GetFileKeyWords(String sLine, int nMaxKeyLimit,boolean bWeightOut);
public void NLPIR_Exit();
}
public static String transString(String aidString, String ori_encoding,
String new_encoding) {
try {
return new String(aidString.getBytes(ori_encoding), new_encoding);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
//读取文件
/*
* @dic 文件集存在的目录
* @currentPage 类似于分页
* @return
* */
public static File[] readTxt(String dir ){
//创建File对象
File file = new File(dir);
//获取该目录下的所有文件
// String[] files = file.list();
// for (String f : files){
// System.out.println(f);
// }
//listFiles是获取该目录下所有文件和目录的绝对路径
File[] fs = file.listFiles();
for (File f : fs){
System.out.println(f);
}
return fs;
}
public static void main(String[] args) throws Exception {
String argu = "F:\\ICTCLAS";
// String system_charset = "GBK";//GBK----0
String system_charset = "utf-8";
int charset_type = 1;
// int charset_type = 0;
// 调用printf打印信息
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;
}
//读取txt文件
File[] fs=readTxt("F:\\作业\\homework2\\Training Dataset\\testtxt16");
String sInput=null;
for(File temp:fs){
String in=null;
String s =new String();
try {
BufferedReader input=new BufferedReader(new InputStreamReader(new FileInputStream(temp),"GBK"));
while((s = input.readLine())!=null){
in = in + s;
}
sInput = sInput + in;
input.close();
}catch (Exception e){
System.out.println("读取文件失败!");
}
}
String nativeBytes = null;
try {
nativeBytes = CLibrary.Instance.NLPIR_ParagraphProcess(sInput, 0);
// String nativeStr = new String(nativeBytes, 0,
// nativeBytes.length,"utf-8");
System.out.println("分词结果为: " + nativeBytes);
// System.out.println("分词结果为: "
// + transString(nativeBytes, system_charset, "UTF-8"));
//
// System.out.println("分词结果为: "
// + transString(nativeBytes, "gb2312", "utf-8"));
int nCountKey = 0;
String nativeByte = CLibrary.Instance.NLPIR_GetKeyWords(sInput, 20,false);
String fInput ="F:\\11.TXT";
String fOut ="F:\\rs.TXT";
double d =CLibrary.Instance.NLPIR_FileProcess(fInput,
fOut,0);
String dd =CLibrary.Instance.NLPIR_GetFileKeyWords(fInput,10,false);
System.out.println(dd);
System.out.print("关键词提取结果是:" + nativeByte);
// int nativeElementSize = 4 * 6 +8;//size of result_t in native
// code
// int nElement = nativeByte.length / nativeElementSize;
// ByteArrayInputStream(nativeByte));
//
// nativeByte = new byte[nativeByte.length];
// nCountKey = testNLPIR30.NLPIR_KeyWord(nativeByte, nElement);
//
// Result[] resultArr = new Result[nCountKey];
// DataInputStream dis = new DataInputStream(new
// ByteArrayInputStream(nativeByte));
// for (int i = 0; i < nCountKey; i++)
// {
// resultArr[i] = new Result();
// resultArr[i].start = Integer.reverseBytes(dis.readInt());
// resultArr[i].length = Integer.reverseBytes(dis.readInt());
// dis.skipBytes(8);
// resultArr[i].posId = Integer.reverseBytes(dis.readInt());
// resultArr[i].wordId = Integer.reverseBytes(dis.readInt());
// resultArr[i].word_type = Integer.reverseBytes(dis.readInt());
// resultArr[i].weight = Integer.reverseBytes(dis.readInt());
// }
// dis.close();
//
// for (int i = 0; i < resultArr.length; i++)
// {
// System.out.println("start=" + resultArr[i].start + ",length=" +
// resultArr[i].length + "pos=" + resultArr[i].posId + "word=" +
// resultArr[i].wordId + " weight=" + resultArr[i].weight);
// }
CLibrary.Instance.NLPIR_Exit();
} catch (Exception ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
}
}
分词的结果:
关键词提取结果:
有大神对NLPIR系统的接口函数说明进行了简单的翻译(http://blog.youkuaiyun.com/yusewuhen/article/details/49337125),如下所示:
1. NLPIR_Init
初始化分析器,并根据配置文件为NLPIR准备数据。
函数形式:
boolNLPIR_Init(const char* sInitDirPath=0, int encoding=GBK_CODE,
const char*sLicenceCode=0)
需要的头文件:<NLPIR.h>
返回值:
如果初始化成功,返回successed,否则返回false。
参数:
char* sInitDirPath:指定存放配置文件Configure.xml和Data文件的路径,默认值为0,表明路径为当前工作目录。
int encoding:编码格式标识符,默认为GBK_CODE ,也可以设置为UTF8_CODE和BIG5_CODE。
char* sLicenceCode:商业用户需要使用的许可证编码,免费用户无需使用该参数。
说明:
使用NLPIR时必须先执行NLPIR_Init函数(只需执行一次)。系统关闭时还应执行NLPIR_Exit函数来销毁缓存数据。
NLPIR_Init执行失败通常有两个原因:1. 需要的数据文件格式不兼容或丢失;2.配置文件丢失或存在非法参数。还可以通过日志文件来了解更多信息,日志文件存放在默认路径中。
2. NLPIR_Exit
退出程序并释放所有资源和NLPIR使用的缓存数据。
函数形式:
boolNLPIR_Exit();
需要的头文件:<NLPIR.h>
返回值:
执行成功返回successed,否则返回false。
参数:
无
说明:
该函数必须在关闭系统时执行,若需重启NLPIR,再次执行NLPIR_Init函数即可。
3.NLPIR_ImportUserDict
从文件中导入用户自定义的词典。
函数形式:
unsigned intNLPIR_ImportUserDict(const char * sFilename);
需要的头文件:<NLPIR.h>
返回值:
导入的词汇数量。
参数:
char* sFilename: 要导入的用户词典文件所在路径。
说明:
该函数只有在NLPIR_Init函数执行成功后才能使用。词典文件的格式请参见相关示例。
你只需在更改了用户词典或第一次使用某个词典时执行该函数,当配置文件中的UserDict参数为on时,NLPIR将会(把该词典添加到配置文件中)并在启动时自动加载该词典。当将UserDict置为off时,用户自定义词典文件将不再自动导入。
4.NLPIR_ParagraphProcess
处理一个段落文字,返回运行结果缓存的指针。
函数形式:
const char *NLPIR_ParagraphProcess(const char * sParagraph, int bPOStagged=1);
需要的头文件:<NLPIR.h>
返回值:
运行结果缓存的指针。
参数:
char* sParagraph: 输入段落的源
int bPOStagged: 判断是否需要位置标记,0:无标记;1:有标记。默认值为1。
说明:
该函数只有在NLPIR_Init函数执行成功后才能使用
5.NLPIR_ParagraphProcessA
函数形式:
result_t *NLPIR_ParagraphProcessA(
const char *sParagraph, int * pResultCount, bool bUserDict=true)
需要的头文件:<NLPIR.h>
返回值:
运行结果向量的指针,该指针由系统进行管理,用户无法对它进行分配和释放。
其结构如下:
struct result_t{
int start;//start position,词语在输入句子中的开始位置
int length;//length,词语的长度
charsPOS[POS_SIZE];//word type,词性ID值,可以快速的获取词性表
int iPOS;//词性
int word_ID; //如果是未登录词,设成或者-1
int word_type;//区分用户词典;1,是用户词典中的词;,非用户词典中的词
int weight;//word weight
};
参数:
char* sParagraph: 输入段落的源
int* pResultCount: 结果向量的大小
bool bUserDict:是否使用用户词典
说明:
该函数只有在NLPIR_Init函数执行成功后才能使用
6.NLPIR_FileProcess
处理一个TXT文件。
函数形式:
DoubleNLPIR_FileProcess(const char * sSourceFilename,
const char *sResultFilename, int bPOStagged=1);
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回处理速度值,否则返回false。
参数:
char *sSourceFilename: 要处理的源文件名称;
char *sResultFilename: 存储处理结果的文件名称;
intbPOStagged: 判断是否需要位置标记,0:无标记;1:有标记。默认值为1。说明:
该函数只有在NLPIR_Init函数执行成功后才能使用
处理结果的输出格式可在配置文件中进行设置。
7.NLPIR_GetParagraphProcessAWordCount
NLPIR_ParagraphProcessA函数的C#实现API。
函数形式:
int NLPIR_GetParagraphProcessAWordCount(constchar *sParagraph);
需要的头文件:<NLPIR.h>
返回值:
返回输入段落的词汇数量。
参数:
char* sParagraph: 输入段落的源
说明:
该函数只有在NLPIR_Init函数执行成功后才能使用
处理结果的输出格式可在配置文件中进行设置。
8. NLPIR_ParagraphProcessAW
NLPIR_ParagraphProcessA函数的C#实现API。
函数形式:
voidNLPIR_ParagraphProcessAW(int nCount,result_t * result);
需要的头文件:<NLPIR.h>
返回值:
无。
参数:
nCount: 输入段落的词汇数量;
result: 处理结果的结构体指针;
说明:
该函数只有在NLPIR_Init函数执行成功后才能使用
处理结果的输出格式可在配置文件中进行设置。
9.NLPIR_AddUserWord
向用户词典添加一个词汇。
函数形式:
intNLPIR_AddUserWord(const char * sWord);
需要的头文件:<NLPIR.h>
返回值:
如果添加成功,返回successed,否则返回false。
参数:
char* sWord:要添加的词汇。
说明:
该函数只有在NLPIR_Init函数执行成功后才能使用
10.NLPIR_SaveTheUsrDic
将用户词典保存至硬盘。
函数形式:
intNLPIR_SaveTheUsrDic();
需要的头文件:<NLPIR.h>
返回值:
如果执行成功返回1,否则返回0。
参数:
无
说明:
该函数只有在NLPIR_Init函数执行成功后才能使用
11.NLPIR_DelUsrWord
从用户词典中删除一个词汇。
函数形式:
intNLPIR_DelUsrWord(const char * sWord);
需要的头文件:<NLPIR.h>
返回值:
如果要删除的词汇不存在,则返回-1;如果删除成功,则返回该词汇的句柄。
参数:
char* sWord:要删除的词汇。
说明:
该函数只有在NLPIR_Init函数执行成功后才能使用
12.NLPIR_GetKeyWords
从输入的段落中提取关键词。
函数形式:
const char *NLPIR_GetKeyWords(const char * sLine,int nMaxKeyLimit=50,
boolbWeightOut=false);
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回执行结果列表。如果执行失败,返回NULL。
格式如下:
"科学发展观 宏观经济 "
或者
"科学发展观 23.80 宏观经济 12.20" (带有权值)
参数:
char* sLine:输入的段落;
int nMaxKeyLimit:关键词最大数量;
bool bWeightOut:是否输出权值;
说明:
无。
13.NLPIR_GetFileKeyWords
从TXT文件中提取关键词。
函数形式:
const char *NLPIR_GetFileKeyWords(const char * sTextFile,
intnMaxKeyLimit=50, bool bWeightOut=false);
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回执行结果列表。如果执行失败,返回NULL。格式同上。
参数:
char* sTextFile:输入文件的名称;
int nMaxKeyLimit:关键词最大数量;
bool bWeightOut:是否输出权值;
说明:
无
14.NLPIR_GetNewWords
从段落中提取新词。
函数形式:
const char *NLPIR_GetNewWords(const char * sLine, int nMaxKeyLimit=50,
boolbWeightOut=false);
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回提取到的新词列表,否则返回NULL。格式同上
参数:
char* sLine:输入的段落;
int nMaxKeyLimit:关键词最大数量;
bool bWeightOut:是否输出权值;
说明:
无
15.NLPIR_GetFileNewWords
从TXT文件中提取新词。
函数形式:
const char *NLPIR_GetFileNewWords(const char * sTextFile,
intnMaxKeyLimit=50, bool bWeightOut=false);
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回提取到的新词列表,否则返回NULL。格式同上
参数:
char* sTextFile:输入文件的名称;
int nMaxKeyLimit:关键词最大数量;
bool bWeightOut:是否输出权值;
说明:
无
16.NLPIR_FingerPrint
提取段落的一个指纹。
函数形式:
unsigned longNLPIR_FingerPrint(const char * sLine);
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回指纹值,否则返回0。
参数:
char* sLine:输入的段落;
说明:
无。
17.NLPIR_SetPOSmap
设置使用的POS map。
函数形式:
intNLPIR_SetPOSmap(int nPOSmap);
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回1,否则返回0。
参数:
int nPOSmap :
ICT_POS_MAP_FIRST 计算所一级标注集
ICT_POS_MAP_SECOND 计算所二级标注集
PKU_POS_MAP_SECOND 北大二级标注集
PKU_POS_MAP_FIRST 北大一级标注集
说明:
该函数只有在NLPIR_Init函数执行成功后才能使用
18.NLPIR_GetLastErrorMsg
获取最近一条报错信息。
函数形式:
const char *NLPIR_GetLastErrorMsg();
需要的头文件:<NLPIR.h>
返回值:
获取最近一条报错信息的指针。
参数:
无。
说明:
无。
以下为新词识别函数,建议脱机使用。
1. NLPIR_NWI_Start
启动新词识别。
函数形式:
boolNLPIR_NWI_Start();
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回successed,否则返回false。
参数:
无
2.NLPIR_NWI_AddFile
往新词识别系统中添加待识别新词的文本文件,需要在运行 NLPIR_NWI_Start()之后,才有效。
函数形式:
IntNLPIR_NWI_AddFile(const char * sFilename);
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回true,否则返回false。
参数:
char *sFilename:输入的文件名;
3.NLPIR_NWI_AddMem
往新词识别系统中添加一段待识别新词的内存,需要在运行 NLPIR_NWI_Start()之后,才有效。
函数形式:
boolNLPIR_NWI_AddMem(const char *sText);
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回true,否则返回false。
参数:
char *sFilename:文件名
4. NLPIR_NWI_Complete
新词识别添加内容结束,需要在运行 NLPIR_NWI_Start()之后,才有效。
函数形式:
boolNLPIR_NWI_Complete();
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回true,否则返回false。
参数:
无。
说明:
5.NLPIR_NWI_GetResult
获取新词识别的结果。
函数形式:
const char *NLPIR_NWI_GetResult(bool bWeightOut=false);
需要的头文件:<NLPIR.h>
返回值:
执行结果的列表。
参数:
bool bWeightOut:是否输出权重值。
6.NLPIR_NWI_Result2UserDict
将新词识别结果导入到用户词典中,需要在运行 NLPIR_NWI_Complete()之后,才有效,如果需要将新词结果永久保存,建议在执行NLPIR_SaveTheUsrDic函数。
函数形式:
unsigned intNLPIR_NWI_Result2UserDict()
需要的头文件:<NLPIR.h>
返回值:
如果执行成功,返回true,否则返回false。
参数:
无。