NLP(四十九)使用kenlm进行文本纠错

本文将会介绍如何使用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
# -*- coding: utf-8 -*-
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

# 加载训练好的kenlm模型
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奇幻之旅,原创技术文章第一时间推送。

欢迎关注我的知识星球“自然语言处理奇幻之旅”,笔者正在努力构建自己的技术社区。


NLP(四十九)使用kenlm进行文本纠错
https://percent4.github.io/NLP(四十九)使用kenlm进行文本纠错/
作者
Jclian91
发布于
2023年7月10日
许可协议