目录
一、分词工具
现有的分词工具有很多,比较常用的是jieba分词,直接调用cut方法即可。可以通过add_word添加jieba词库中没有的词。也有其他的工具,这里简单列举几个以及网址。
二、分词工具底层算法
1.前向最大匹配
前向最大匹配是一种贪心算法。比如我们需要分词的句子是“我们经常有意见分歧”,并且我们的词典如下面所示:
我们有一个参数需要设置max_len,也就是开始匹配的最长的字符串长度。
比如设为5,那么:
①看“我们经常有”这五个字是否出现在词典中
②如果没有,就去掉“有”,看“我们经常”是否出现在词典中
③如果没有,去掉“常”,看“我们经”是否出现在词典中
④如果没有,去掉“经”,看“我们”是否出现在词典中
⑤发现“我们”在词典中出现,将其添加到结果中["我们"]
接下来继续选择最大长度“经常有意见”,还是按照上面的步骤匹配,最终匹配到“经常”,添加到结果中["我们", "经常"],同样的方法一直匹配到最后,剩余2个字,就直接匹配即可。
缺点:不能考虑语义、匹配的内容有可能还可以细分、局部最优、效率不高
2.语言模型
①传一个句子,找到所有可能的分割组合:比如:["我们", "经", "常", "有", "意", "见"], ["我们", "经常", "有", "意", "见"], ["我们", "经", "常", "有意", "见"], ["我们", "经常", "有", "意见"]......注意,组合中的词,都是在词典中出现的。词典中给出每个词的概率。
②根据一个语言模型,比如unigram language model,计算所有组合的概率:在unigram LM中,所有元素之间都是相互独立的,因此计算联合概率,把所有词的概率相乘即可。
比如:P( ["我们", "经常", "有", "意见"]) = P("我们")+P("经常")+P("有")+P("意见")
③计算联合概率的时候由于每个概率值都很小,因此取log,使相乘变相加,防止结果溢出。最后返回概率最高的结果。
缺点:时间复杂度高
代码实现:
3.维特比算法
该方法可以把上面的“找到所有组合” + “选出最好组合”合成一步,减少时间复杂度。
①根据词典中的词,以及对应的概率,创建出有向图。其中,没有出现在词典中的词,概率可以设为1e-8,以表示概率极小。为了方便计算,可以取负log
②使用动态规划方法找出从开头到最后最优的结果。