文分词介绍
中文分词相较于英文分词要难许多,因为英文本身就是由单词与空格组成的,而中文则是由独立的字组成的,但同时语义却是有词来表达的。因此对于中文的分析与研究,首先应寻找合适的方法进行分词。现有的中文分词技术主要分为规则分词,统计分词与规则加统计相结合的方式,接下来将分别介绍。
规则分词
规则分词主要是通过构建词典,对需要进行分词的语句与词典中的词语进行匹配,从而实现切分,具体主要有正向最大匹配法,逆向最大匹配法,双向最大匹配法。
正向最大匹配法
正向最大匹配法实现的原理如下:假设分词词典中最长词语的长度为 i, 那么则选取需要进行分词的语句中的前 i个字,查询是否匹配词典中长度为i的词。如果匹配,则进行切分;如果不匹配,则选取i-1个字查询分词词典是否匹配,以此类推,直至成功切分。接着对于剩余的字段采取同样的方法进行切分,直到最后完全切分。
比如我们现在要对“正向最大匹配法”进行分词,而我们的分词字典最长的词语长度为4。首先选取前四个字“正向最大”,词典中并无匹配,那么接着选取前三个字“正向最”,依旧没有,再选择前两个字“正向”,成功匹配,则进行切分,接着选取之后的四个字“最大匹配”,以此类推,继续切分,直至切分完毕。
逆向最大匹配法
逆向最大匹配法的原理与正向是基本一致的,只是逆向最大匹配法是从句尾开始进行匹配。由于汉语中偏正结构较多,一般逆向最大匹配法的结果准确度要稍高于正向最大匹配法
双向最大匹配法
双向最大匹配法是在正向与逆向最大匹配法的基础上对两者结果进行比较,选取切分词数较少的一个结果作为最终分词。双向最大匹配法在实际中运用更为广
接下来,我们可以通过python实现简单的三种最大匹配法:
#读取训练字典
def readDict(path):
dictionary=[]
maximum=0
with open(path,'r',encoding='utf-8') as f:
for line in f:
line=line.strip()
if line:
dictionary.append(line)
if maximum<len(line):
maximum=len(line)
else:
continue
return dictionary,maximum
#正向最大匹配法
def forwardCut(text,dictionary,maximum):
result=[]
index=0
while index<len(text):
word=None
for i in range(maximum,0,-1):
if len(text)-index<i+1:
continue
piece=text[index:index+i]
if piece in dictionary:
word=piece
result.append(word)
index+=i
break
if word ==None:
result.append(text[index:index+1])
index+=1
return result
#逆向最大匹配法
def backwardCut(text,dictionary,maximum):
result=[]
index=len(text)
while index>0:
word=None
for i in range(maximum,0,-1):
if index-i<0:
continue
piece=text[index-i:index]
if piece in dictionary:
word=piece
result.append(word)
index-=i
break
if word==None:
result.append(text[index-1:index])
index-=1
return result[::-1]
#双向最大匹配法
def compare(text,dictionary,maximum):
Fresult=forwardCut(text,dictionary,maximum)
Bresult=backwardCut(text,dictionary,maximum)
if len(Fresult)<len(Bresult):
return '/'.join(Fresult)
else:
return '/'.join(Bresult)
接下来,我们通过输入自制词典来比较三种分词方法的结果。词典如下:
正向最大匹配法:
dictionary,maximum=readDict('dic.utf8')
print('/'.join(forwardCut('双向最大匹配法',dictionary,maximum)))
输出结果为:
逆向最大匹配法:
print('/'.join(backwardCut('双向最大匹配法',dictionary,maximum)))
输出结果为:
双向最大匹配法:
print(compare('双向最大匹配法',dictionary,maximum))
输出结果为:
规则分词在一般的分词任务中已经能够得到较好的结果了,但是其缺点是需要大量人力物力去维护与更新分词词典。同时,对于新词,规则分词很难能够正确切割。相反,统计分词法较好的解决的这个问题。
统计分词
统计分词的基本思想是基于统计的概念,如果相连的字在不同的地方出现的次数越多,则其越有可能为一个词。因此我们可以利用出项概率来推测成词的可能性,从而实现分词。常见的统计分词方法有隐含马尔可夫(HMM)、条件随机场(CRF)等。接下来我们首先建立统计分词的语言模型,接着简单介绍一下HMM
统计分词语言模型
假设字符串的长度为m,那么对于这个字符串的概率分布可以描述为:
P ( w 1 , w 2 , . . . , w m ) P(w_1,w_2,...,w_m) P(w1,w2,...,wm)
通过链式法则,我们可以计算其概率值:
P ( w 1 , w 2 , . . . , w m ) = P ( w 1 ) P ( w 2 ∣ w 1 ) P ( w 3 ∣ w 2 , w 1 ) ⋅ ⋅ ⋅ P ( w i ∣ w i − 1 , w i − 2 , . . , w 1 ) ⋅ ⋅ ⋅ P ( w m ∣ w m − 1 . . . w 1 ) P(w_1,w_2,...,w_m)=P(w_1)P(w_2|w_1)P(w_3|w_2,w_1)···P(w_i|w_{i-1},w_{i-2},..,w_1) ···P(w_m|w_{m-1}...w_1) P(w1,w2,...,wm)=P(w1)P(w2∣w1)P(w3∣w2,w