其他
NLP.TM[35] | 纠错:pycorrector的候选排序
【NLP.TM】
本人有关自然语言处理和文本挖掘方面的学习和笔记,欢迎大家关注。
往期回顾
有关pycorrector这块,之前讲了错误检测和召回,这回讲讲最后的一步,排序。有关pycorrector里面的排序内容其实比较简单,其实就这是基于ppl来做排序。来看看具体怎么做的。
def get_lm_correct_item(self, cur_item, candidates, before_sent, after_sent, threshold=57):
"""
通过语言模型纠正字词错误
:param cur_item: 当前词
:param candidates: 候选词
:param before_sent: 前半部分句子
:param after_sent: 后半部分句子
:param threshold: ppl阈值, 原始字词替换后大于该ppl值则认为是错误
:return: str, correct item, 正确的字词
"""
result = cur_item
if cur_item not in candidates:
candidates.append(cur_item)
ppl_scores = {i: self.ppl_score(list(before_sent + i + after_sent)) for i in candidates}
sorted_ppl_scores = sorted(ppl_scores.items(), key=lambda d: d[1])
# 增加正确字词的修正范围,减少误纠
top_items = []
top_score = 0.0
for i, v in enumerate(sorted_ppl_scores):
v_word = v[0]
v_score = v[1]
if i == 0:
top_score = v_score
top_items.append(v_word)
# 通过阈值修正范围
elif v_score < top_score + threshold:
top_items.append(v_word)
else:
break
if cur_item not in top_items:
result = top_items[0]
return result
从代码中能看到,其实长度就不是很长,核心代码也不是很长。
求全局ppl。 按照ppl排序。 最后确认是否纠正。
全局ppl
前面其实也有算分数,这里其实是算的是全局的ppl,毕竟纠错的最终目标就是让整个句子正确,这里的评价标准就是整个句子更加能“成句”。
ppl_scores = {i: self.ppl_score(list(before_sent + i + after_sent)) for i in candidates}
把修改部分的结果和原句拼接回去然后计算整个句子的混淆程度。
def ppl_score(self, words):
"""
取语言模型困惑度得分,越小句子越通顺
:param words: list, 以词或字切分
:return:
"""
self.check_detector_initialized()
return self.lm.perplexity(' '.join(words))
按照ppl排序
其实就是一行代码的事情:
sorted_ppl_scores = sorted(ppl_scores.items(), key=lambda d: d[1])
确认是否纠正
这里有一个比较有意思的事情,就是为了防止过纠,作者要求ppl必须超过原句一定距离,才让他纠。
# 增加正确字词的修正范围,减少误纠
top_items = []
top_score = 0.0
for i, v in enumerate(sorted_ppl_scores):
v_word = v[0]
v_score = v[1]
if i == 0:
top_score = v_score
top_items.append(v_word)
# 通过阈值修正范围
elif v_score < top_score + threshold:
top_items.append(v_word)
else:
break
if cur_item not in top_items:
result = top_items[0]
return result
其实纠错的排序的基线就是ppl算全局的效果,没有想到的是为了保证效果可靠性,防止过纠,所以加了一个阈值的约束。
小结
一连3篇讨论pycorrector方面基本纠错的讲解已经结束。这应该业内开源比较完整的一套方法了,简单的甚至可以直接拿来做基线,当然特殊场景可能需要一些调整,但是里面的内容是非常有参考意义的,未来需要优化也可以在调整架构后形成插件的模式加入,非常方便。