简介
- kenlm是Kenneth Heafield个人开发的语言模型工具,参考:https://kheafield.com/code/kenlm/
- GitHub: https://github.com/kpu/kenlm
安装流程省略
文本纠错应用
模型训练
- 准备数据
- 哈工大信息检索研究中心(HIT CIR)语言技术平台共享资源
http://ir.hit.edu.cn/demo/ltp/Sharing_Plan.htm
http://ir.hit.edu.cn/demo/ltp/HIT-CIR_LTP_Corpora_Sample_v1.rar
- 使用prepare.py脚本预处理,处理成如下的格式
中 国 开 展 登 月 计 划 的 意 义
神 舟 五 号 载 人 飞 船 带 着 亿 万 炎 黄 子 孙 的 期 盼 遨 游 九 天 。
关 于 月 亮 的 咏 叹 比 比 皆 是 :
我 国 古 代 , 帝 王 就 有 春 天 祭 日 、 秋 天 祭 月 的 礼 制 。
在 民 间 , 每 逢 八 月 中 秋 , 也 有 拜 月 或 祭 月 的 风 俗 。
关 于 月 球 的 传 说 家 喻 户 晓 :
- 训练模型:文本以单字切分,使用n-gram
bin/lmplz -o 2 --text ./data.txt --arpa lm.arpa -S 80% --discount_fallback
-o 指定n-gram
-S 指定使用多少内存
--discount_fallback 需要指定 不然会报下面的错
Unigram tokens 205390 types 2106
=== 2/5 Calculating and sorting adjusted counts ===
Chain sizes: 1:25272 2:18370318336 3:34444349440 4:55110959104
/data/xqchen4/3rd/kenlm/lm/builder/adjust_counts.cc:60 in void lm::builder::{anonymous}::StatCollector::CalculateDiscounts(const lm::builder::DiscountConfig&) threw BadDiscountException because `discounts_[i].a
mount[j] < 0.0 || discounts_[i].amount[j] > j'.ERROR: 4-gram discount out of range for adjusted count 3: -29.239872. This means modified Kneser-Ney smoothing thinks something is weird about your data. To override this error for e.g. a class-based model, r
erun with --discount_fallback
bin/build_binary -s lm.arpa lm.bin
demo应用测试
代码示例:
# 使用kenlm进行文本纠错
import kenlm
import json
def correction(lm,sentence,dict):
result = []
s1 = lm.perplexity(" ".join(sentence))
for i in range(len(sentence)):
cur_word = sentence[i]
if cur_word not in dict:
continue
cur_candidates = []
for candi in dict[cur_word]:
new_sentence = sentence
new_sentence[i] = candi
s2 = lm.perplexity(" ".join(new_sentence))
if s2 < s1:
cur_candidates.append({
"original":cur_word,
"correction":candi,
"position":i,
"perplexity":s2
})
#存在多个候选结果,则按照perplexity得分进行排序,取top1结果
if len(cur_candidates) > 1:
cur_candidates.sort(key = lambda e:e.__getitem__('perplexity'))
if len(cur_candidates) > 0:
result.append(cur_candidates[0])
return result
if __name__ == "__main__":
#提前训练好的模型
lm_model_path = "./model/lm.bin"
#别字词典
similarity_dictionary = {"泳":["永","咏"],"事":["是"]}
sentence = "关于月亮的泳叹比比皆事"
#加载模型
lm = kenlm.Model(lm_model_path)
#别字纠错计算
result = correction(lm,list(sentence),similarity_dictionary)
if result:
result.sort(key=lambda e: e.__getitem__('perplexity'))
print(json.dumps(result,ensure_ascii=False,indent=2))
Reference