-
Notifications
You must be signed in to change notification settings - Fork 725
Library
FNLP入门教程
(by h4x3rotab)
FNLP提供了各种调用方式,然而为了使用FNLP的全部功能,或是为了达到最高的处理性能,调用FNLP库是最佳的选择。FNLP以Java编写,因此可以轻松整合到Java项目,并运行在各种平台之上。
本章将介绍FNLP库涉及的相关概念和使用方法。关于如何在Java项目中引用FNLP库,以及项目的配置等问题,请参见快速入门章节。
语言模型、文件结构等
FNLP提供了多种中文处理工具,包括分词、词性标注、实体名识别、依存句法分析、指代消解等等。这些工具大多都封装在位于org.fnlp.nlp.cn
的CNFactory
工厂类之中。
使用静态方法CNFactory.getInstance(String)
可以创建CNFactory
的实例。此方法接受一个参数,指定用于初始化系统的语言模型文件目录。语言模型通常位于FNLP源码目录中的“models”文件夹。
CNFactory
对象提供了诸多实现中文处理任务的方法,后文将逐一介绍。
CNFactory.seg(String)
方法提供了中文分词功能。它接受一个语句,返回分词结果。分词结果为字符串数组,每个元素都是结果中的一个词。
清单 CNFactory.seg(String)示例
// 对line分词
String[] words = factory.seg(line);
// 显示分词结果
for(String word : words) {
System.out.print(word + " ");
}
System.out.println();
CNFactory.seg(String)
方法实质上是对中文分词器CWSTagger
的封装。CWSTagger
位于org.fnlp.nlp.cn.tag
包之中,也可以直接调用此类实现分词功能。
CWSTagger
把中文分词转化为一个“BMES”序列标注问题,采用线性HMM/CRF方法实现了标注器,可以在O(N K^2 T)的时间复杂度内实现标注功能。当标注器确定时,可以得到线性时间复杂度O(N),详情请参见第4章【TODO:相关章节】。
CNFactory.tag
系列方法实现了中文词性标注。它们包括以下方法:
-
String[] tag(String[] input)
对已分词后的词数组
input
进行词性标注,输出一个等长的数组,表示每个词的词性。例如对数组{ “关注”, “自然”, “语言”, “处理”, “。” }
,调用此方法可以得到标注结果:{ “动词”, “名词”, “名词”, “动词”,,“标点” }
-
String[][] tag(String input)
对一个未分词的中文语句
input
进行分词与词性标注。返回一个二维数组String[2][N]
,其中N
为分词得到的词数。二维数组的第一个下标为数据类型,分词结果保存在下标0之中,词性标注结果保存在下标1之中。例如调用此方法对“关注自然语言处理。”进行词性标注,可以得到标注结果:
{ { “关注”, “自然”, “语言”, “处理”, “。” }, {“动词”, “名词”, “名词”, “动词”,,“标点” } }
-
String tag2String(String input)
与
String[][] tag(String input)
相同,但不返回一个二维数组,而是返回编码后的标注结果。如对“关注自然语言处理。”进行标注,则可以得到结果:“关注/动词 自然/名词 语言/名词 处理/动词 。/标点”
CNFactory.tag
系列方法实质上是对中文分词器POSTagger
的封装。POSTagger
位于org.fnlp.nlp.cn.tag
包之中。
词性标注是对语料进行进一步处理的基础。FNLP提供的词性标注功能支持的词性如下表所示。
FNLP词性 | ||||
---|---|---|---|---|
名词 | 专有名 | 人名 | 地名 | 机构名 |
型号名 | 事件名 | 网址 | 品牌名 | |
形容词 | 形谓词 | 副词 | 限定词 | |
代词 | 人称代词 | 指示代词 | 疑问代词 | |
从属连词 | 并列连词 | 结构助词 | 介词 | |
数词 | 序数词 | 量词 | ||
动词 | 能愿动词 | 趋向动词 | 被动词 | 把动词 |
时间短语 | 惯用词 | 拟声词 | 省略词 | 语气词 |
时态词 | 方位词 | 标点 | 叹词 | 表情符 |
运算符 | ||||
动态助词 | ||||
未知 |
清单 CNFactory.tag2String(String)
示例
// 对line进行词性标注
String tagged = factory.tag2String(line);
// 显示标注结果
System.out.println(tagged);
FNLP的词性标注原理与中文分词类似,同样采用了线性HMM/CRF方法,可以在线性时间内对中文语句进行标注。由于词性标注涉及的标签与特征数更多,因此线性算法的时间常数因子可能较分词器更大。详情请参见第4章【TODO:相关章节】。
CNFactory.ner(String)
方法实现了实体名识别功能。它接受一个中文语句,识别出其中的实体名(如人名、地名等专有名词),并返回一个HashMap<String, String>
对象,包含识实体名与其对应的类型。哈希表中的键为实体名,值为实体类型。
清单 CNFactory.ner(String)
示例
// 对line进行实体名识别处理
HashMap<String, String> hashMap = factory.ner(line);
// 显示识别结果
System.out.println(hashMap.toString());
在FNLP中共有人名、地名、机构名与专有名四种实体类型。识别实体名的原理实质上是对中文语句进行词性标注,通过判断每个词的类型是否属于实体类型,来确定一个词是否属于实体名。因此其性能与词性标注一致。
CNFactory.ner(String)
方法是对NERTagger
的封装。NERTagger
位于org.fnlp.nlp.cn.tag
包之中。
CNFactory.parse
系列方法实现了中文依存句法分析。它们包括以下方法:
-
DependencyTree parse2T(String sent)
对未分词的中文句子进行分词、标注等处理后,进行依存句法分析。参数
sent
为输入句子。此方法返回一个DependencyTree
对象,记录了依存句法分析结果。例如,调用此方法分析句子“越过长城,走向世界。”则可以得到分析树:
依存语法树
-
DependencyTree parse2T(String[] words, String[] pos)
对已分词的中文句子进行依存句法分析。其中
words
参数是句子的分词结果,pos
参数是句子的词性标注序列,这两个字符串数组必须具有相同的长度。此方法返回一个DependencyTree
对象,记录了依存句法的分析结果。 -
DependencyTree parse2T(String[][] tagg)
同
parse2T(String[], String[])
,但接受一个二维数组tagg
。要求tagg
是一个2xN的数组,tagg[0]
为分词序列,tagg[1]
为词性标注序列,其中N为序列长度。 -
int[] parse(String[] words, String[] pos)
对一份次的中文句子进行依存句法分析,接受分词序列
words
与词性标注序列pos
,返回依存关系数组。依存关系数组的长度与序列长度一致,其中的每个元素表示序列中对应词所依赖元素的下标。例外的是,中心词的元素值为-1。例如调用此方法对
{{“越过”, “长城”, “,”, “走向”, “世界”, “。”}, {“动词”, “地名”, “标点”, “动词”, “名词”, “标点”}}
进行分析,则可以得到结果:{ 3, 0, 0, -1, 3, 3 }
在这个例子中,“越过”作为状语依赖第3个词“走向”,“长城”作为宾语依赖第0个词“越过”。
CNFactory.parse
系列方法是对JointParser
的封装。JointParser
位于org.fnlp.nlp.parser.dep
包之中。
通过依存句法分析可以得到依存语法树。依存语法树是一种标识词之间关系的语法树,树根节点为中心词,而其余所有词都与某一词构成二元关系。这些关系包含:
FNLP依存关系 | ||||
---|---|---|---|---|
主语 | 标点 | 疑问连动 | 补语 | 语态 |
的字结构 | 介宾 | 数量 | 宾语 | 地字结构 |
感叹 | 时态 | 之字结构 | 同位语 | 得字结构 |
并列 | 连动 | 修饰 | 核心词 | 定语 |
状语 | 关联 |
FNLP的依存句法分析基于Yamada算法(Yamada & Matsumoto, 2003),该算法对句子的标注序列进行扫描,尝试每一轮都合并部分相邻节点。在合并时,抽取词的上下文特征,对特征进行分类,由此决策节点间如何合并。不断重复此过程,直到所有节点都被合并为一颗树,最终就得到了依存语法树。Yamada算法为确定性状态转移算法,其时间复杂度的增长不会超过O(n^2)。
作为新手补充几个容易出问题的点; 1、在原GitHub里最新版的模型文件的网盘地址被举报了无法获取,所以只能退一步下载2.1版本的模型文件和2.1版本的源码(测试之后可以使用,如果版本和模型不匹配会出问题)。 2、在装完maven之后开始编译FNLP文件,我安装的时候会下载非常多的组件,不挂梯子会一直失败,所以建议稳定网络稳定梯子安装。(安装的时候会花挺久的,而且cmd有概率会卡死,重新开始编译就行) 3、执行maven命令copy jar包到lib目录下会有问题,推荐手动复制或下载。 4、导入的时候需要导入的fnlp-core-2.0-SNAPSHOT.jar在fnlp-core文件夹下fnlp-core/target/fnlp-core-2.0-SNAPSHOT.jar(很容易被忽略) 5、helloword指导中 1 import org.fnlp.nlp.cn.CNFactory;
2 CNFactory factory = CNFactory.getInstance("models"); 第二行的初始化格式工厂需要在你项目建立好的类中,放在全局外面会报错。 导入包的时候有时候会出现格式错误,此时手打一遍可能会解决问题。