标签:log hang min 工具包 time 交换 大小 关于 wrap
中文分词,即 Chinese Word Segmentation,即将一个汉字序列进行切分,得到一个个单独的词。表面上看,分词其实就是那么回事,但分词效果好不好对信息检索、实验结果还是有很大影响的,同时分词的背后其实是涉及各种各样的算法的。
中文分词与英文分词有很大的不同,对英文而言,一个单词就是一个词,而汉语是以字为基本的书写单位,词语之间没有明显的区分标记,需要人为切分。根据其特点,可以把分词算法分为四大类:
下面我们对这几种方法分别进行总结。
这种方法又叫作机械分词方法、基于字典的分词方法,它是按照一定的策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行匹配。若在词典中找到某个字符串,则匹配成功。该方法有三个要素,即分词词典、文本扫描顺序和匹配原则。文本的扫描顺序有正向扫描、逆向扫描和双向扫描。匹配原则主要有最大匹配、最小匹配、逐词匹配和最佳匹配。
此种方法优点是简单,易于实现。但缺点有很多:匹配速度慢;存在交集型和组合型歧义切分问题;词本身没有一个标准的定义,没有统一标准的词集;不同词典产生的歧义也不同;缺乏自学习的智能性。
该方法的主要思想:词是稳定的组合,因此在上下文中,相邻的字同时出现的次数越多,就越有可能构成一个词。因此字与字相邻出现的概率或频率能较好地反映成词的可信度。可以对训练文本中相邻出现的各个字的组合的频度进行统计,计算它们之间的互现信息。互现信息体现了汉字之间结合关系的紧密程度。当紧密程 度高于某一个阈值时,便可以认为此字组可能构成了一个词。该方法又称为无字典分词。
该方法所应用的主要的统计模型有:N 元文法模型(N-gram)、隐马尔可夫模型(Hiden Markov Model,HMM)、最大熵模型(ME)、条件随机场模型(Conditional Random Fields,CRF)等。
在实际应用中此类分词算法一般是将其与基于词典的分词方法结合起来,既发挥匹配分词切分速度快、效率高的特点,又利用了无词典分词结合上下文识别生词、自动消除歧义的优点。
语义分词法引入了语义分析,对自然语言自身的语言信息进行更多的处理,如扩充转移网络法、知识分词语义分析法、邻接约束法、综合匹配法、后缀分词法、特征词库法、矩阵约束法、语法分析法等。
基于理解的分词方法是通过让计算机模拟人对句子的理解,达到识别词的效果。其基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统可以获得有关词、句子等的句法和语义信息来对分词歧义进行判断,即它模拟了人对句子的理解过程。这种分词方法需要使用大量的语言知识和信息。目前基于理解的分词方法主要有专家系统分词法和神经网络分词法等。
以上便是对分词算法的基本介绍,接下来我们再介绍几个比较实用的分词 Python 库及它们的使用方法。
在这里介绍几个比较有代表性的支持分词的 Python 库,主要有:
专用于分词的 Python 库,GitHub:https://github.com/fxsjy/jieba,分词效果较好。
支持三种分词模式:
另外 jieba 支持繁体分词,支持自定义词典。
其使用的算法是基于统计的分词方法,主要有如下几种:
首先我们来看下精确模式分词,使用 lcut() 方法,类似 cut() 方法,其参数和 cut() 是一致的,只不过返回结果是列表而不是生成器,默认使用精确模式,代码如下:
1
2
3
4
|
import jieba
string = ‘这个把手该换了,我不喜欢日本和服,别把手放在我的肩膀上,工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作‘
result = jieba.lcut(string)
print(len(result), ‘/‘.join(result))
|
结果:
1
|
38 这个/把手/该换/了/,/我/不/喜欢/日本/和服/,/别/把手/放在/我/的/肩膀/上/,/工信处/女干事/每月/经过/下属/科室/都/要/亲口/交代/24/口/交换机/等/技术性/器件/的/安装/工作
|
可见分词效果还是不错的。
使用全模式分词需要添加 cut_all 参数,将其设置为 True,代码如下:
1
2
|
result = jieba.lcut(string, cut_all=True)
print(len(result), ‘/‘.join(result))
|
结果如下:
1
|
51 这个/把手/该换/了///我/不/喜欢/日本/和服///别/把手/放在/我/的/肩膀/上///工信处/处女/女干事/干事/每月/月经/经过/下属/科室/都/要/亲口/口交/交代/24/口交/交换/交换机/换机/等/技术/技术性/性器/器件/的/安装/安装工/装工/工作
|
使用搜索引擎模式分词需要调用 cut_for_search() 方法,代码如下:
1
2
|
result = jieba.lcut_for_search(string)
print(len(result), ‘/‘.join(result))
|
结果如下:
1
|
42 这个/把手/该换/了/,/我/不/喜欢/日本/和服/,/别/把手/放在/我/的/肩膀/上/,/工信处/干事/女干事/每月/经过/下属/科室/都/要/亲口/交代/24/口/交换/换机/交换机/等/技术/技术性/器件/的/安装/工作
|
另外可以加入自定义词典,如我们想把 日本和服 作为一个整体,可以把它添加到词典中,代码如下:
1
2
3
|
jieba.add_word(‘日本和服‘)
result = jieba.lcut(string)
print(len(result), ‘/‘.join(result))
|
结果如下:
1
|
37 这个/把手/该换/了/,/我/不/喜欢/日本和服/,/别/把手/放在/我/的/肩膀/上/,/工信处/女干事/每月/经过/下属/科室/都/要/亲口/交代/24/口/交换机/等/技术性/器件/的/安装/工作
|
可以看到切分结果中,日本和服 四个字就作为一个整体出现在结果中了,分词数量比精确模式少了一个。
另外 jieba 还支持词性标注,可以输出分词后每个词的词性,实例如下:
1
2
|
words = pseg.lcut(string)
print(list(map(lambda x: list(x), words)))
|
运行结果:
1
|
[[‘这个‘, ‘r‘], [‘把手‘, ‘v‘], [‘该‘, ‘r‘], [‘换‘, ‘v‘], [‘了‘, ‘ul‘], [‘,‘, ‘x‘], [‘我‘, ‘r‘], [‘不‘, ‘d‘], [‘喜欢‘, ‘v‘], [‘日本和服‘, ‘x‘], [‘,‘, ‘x‘], [‘别‘, ‘r‘], [‘把手‘, ‘v‘], [‘放在‘, ‘v‘], [‘我‘, ‘r‘], [‘的‘, ‘uj‘], [‘肩膀‘, ‘n‘], [‘上‘, ‘f‘], [‘,‘, ‘x‘], [‘工信处‘, ‘n‘], [‘女干事‘, ‘n‘], [‘每月‘, ‘r‘], [‘经过‘, ‘p‘], [‘下属‘, ‘v‘], [‘科室‘, ‘n‘], [‘都‘, ‘d‘], [‘要‘, ‘v‘], [‘亲口‘, ‘n‘], [‘交代‘, ‘n‘], [‘24‘, ‘m‘], [ |