本文将会介绍如何使用kenlm工具进行文本纠错。
kenlm是用C++编写的语言模型工具,可以方便、快速地计算n-gram。kenlm工具的首页网址为:https://kheafield.com/code/kenlm/,该工具的Github网址为:https://github.com/kpu/kenlm。
关于kenlm的安装,本文不再详细介绍,网上有很多这方面的介绍。安装完kenlm工具包后,其文件夹目录结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| BUILDING CMakeLists.txt COPYING COPYING.3 COPYING.LESSER.3 Doxyfile GIT_REVISION LICENSE MANIFEST.in README.md build clean_query_only.sh cmake compile_query_only.sh include lm python setup.py util
|
模型训练
我们训练的语料为people2014_words.txt
,来自百度网盘,访问网址为https://pan.baidu.com/s/1971a5XLQsIpL0zL0zxuK2A#list/path=%2F。我们需要将原来已经分词好的文件(people2014_words.txt
)改成单个字的文件(people2014_chars.txt
),即每个字用空格隔开,python代码如下:
1 2 3 4 5 6 7
| with open("people2014_words.txt", "r", encoding="utf-8") as f: content = [_.strip() for _ in f.readlines()]
with open("people2014_chars.txt", "w", encoding="utf-8") as g: for line in content: g.write(" ".join(list("".join(line.split())))+"\n")
|
改写后的文件前两行如下:
1 . 手 指 长 度 一 项 2 0 0 8 年 在 期 刊 上 发 表 的 调 查 发 现 食
指 比 无 名 指 短 的 女 性 可 能 有 比 其 他 女 性 高 两 倍 的 可 能 性
患 上 在 膝 盖 处 的 关 节 炎 。 研 究 人 员 还 宣 称 , 有 这 些 明 显
男 性 特 征 的 女 性 更 加 容 易 雌 激 素 激 素 分 泌 水 平 低 , 这 可
能 会 对 关 节 炎 的 产 生 有 极 大 的 影 响 。 预 防 措 施 : 加 强 锻
炼 膝 盖 周 围 的 肌 肉 。 在 你 坐 着 的 时 候 , 把 两 腿 伸 直 并 平
行 于 地 面 , 做 十 次 每 次 坚 持 5 — 1 0 秒 。
我们将该文件放在build/result目录下。
切换至build文件夹所在目录,模型运行的运行命令如下:
1
| ./bin/lmplz -o 3 --verbose_header --text ./result/people2014_chars.txt --arpa ./result/people2014corpus_chars.arps -S 4G
|
运行参数解释:
- -o表示n-gram中n的数量,一般取3足够了,也可以取5;
- -verbose_header:在生成的文件头位置加上统计信息;
- --text表示输入的文本文件;--arpa表示输出的模型参数文件;
- -S表示使用系统内存大小,
注意:需要设置合适的内存大小,不然可能会运行失败
运行过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| === 1/5 Counting and sorting n-grams === Reading ~/work/kenlm/build/result/people2014_chars.txt ----5---10---15---20---25---30---35---40---45---50---55---60---65---70---75---80---85---90---95--100 **************************************************************************************************** Unigram tokens 36092956 types 6914 === 2/5 Calculating and sorting adjusted counts === Chain sizes: 1:82968 2:1493872896 3:2801011712 Statistics: 1 6914 D1=0.53084 D2=1.03394 D3+=1.4564 2 1159283 D1=0.625083 D2=1.08043 D3+=1.49998 3 6643214 D1=0.589546 D2=1.13123 D3+=1.52492 Memory estimate for binary LM: type MB probing 140 assuming -p 1.5 probing 147 assuming -r models -p 1.5 trie 48 without quantization trie 23 assuming -q 8 -b 8 quantization trie 46 assuming -a 22 array pointer compression trie 22 assuming -a 22 -q 8 -b 8 array pointer compression and quantization === 3/5 Calculating and sorting initial probabilities === Chain sizes: 1:82968 2:18548528 3:132864280 ----5---10---15---20---25---30---35---40---45---50---55---60---65---70---75---80---85---90---95--100
=== 4/5 Calculating and writing order-interpolated probabilities === Chain sizes: 1:82968 2:18548528 3:132864280 ----5---10---15---20---25---30---35---40---45---50---55---60---65---70---75---80---85---90---95--100
=== 5/5 Writing ARPA model === ----5---10---15---20---25---30---35---40---45---50---55---60---65---70---75---80---85---90---95--100 **************************************************************************************************** Name:lmplz VmPeak:4358320 kB VmRSS:24136 kB RSSMax:1112940 kB user:13.5094 sys:2.38785 CPU:15.8973 real:15.2563
|
运行完后会生成arps格式的模型文件,我们需要运行如下命令将模型文件进行压缩:
1
| ./bin/build_binary ./result/people2014corpus_chars.arps ./result/people2014corpus_chars.klm
|
运行完该命令后,就会生成klm格式的模型文件,模型文件体积大大减小,这也是我们所需要的的训练好后的模型文件。至此,我们已完成了使用kenlm训练n-gram模型。
文本纠错
pycorrector
模块支持使用自己训练好的kenlm模型进行纠错,参考网址:https://github.com/shibing624/pycorrector
。
演示的Python代码如下:
1 2 3 4 5 6 7 8 9 10
| from pycorrector import Corrector
lm_path = "~/work/kenlm/build/result/people2014corpus_chars.klm" model = Corrector(language_model_path=lm_path)
corrected_sent, detail = model.correct('真麻烦你了。希望你们好好的跳无') print(corrected_sent) print(detail)
|
我们对pycorrector中给出的5个样例句子进行纠错,结果如下:
1 2 3
| 原句:真麻烦你了。希望你们好好的跳无 纠错后:真麻烦你了。希望你们好好的跳舞 纠错细节:[('无', '舞', 14, 15)]
|
1 2 3
| 原句:少先队员因该为老人让坐 纠错后:少先队员应该为老人让坐 纠错细节:[('因该', '应该', 4, 6)]
|
1 2 3
| 原句:机七学习是人工智能领遇最能体现智能的一个分知 纠错后:机器学习是人工智能领域最能体现智能的一个分知 纠错细节:[('机七', '机器', 0, 2), ('领遇', '领域', 9, 11)]
|
1 2 3
| 原句:一只小鱼船浮在平净的河面上 纠错后:一只小鱼船夫在平静的河面上 纠错细节:[('船浮', '船夫', 4, 6), ('平净', '平静', 7, 9)]
|
1 2 3
| 原句:我的家乡是有明的渔米之乡 纠错后:我的家乡是有名的鱼米之乡 纠错细节:[('有明', '有名', 5, 7), ('渔米', '鱼米', 8, 10)]
|
可以看到,训练好的kenlm模型对于常见的文本错误具有一定的纠错能力,但也有一些没有纠正过来。
因为使用的是n-gram模型,所以文本纠错的效果依赖于语料的质量及语料大小。
总结
本文介绍了如何使用kenlm工具进行文本纠错。之所以写这篇文章,是因为网上人云亦云,很多文章都讲到使用kenlm训练n-gram模型时必须使用分词后的文件,但根据笔者自身的实践,发现分词后的文件并没有纠错能力,反而是单个字的文件进行训练有一定的纠错能力。希望大家不要迷信网上的所谓博客,还是要自己亲身实践下~
n-gram模型是文本纠错中的统计语言模型,属于较为简单的纠错方法,但有一定的使用价值,后续笔者将会为大家介绍更多的文本纠错相关内容,欢迎大家关注~
2021年7月26日于上海浦东,此日上海台风肆虐~
欢迎关注我的公众号
NLP奇幻之旅,原创技术文章第一时间推送。
欢迎关注我的知识星球“自然语言处理奇幻之旅”,笔者正在努力构建自己的技术社区。