【NLP】为什么中文分词比英文分词更难?有哪些常用算法?(附代码)
导读:人类文明的重要标志之一是语言文字的诞生。数千年来,几乎人类所有知识的传播都是以语言和文字作为媒介。
自然语言处理是使用计算机科学与人工智能技术分析和理解人类语言的一门学科。在人工智能的诸多范畴中,自然语言的理解以其复杂性、多义性成为难度最大也是最有价值的领域之一。
随着机器学习、统计学、深度学习的飞速进步,自然语言处理方面的研究取得了许多突破性的进展。本文将以文本分析中最基本的分词操作为入口,介绍人工智能处理自然语言的基本工具和方法,为读者打开语言分析和认知的大门。
来源:大数据DT(ID:hzdashuju)
00 文本分词
单词是语言中重要的基本元素。一个单词可以代表一个信息单元,有着指代名称、功能、动作、性质等作用。在语言的进化史中,不断有新的单词涌现,也有许多单词随着时代的变迁而边缘化直至消失。根据统计,《汉语词典》中包含的汉语单词数目在37万左右,《牛津英语词典》中的词汇约有17万。
理解单词对于分析语言结构和语义具有重要的作用。因此,在机器阅读理解算法中,模型通常需要首先对语句和文本进行单词分拆和解析。
分词(tokenization)的任务是将文本以单词为基本单元进行划分。由于许多词语存在词型的重叠,以及组合词的运用,解决歧义性是分词任务中的一个挑战。不同的分拆方式可能表示完全不同的语义。如在以下例子中,两种分拆方式代表的语义都有可能:
南京市|长江|大桥
南京|市长|江大桥
为了解决分词中的歧义性,许多相关算法被提出并在实践中取得了很好的效果。下面将对中文分词和英文分词进行介绍。
01 中文分词
在汉语中,句子是单词的组合。除标点符号外,单词之间并不存在分隔符。这就给中文分词带来了挑战。
分词的第一步是获得词汇表。由于许多中文词汇存在部分重叠现象,词汇表越大,分词歧义性出现的可能性就越大。因此,需要在词汇表的规模和最终分词的质量之间寻找平衡点。这里介绍一种主流的中文分词方式——基于匹配的分词。
这种分词方式采用固定的匹配规则对输入文本进行分割,使得每部分都是一个词表中的单词。正向最大匹配算法是其中一种常用算法,它的出发点是,文本中出现的词一般是可以匹配的最长候选词。
例如,对于文本“鞭炮声响彻夜空”,鞭炮和鞭炮声都是合理的单词,这里选择更长的鞭炮声,并最终分割成“鞭炮声|响彻|夜空”。
具体来说,正向最大匹配算法从第一个汉字开始,每次尝试匹配存在于词表中的最长的词,然后继续处理下一个词。这一过程无须每次在词表中查找单词,可以使用哈希表(hash table)或字母树(trie)进行高效匹配。
但是,正向最大匹配算法也经常会产生不符合逻辑的语句,如“为人民服务”,因为为人也是一个单词,所以算法会给出“为人|民|服务”的错误结果。
另一种改进的算法改变了匹配的顺序,即从后往前进行最大匹配。这种逆向最大匹配算法从文本末尾开始寻找在词表中最长的单词。读者可以发现,这种改进的算法能将“为人民服务”正确分词。统计结果表明,逆向最大匹配算法的错误率为1/245,低于正向最大匹配算法的错误率1/169。
下面给出逆向最大匹配算法的一个Python语言实现样例:
'''
逆向最大匹配算法
输入语句s和词表vocab,输出分词列表。
例子:
输入:s=‘今天天气真不错’,vocab=[‘天气’,‘今天’,‘昨天’,‘真’,‘不错’,‘真实’,‘天天’]
输出:[‘今天’,‘天气’,‘真’,‘不错’]
'''
def backward_maximal_matching(s, vocab):
result = []
end_pos = len(s)
while end_pos > 0:
found = False
for start_pos in range(end_pos):
if s[start_pos:end_pos] in vocab:
#找到最长匹配的单词,放在分词结果最前面
result = [s[start_pos:end_pos]] + result
found = True
break
if found:
end_pos = start_pos
else:
#未找到匹配的单词,将单字作为词分出
result = [s[end_pos - 1]] + result
end_pos -= 1
return result
此外,中文分词还有基于统计的方法。
02 英文分词
相比于中文分词,英文分词的难度要小得多,因为英文的书写要求单词之间用空格分开。因此,最简单的方法就是去除所有标点符号之后,按空格将句子分成单词。但是,使用这种方法有以下弊端:
-
标点符号有时需要作为词的一部分保留。 例如:Ph.D.、http://www.stanford.edu; -
英文中千分位的逗号表示。 例如:123,456.78; -
英文中缩写需要展开。 例如:you're表示you are、we'll表示we will; -
一些专有名词需要多个单词一起组成。 例如:New York、 San Francisco。
-
sses→ss:classes→class -
ies→i:ponies→poni -
ative→ :informative→inform
# 安装Jieba
# pip install jieba
import jieba
seg_list = jieba.cut(‘我来到北京清华大学’)
print('/ '.join(seg_list))
我/ 来到/ 北京/ 清华大学
# 安装spaCy
# pip install spacy
# python -m spacy download en_core_web_sm
import spacy
nlp = spacy.load('en_core_web_sm')
text = ('Today is very special. I just got my Ph.D. degree.')
doc = nlp(text)
print([e.text for e in doc])
['Today', 'is', 'very', 'special', '.', 'I', 'just', 'got', 'my', 'Ph.D.', 'degree', '.']
-
原句:Hongtao is visiting Weibo website. -
使用词表分词:<OOV> | is | visiting | <OOV> | website | . -
不依赖于词表分词:Hong | #tao | is | visit | #ing | Wei | #bo | website | .
//训练文本
wonder ponder toner
//按照当前子词分
w o n d e r
p o n d e r
t o n e r
//按照当前子词分
w o n d er
p o n d er
t o n er
//按照当前子词分
w on d er
p on d er
t on er
w ond er
p ond er
t on er
//解码新词fond
合并e r: f o n d
合并o n: f on d
合并on d:f ond
“为沉迷学习点赞↓