FNLP是由Fudan NLP实验室的邱锡鹏老师开源的一套Java写就的中文NLP工具包,提供诸如分词、词性标注、文本分类、依存句法分析等功能。
【开源中文分词工具探析】系列:
- 开源中文分词工具探析(一):ICTCLAS (NLPIR)
- 开源中文分词工具探析(二):Jieba
- 开源中文分词工具探析(三):Ansj
- 开源中文分词工具探析(四):THULAC
- 开源中文分词工具探析(五):FNLP
- 开源中文分词工具探析(六):Stanford CoreNLP
- 开源中文分词工具探析(七):LTP
1. 前言
类似于THULAC,FNLP也是采用线性模型(linear model)分词。较于对数线性模型(log-linear model)HMM/CRF所不同的是,线性模型没有归一化因子而直接建模Score函数:
\]
则序列标注问题对应于求解:
\]
THULAC是采用感知器来学习参数\(w_s\),而FNLP则是采用在线学习算法Passive-Aggressive(PA) [2]。PA算法结合感知器与SVM的优点,学习速度快;损失函数为hinge loss:
{
\matrix {
{0,} & {\gamma (W;(X,Y)) \ 1} \cr
{1- \gamma (W;(X,Y))} & { otherwise} \cr
}
}
\right.
\]
其中,\(\gamma (W;(X,Y))\)为边际距离,定义为:
\]
\(\hat{Y}\)为错误序列标注中得分最高(score函数最大值)的标签。关于参数更新策略的细节请参看FNLP Book [3].
2. 分解
以下源码分析基于fnlp-2.1版本。
训练模型
中文分词的训练模型为seg.m
,由两个类TempletGroup
与Linear
序列化压缩而成:
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(
new GZIPInputStream(new FileInputStream("models/seg.m"))));
TempletGroup templets = (TempletGroup) in.readObject();
Linear cl = (Linear) in.readObject();
其中,类TempletGroup
定义了特征模板,Linear
包含了特征模板、特征及其偏移量、权重数组:
// main field
public Inferencer inferencer;
protected AlphabetFactory factory;
// details about `factory` field
.factory: AlphabetFactory
.maps { "LABELS" -> LabelAlphabet(data: {S=0,M=2,E=3,B=1})
"FEATURES" -> StringFeatureAlphabet(data: TObjectIntCustomHashMap<String>)}
// StringFeatureAlphabet记录了feature在weights数组中的偏移
// details about `inferencer` field
.inferencer: LinearViterbi
protected float[] weights;
public TempletGroup templets;
类StringFeatureAlphabet
的变量data为一个TObjectIntMap,K为特征,V为偏移量,如下所示:
0: 32
1:供/ 414540
2:O/ 14372
2:L/ 131248
3:煞/C/ 147492
5:呼/ 20032
8:哈/钦/ 419968
12:拉/杰/沙/ 350972
13:L/文/C/ 1324032
Map的size为441006,即为特征总数(感觉FNLP的训练语料太少);特征由index + 特征值组成,共有14种。至于特征模板是如何定义,且看下下一小节。
解码
中文分词对应的解码类为CWSTagger
,主要的field如下:
private Linear cl; //
protected Pipe prePipe = null; // String2Sequence, 初步切分成char array形式
protected Pipe featurePipe; // Sequence2FeatureSequence, 计算特征数组
protected AlphabetFactory factory;
protected TempletGroup templets; // lis of BaseTemplet, 特征模板
protected LabelAlphabet labels; // 对应于factory.maps中的LABELS,即S,M,E,B
解码同CRF、结构化感知器SP一样为Viterbi算法,具体实现见类LinearViterbi
,在此不再赘述。
特征
特征模板共定义了14个特征(对应于上面的训练模型),如下所示:
0: %y[-1]%y[0]
1: %x[0,0]%y[0]
2: %x[0,1]%y[0]
3: %x[0,0]%x[0,1]%y[0]
4: %x[-1,0]%y[0]
5: %x[1,0]%y[0]
6: %x[-2,0]%y[0]
7: %x[2,0]%y[0]
8: %x[-2,0]%x[-1,0]%y[0]
9: %x[-1,0]%x[0,0]%y[0]
10: %x[0,0]%x[1,0]%y[0]
11: %x[1,0]%x[2,0]%y[0]
12: %x[-1,0]%x[0,0]%x[1,0]%y[0]
13: %x[-1,1]%x[0,0]%x[1,1]%y[0]
特征模板格式与CRF++相类似;从上可以看出,有1个类别转移特征(index 0),5个unigram字符状态特征(index 1, 4, 5, 6, 7),4个bigram字符状态特征(index 8, 9, 10, 11),1个trigram字符状态特征(index 12),3个字符状态与类型的混合特征(index 2, 3, 13)。其中,FNLP的enum Chars.CharType
定义了5种字符类型如下(与训练模型有稍许区别)。其实,字符类型特征对于分词来说比较鸡肋,可以不用。
D // 数字
L // 字母
C // 汉字
O // 其他,例如标点等
B_ // 空格
public enum CharType {
C,
L,
D,
P, // 标点
B}
我们来直观感受下FNLP的分词效果:
CWSTagger segger = new CWSTagger("models/seg.m");
segger.setEnFilter(true);
String sentence = "小明硕士毕业于中国科学院计算所,后在日本京都大学深造";
List<String> words = segger.tag2List(sentence);
// [小明, 硕士, 毕业于, 中国, 科学院, 计算, 所, ,, 后, 在, 日本, 京都, 大学, 深造]
可以看出,FNLP分词的粒度不均匀,准确性不是太高;应该是跟训练语料太少有关系,训练不充分而导致的。
3. 参考文献
[1] Qiu, Xipeng, Qi Zhang, and Xuanjing Huang. "FudanNLP: A Toolkit for Chinese Natural Language Processing." ACL (Conference System Demonstrations). 2013.
[2] Crammer, Koby, et al. "Online passive-aggressive algorithms." Journal of Machine Learning Research 7.Mar (2006): 551-585.
[3] 邱锡鹏, “自然语言处理原理与实现”, 2014.
开源中文分词工具探析(五):FNLP的更多相关文章
-
开源中文分词工具探析(五):Stanford CoreNLP
CoreNLP是由斯坦福大学开源的一套Java NLP工具,提供诸如:词性标注(part-of-speech (POS) tagger).命名实体识别(named entity recognizer ...
-
开源中文分词工具探析(三):Ansj
Ansj是由孙健(ansjsun)开源的一个中文分词器,为ICTLAS的Java版本,也采用了Bigram + HMM分词模型(可参考我之前写的文章):在Bigram分词的基础上,识别未登录词,以提高 ...
-
开源中文分词工具探析(四):THULAC
THULAC是一款相当不错的中文分词工具,准确率高.分词速度蛮快的:并且在工程上做了很多优化,比如:用DAT存储训练特征(压缩训练模型),加入了标点符号的特征(提高分词准确率)等. 1. 前言 THU ...
-
开源中文分词工具探析(七):LTP
LTP是哈工大开源的一套中文语言处理系统,涵盖了基本功能:分词.词性标注.命名实体识别.依存句法分析.语义角色标注.语义依存分析等. [开源中文分词工具探析]系列: 开源中文分词工具探析(一):ICT ...
-
开源中文分词工具探析(六):Stanford CoreNLP
CoreNLP是由斯坦福大学开源的一套Java NLP工具,提供诸如:词性标注(part-of-speech (POS) tagger).命名实体识别(named entity recognizer ...
-
中文分词工具探析(二):Jieba
1. 前言 Jieba是由fxsjy大神开源的一款中文分词工具,一款属于工业界的分词工具--模型易用简单.代码清晰可读,推荐有志学习NLP或Python的读一下源码.与采用分词模型Bigram + H ...
-
中文分词工具探析(一):ICTCLAS (NLPIR)
1. 前言 ICTCLAS是张华平在2000年推出的中文分词系统,于2009年更名为NLPIR.ICTCLAS是中文分词界元老级工具了,作者开放出了free版本的源代码(1.0整理版本在此). 作者在 ...
-
基于开源中文分词工具pkuseg-python,我用张小龙的3万字演讲做了测试
做过搜索的同学都知道,分词的好坏直接决定了搜索的质量,在英文中分词比中文要简单,因为英文是一个个单词通过空格来划分每个词的,而中文都一个个句子,单独一个汉字没有任何意义,必须联系前后文字才能正确表达它 ...
-
11大Java开源中文分词器的使用方法和分词效果对比,当前几个主要的Lucene中文分词器的比较
本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...
随机推荐
-
JS总结 本地对象2 BOM DOM
string对象 定义一个字符: var str = "world"; str.length 返回字符长度,5 str.charAt(2) 返回字符串第2个字符(从0开始,下 ...
-
SpringMyBatis解析1-使用示例
MyBatis使用介绍 MyBatis的详细使用介绍 http://www.cnblogs.com/xrq730/category/796495.html 建立PO public class Per ...
-
Java Drp项目实战——Drp知多少
是什么 Drp是Distribution Resource Planning的缩写,意思是分销资源计划.它是用来管理企业的执行于Internet上的分销网络的系统,是以商业流程优化为基础,它的核心是销 ...
-
shell编程之数组
bash 编程只支持一维数组,不支持多维,类似c语言,数组下标从0开始,下标可以是整数,也可以是表达式 数组的定义 在shell中用括号来表示数组,中间用空格来隔开 主要有两种种定义形式: arr=( ...
-
UML作业第三次:分析《书店图书销售管理系统》
分析图书销售管理系统 一.概览 PlantUML类图语法学习小结 <书店图书销售管理>的类图元素 绘制类图脚本程序 绘制的类图 二.PlantUML类图语法 1.类之间的关系绘制 示例: ...
-
网页图表Highcharts实践教程标之添加题副标题版权信息
网页图表Highcharts实践教程标之添加题副标题版权信息 Highcharts辅助元素 辅助元素图表的非必要元素,如标题.版权信息.标签.载入动态.它们不和图表数据发生关联,只是额外说明一些基本信 ...
-
create-react-app时registry的奇怪问题
用React官方给的NPM脚本 create-react-app my-app 在自动安装module的过程中,在安装registry的组件的时候莫名其妙的挂住不动了.界面显示的信息如下: fetch ...
-
Babel 是干什么的
首先babel是干什么的?Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行. babel就是为了支持原有的旧的环境. 一.配置文件.babelrc Babel的配置 ...
-
最小生成树-Borůvka算法
一般求最小生成树的时候,最流行的是Kruskal算法,一种基于拟阵证明的贪心,通过给边排序再扫描一次边集,利用并查集优化得到,复杂度为\(O(ElogE)\).另一种用得比较少的是Prim算法,利用优 ...
-
C# 对WinForm应用程序的App.config的加密
默认情况下,我们需要对App.config文件里的connectionStrings片断进行加密处理,ASP.NET IIS 注册工具 (Aspnet_regiis.exe)可以胜任这个工作,但这个工 ...