自然语言处理-2-分词(Word Segmentation)


 
链接:[ 全文章目录 ]


一、引入问题

 对于输入的一句话:“我们经常有意见分歧”
 我们首先想在电脑中如何表达:用单字表达、用词汇表达、还是直接将一整个句子看作是一个整体。
 可以很容易的想到,单字的意思不完整,句子同样意思下的表达方式多种多样近乎无限;词汇有固定的一种或几种语义,非常适合用来表达句子内在的意思。
 


二、分词的几种方法

 现在我们知道了使用词汇来进行分词,假设现在有词典如下(一些词典是开源的):
  [“我们”, “经常”, “有”, “有意⻅”,“意⻅”,“分歧”]
 那么我们就可以开始分词了

(一)前向最大匹配(forward-max matching)

  首先我们设定最大长度的大小为4,然后我们用词典对上面那句话进行分词。(【】括号中为关注的字符串)
  第一轮:
  【我们经常】有意见分歧(取前4个字(最大长度),发现 “我们经常” 不在词典中)
  【我们经】常有意见分歧(取前3个字,发现 “我们经” 不在词典中)
  【我们】经常有意见分歧(取前2个字,发现 “我们” 在词典中,结束)
  此时分词为:我们 | 经常有意见分歧

  第二轮:
  【经常有意】见分歧(取前4个字(最大长度),发现 “经常有意” 不在词典中)
  【经常有】意见分歧(取前3个字,发现 “经常有” 不在词典中)
  【经常】有意见分歧(取前2个字,发现 “经常” 在词典中,结束)
  此时分词为:我们 | 经常 | 有意见分歧

  第三轮:
  【有意见分】歧(取前4个字(最大长度),发现 “有意见分” 不在词典中)
  【有意见】分歧(取前3个字,发现 “有意见” 在词典中,结束)
  此时分词为:我们 | 经常 | 有意见 | 分歧

  第四论:
  【分歧】(不满足4的最大长度就选择剩下的全部,发现 “分歧” 在词典中,结束)
  此时分词为:我们 | 经常 | 有意见 | 分歧
 

(二)后向最大匹配(backward-max matching)

  假定此时最大长度仍为4,后向最大匹配类似前向最大匹配,只是一个向句尾(前向),一个向句首(后向)。下面大家可以根据前向最大匹配来理解。
  第一轮:
  我们经常有【意见分歧】
  我们经常有意【见分歧】
  我们经常有意见【分歧】
  此时分词为:我们经常有意见 | 分歧

  第二轮:
  我们经【常有意见】
  我们经常【有意见】
  此时分词为:我们经常 | 有意见 | 分歧

  第三轮:
  【我们经常】
  我【们经常】
  我们【经常】
  此时分词为:我们 | 经常 | 有意见 | 分歧

  第四论:
  【我们】
  此时分词为:我们 | 经常 | 有意见 | 分歧
 

(三)考虑语义(Incorporate Semantic)

  考虑语义顾名思义,就是判断语义,具体为生成句子可能的所有分割,在这些分割中返回最好的。
  判断好坏的方法可以使用语言模型(Language Model)。
  语言模型是什么:
  对于一个分好词的句子:“ 我们 | 经常 | 有意见 | 分歧 ”,假设我们已知词汇在词库中出现的概率(这种概率可以通过统计网页、书籍提前计算出)

Unigram Language Model为:P(S0) = P(“我们”) * P(“经常”) * P(“有意见”) * P(“分歧”)
Bigram Language Model为:P(S0) = P(“我们”) * P(“经常” | “我们”) * P(“有意见” | “经常”) * P(“分歧” | “有意见”)
Trigram Language Model为:P(S0) = P(“我们”) * P(“经常” | “我们”) * P(“有意见” | “我们”,“经常”) * P(“分歧” | “经常”,“有意见”)

  很容易看出其实就是n-gram Language Model,n为几,则概率考虑前n个词。

注意,由于每个词在所有的文本中出现的次数可能非常少,所以概率值可能非常非常非常小,导致负溢出,所以会将概率套一层log()。因为log10(0.00000001)=-8,可见值是下降的很缓慢的,而且log10是单调递增的函数,与原概率的大小比较结果相同。

  现在我们知道了考虑语义的用法,但是不妨思考一下,假设一个句子的长度有最大值n个词汇,那么在Unigram的情况下语言模型对一种分词情况下计算的时间是O(n),产生所有的分割又需要O((n-1)!)。那么总体的时间复杂度为O(n*(n-1)!) = O(n!),而且这个复杂度只是对于一个句子,如果是一系列大量句子的话时间就难以承受,所以我们需要优化一下这种方法才能实际使用。
 

(四)考虑语义的优化方法(维特比算法)

  从上面我们知道了“考虑语义”分为两步,一是产生所有分割,二是判断产生的分割的分词好不好。两个方面都不容易进行优化,那不妨把两个方面放在一起思考。
假设现在有一个句子Pn的长度为n,目标是求得这个句子最好的分割。那么子问题就是Pn-1这个句子有最好的分割(即减去Pn的最后一个字)。
  这种带有最优子结构的问题我们很快就能想到使用动态规划进行求解。公式为:
P n = m a x x : 1 n 1 { P x + D [ x ] [ n ] } P_n = max_{x:1 \rightarrow n-1}\{P_{x}+D[x][n]\}

 解释:
 Pn是指句子S前n个字的最好分割的语言模型概率P(这里的P是log后的),D[x][n]是指从x到n的独立的词的概率,D[x][n]为-1的话就代表x到n的独立的词汇不在词库中。概率为什么变为加法是因为log10(P1 * P2) = log10P1 + log10P2。(这个算法有点像最大上升子序列算法,根据习惯一般会求最小值,此时P就要进行-log)。
 怎么找到最好的分词:
 更新最好分词的时候单独使用一个数组进行记录。


三、分词总结

方法 具体
基于匹配规则方法 前向最大匹配、后向最大匹配等
基于概率统计的方法 语言模型LM、隐马尔可夫模型HMM、条件随机场CRF等

  分词可以认为是已经解决的问题,因为已经有了成熟的分词工具,如:jieba分词、SnowNLP、LTP、HanNLP。

发布了11 篇原创文章 · 获赞 96 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_42159233/article/details/104184071
今日推荐