词法分析
词法分析是对自然语言进行较浅层次处理的过程。
中文分词
英文有空格可以将单词分开。但是中文都是连续的字串,因此将中文切分成词,面临着困难。主要有:
- 交集型歧义:例如
下雨天地面积水
。可以分成下雨天/地面/积水
。也可以分成下雨/天地/面积/水
。 - 组合型歧义:例如
门把手弄坏了
。可以分成门/把/手/弄/坏/了
。或门/把手/弄/坏/了
。
在分词实践中,会出现词典或样本数据中没有出现过的新词,这些词称为集外词
。分词错误中 98.33%由集外词导致。而由歧义导致的只占1.67%。因此在中文自动分词中能够发现集外词格外重要。
基于词典的切分
基于词典的方法虽然简单,但是如果词典构建得比较好,准确率也能到95%左右。它的优点是计算快。主要有下面几种方法:
- 正向最大匹配 :下面介绍
- 逆向最大匹配 :略
- 双向最大匹配 :将正向最大匹配法得到的分词结果和逆向最大匹配法的到的结果进行比较,从而决定正确的分词方法。一般是选择词数较少的那一个。如果词数相同,则返回单字较少的那一个。也可以使用语言模型来选择概率最大的切分。
- 最少分词法:会先构建一个有向无环图,然后求取最短路径(最少词数)作为分词结果。
正向最大匹配
def 前向最大匹配(sentence, dictionary, window_size=3):
i = 0
while i < (len(sentence)):
m = window_size
while m >= 1:
fragment = sentence[i: i+ m]
if(m == 1 or fragment in dictionary):
yield fragment
i += len(fragment)
break
else:
m -= 1
以一个句子为例,调用一下算法:
if __name__ == '__main__':
sentence = "下雨天地面积水"
dictionary = ["下雨", "天地", "面积", "水", "下雨天", "雨天", "地面", "积水"]
print(list(前向最大匹配(sentence, dictionary)))
过程描述如下:
(1) i = 0, m = 3
下雨天地面积水
↑
i
因此从i位置开始向前看m个字符,即"下雨天"。发现这个词在词典里,所以令 i += 3, 返回这个词。
(2) i = 3, m = 3
下雨天地面积水
↑
i
继续从i位置开始向前看m个字符,即“天地面”。发现这个词不在词典,所以令 m -= 1
(3) i = 3, m = 2
下雨天地面积水
↑
i
继续从i位置开始向前看m个字符,即“天地”。发现这个词在词典,所以令 i += 2,并返回这个词
(4) i = 5, m = 3
下雨天地面积水
↑
i
继续从i位置开始向前看m个字符,但是句子只剩下2个字符,所以取“积水”。发现这个词在词典,所以令 i += 2, 并返回这个词。
(5) i = 7
此时i > 句子长度。算法结束。
因此计算结果为:
最少分词法
基于统计的方法
可以不必专门强调词表词信息。但是需要从已经标注好的样本数据中学习到分词规则。一般是使用统计机器学习的方法,但是近年深度学习的发展(指算法、算力)使得分词任务也可以使用深度学习的方法了。统计方法有生成式、判别式两种:
- 生成式:例如隐式马尔可夫模型(HMM),把字串作为显状态,把切分标志(词首B\词中M\词尾E\单独成词S)作为隐状态。通过维特比算法可以解码出字串对应最大概率的切分标志。
- 判别式:例如条件随机场(CRF)、最大熵模型。把分词任务看成是
字分类
问题。每个字都是(词首B\词中M\词尾E\单独成词S)中的一类。
这两种方法都可视为是序列标注任务。输入为字串序列 w 1 , w 2 , . . . , w n w_1,w_2,...,w_n w1,w2,...,wn, 输出为各个字的类别 c 1 , c 2 , . . . , c n c_1,c_2,...,c_n c1,c2,...,cn 下面举例分析:
输入:他只会诊断一般的疾病
输出:S B E B E B E S B E
根据输出的类别,就可以知道句子应当切分成:
他/只会/诊断/一般/的/疾病
评价指标
采用:准确率 P、召回率 R 和F1值。
P
=
n
N
P=\frac{n}{N}
P=Nn
R
=
n
M
R=\frac{n}{M}
R=Mn
F
1
=
2
P
R
P
+
R
F1=\frac{2PR}{P+R}
F1=P+R2PR
N N N表示系统输出的词个数。 M M M表示标准答案词个数。 n n n表示正确切分的结果词条个数。
命名实体识别
命名实体识别( Named Entity Recognition,NER)是词法分析的一项基本任务。命名实体包括:人名
、地名
、机构名
、数字
、时间日期
、货币数量
等。
其它专业术语、新的词汇等未登录词也可视为是命名实体。
在机器翻译任务中,高达28.6%是命名实体翻译错误,因此解决NER问题能够很大提高翻译正确率。
基于神经网络的NER
也是把NER看作序列标注任务。假设要识别时间
、地点
这两种命名实体。则可以根据BIO标注法,定义如下标签
B
t
,
I
t
,
B
s
,
I
s
,
O
{B_t,I_t,B_s,I_s, O}
Bt,It,Bs,Is,O,分别表示字符是 时间的开始字符
, 时间的中间或结束字符
,地点的开始字符
,地点的中间或结束字符
,其它字符
。当然,除此之外达有别的标注方法。
下图是使用示例,但是图中是使用BME标注法。→_→ 懒得画图了。
词性标注
在自然语言中,词性兼类
问题普遍存在。词性标注(Part-of-speech,POS)的主要任务就是消除词性兼类歧义。不同机构有不同的词性分类标准,下面数列举两个:
UPenn Treebank 的词性标注集 33个类
北大计算语言学研究所的词性标注集 106个类
实际上,在有些自然语言处理任务或方法中,词性、分词作用都不大。现在基本上都已经是端到端的方法了。
基于规则的方法
手工编写词性歧义消除规则。包括建立非兼类词典、兼类词典,识别规则等。
规则有:并列规则、同境鉴别规则、… 现在已经不用了。
基于统计模型的方法
把词性标注看成是序列标注问题。使用统计模型(例如HMM)、神经网络模型等等自动学习标注规则。方法与命名实体识别一样。