NLP 《分词方法》

在NLP中,最基础的处理的就是分词,不论是一个网页还是一片文章,还是一段话,都是需要先分词的才能去搞清楚这段话的意思的,这里介绍两个最经典的方法,都是基本的算法。

一:前向最大匹配(forward-max-matching)
分词之前,得知道什么才是单个词,就得有个词典库,作为分词的参考基础。因此我们需要一个包含了我们认为的所有词的词典。

前向最大匹配就是要匹尽量配出最长的字符串,也就是每次希望找到最长的词出来,方向是从前到后,每一步骤中匹配不成功的话,就把待匹配字段的最后一个字去掉继续进行匹配,这块简单,举个例子。

假设所有词语中最长的词语长度是max_len = 5
例子:我们经常有意见分歧
词典:[“我们”,“经常”,“有”,“有意见”,“意见”,“分歧”]

第一个词:
“我们经常有”没有在词典,排除掉。
“我们经常”没有在词典,排除掉。
“我们经”没有在词典,排除掉。
“我们”存在于词典,找到了一个词语。

第二个词:
“经常有意见”没有在词典,排除掉。
“经常有意”没有在词典,排除掉。
“经常有”没有在词典,排除掉。

“经常”存在于词典,找到了一个词语。

第三个词:
“有意见分歧”没有在词典,排除掉。
“有意见分”没有在词典,排除掉。
“有意见”存在于词典,找到了一个词语。

第四个词:
“分歧”存在于词典,找到了一个词语。

因此我们将原始句子分成了四个词语,分别是:
[“我们”,“经常”,“有意见”,“分歧”]

请注意:这里的max_len怎么取值呢?这个需要根据在词典表中做个统计,发现多各个长度等级的词语占比是多少?因为这个值越长,分词也就越准确,但是同时伴随着分词的时候耗费的时间也就越长,因此需要做个权衡,应该把大部分的词语所处的长度等级作为参考,当然为了准确度,在加一些细节上的处理。

二:后向最大匹配算法(backward-max matching)
我们学习了前向最大匹配,是从前到后进行查找最大匹配的词语,那么后向算法顾名思义,只不过是从后到前进行最大长度匹配,每一步骤中匹配不成功的话,就把待匹配字段的第一个字去掉继续进行匹配,举个例子。

假设所有词语中最长的词语长度是max_len = 5
例子:我们经常有意见分歧
词典:[“我们”,“经常”,“有”,“有意见”,“意见”,“分歧”]

第一个词:
“有意见分歧”没有在词典,排除掉。
“意见分歧”没有在词典,排除掉。
“见分歧”没有在词典,排除掉。
“分歧”存在于词典,找到了一个词语。

第二个词:
“经常有意见”没有在词典,排除掉。
“常有意见”没有在词典,排除掉。
“有意见”存在于词典,找到了一个词语。

第三个词:
“我们经常”没有在词典,排除掉。
“们经常”没有在词典,排除掉。
“经常”存在于词典,找到了一个词语。

第四个词:
“我们”存在于词典,找到了一个词语。

因此我们将原始句子分成了四个词语,分别是:
[“我们”,“经常”,“有意见”,“分歧”]

总结一下:这里只介绍了机械的编程下的分词,编程实现简单,也容易理解,但是它没有考虑到词性和语法,所以精确度可能不会很高,不能满足高标准的要求。需要综合考虑词性词义,上下文。

三:双向最大匹配算法(Bi-max matching)
由于前向最大依赖和后向最大匹配的准确度都不是很高,于是有了一个双向的最大匹配算法,也就是分别执行一次前向和后向的算法,90% 的概率二者是一样的结果,这好说,随意取一个结果。

要是二者结果不一样的,就需要按照一些原则来选择了,
1) 一个词语包含的字数越多,信息越多,也就是词语的个数越少越好,这样准确性也越高。
2) 词库中不存在的单个长度的词语越少越好,或者就说词库中不存在的词语也少越好。因为和可能会得到不存在于词典的词语。

比如前向结果:技术、和服、务
比如后向结果:技术、和、服务
很明显单个字的“务”应该不存在于词典中,而后向的结果存在单个字“和”,所以后向的结果更加合理。

四:其他分词方法
上述的方法属于机械式的分析方法,也可以说是基于匹配规则的方法。精确度不高,效率低,不能考虑歧义词义语义,下面提一嘴其他的方式,也可以是基于概率统计的方法,但是这里不展开说。
1) 语言模型(LM)
2) 基于隐马尔可夫模型的分词算法(HMM)
3) 基于条件随机场的分词算法(CRF)

中文分词是比较难的技术,也在不断地发展过程中,既要保证分词的准确度,也要保证分词的效率,才是构建搜索引擎的关键,二者必须都要达到很高的效率。

五:工具介绍
Jieba也可以叫做结巴,是一个比较流行的分词工具,网址是https://github.com/fxsjy/jieba
下面是测试代码,很简单,也特别好理解和使用。

# encoding=utf-8
import jieba

seg_list = jieba.cut("春花秋月何时了,往事知多少,小楼昨夜又东风,故国不堪回首月明中,雕栏玉砌应犹在,只是朱颜改,问君能有几多愁,恰似一江春水向东流", cut_all=False)
print("Result : " + "/".join(seg_list))

jieba.add_word('能有')
jieba.add_word('几多愁')
jieba.add_word('月明中')
jieba.add_word('何时了')
seg_list = jieba.cut("春花秋月何时了,往事知多少,小楼昨夜又东风,故国不堪回首月明中,雕栏玉砌应犹在,只是朱颜改,问君能有几多愁,恰似一江春水向东流", cut_all=False)
print("Result : " + "/".join(seg_list))

Jieba_cut就是分词的函数
Add_word就是可以增加一些自己想要的词语,算是自己根据自己的场景,自行定制的一些词汇表,丢给结巴。

除此之之外,还可以按照搜索引擎需要的去划分词,标注词性,TF-IDF等多功能。

猜你喜欢

转载自blog.csdn.net/qq_29367075/article/details/109019055