NLP(四十八)使用kenlm進(jìn)行文本糾錯(cuò)
??本文將會(huì)介紹如何使用kenlm工具進(jìn)行文本糾錯(cuò)。
??kenlm是用C++編寫(xiě)的語(yǔ)言模型工具,可以方便、快速地計(jì)算n-gram。kenlm工具的首頁(yè)網(wǎng)址為:https://kheafield.com/code/kenlm/,該工具的Github網(wǎng)址為:https://github.com/kpu/kenlm。
??關(guān)于kenlm的安裝,本文不再詳細(xì)介紹,網(wǎng)上有很多這方面的介紹。安裝完kenlm工具包后,其文件夾目錄結(jié)構(gòu)如下:
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
模型訓(xùn)練
??我們訓(xùn)練的語(yǔ)料為people2014_words.txt,來(lái)自百度網(wǎng)盤(pán),訪問(wèn)網(wǎng)址為https://pan.baidu.com/s/1971a5XLQsIpL0zL0zxuK2A#list/path=%2F。我們需要將原來(lái)已經(jīng)分詞好的文件(people2014_words.txt)改成單個(gè)字的文件(people2014_chars.txt),即每個(gè)字用空格隔開(kāi),python代碼如下:
# -*- 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")
改寫(xiě)后的文件前兩行如下:
1 . 手 指 長(zhǎng) 度
一 項(xiàng) 2 0 0 8 年 在 期 刊 上 發(fā) 表 的 調(diào) 查 發(fā) 現(xiàn) 食 指 比 無(wú) 名 指 短 的 女 性 可 能 有 比 其 他 女 性 高 兩 倍 的 可 能 性 患 上 在 膝 蓋 處 的 關(guān) 節(jié) 炎 。研 究 人 員 還 宣 稱 , 有 這 些 明 顯 男 性 特 征 的 女 性 更 加 容 易 雌 激 素 激 素 分 泌 水 平 低 , 這 可 能 會(huì) 對(duì) 關(guān) 節(jié) 炎 的 產(chǎn) 生 有 極 大 的 影 響 。預(yù) 防 措 施 :加 強(qiáng) 鍛 煉 膝 蓋 周 圍 的 肌 肉 。在 你 坐 著 的 時(shí) 候 , 把 兩 腿 伸 直 并 平 行 于 地 面 , 做 十 次 每 次 堅(jiān) 持 5 — 1 0 秒 。
我們將該文件放在build/result目錄下。
??切換至build文件夾所在目錄,模型運(yùn)行的運(yùn)行命令如下:
./bin/lmplz -o 3 --verbose_header --text ./result/people2014_chars.txt --arpa ./result/people2014corpus_chars.arps -S 4G
運(yùn)行參數(shù)解釋:
-o表示n-gram中n的數(shù)量,一般取3足夠了,也可以取5;
-verbose_header:在生成的文件頭位置加上統(tǒng)計(jì)信息;
--text表示輸入的文本文件;--arpa表示輸出的模型參數(shù)文件;
-S表示使用系統(tǒng)內(nèi)存大小,
注意:需要設(shè)置合適的內(nèi)存大小,不然可能會(huì)運(yùn)行失敗
運(yùn)行過(guò)程如下:
=== 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
?emsp;運(yùn)行完后會(huì)生成arps格式的模型文件,我們需要運(yùn)行如下命令將模型文件進(jìn)行壓縮:
./bin/build_binary ./result/people2014corpus_chars.arps ./result/people2014corpus_chars.klm
運(yùn)行完該命令后,就會(huì)生成klm格式的模型文件,模型文件體積大大減小,這也是我們所需要的的訓(xùn)練好后的模型文件。至此,我們已完成了使用kenlm訓(xùn)練n-gram模型。
文本糾錯(cuò)
??pycorrector模塊支持使用自己訓(xùn)練好的kenlm模型進(jìn)行糾錯(cuò),參考網(wǎng)址:https://github.com/shibing624/pycorrector 。
??演示的Python代碼如下:
from pycorrector import Corrector
# 加載訓(xùn)練好的kenlm模型
lm_path = "~/work/kenlm/build/result/people2014corpus_chars.klm"
model = Corrector(language_model_path=lm_path)
# 文本糾錯(cuò)
corrected_sent, detail = model.correct('真麻煩你了。希望你們好好的跳無(wú)')
print(corrected_sent)
print(detail)
我們對(duì)pycorrector中給出的5個(gè)樣例句子進(jìn)行糾錯(cuò),結(jié)果如下:
原句:真麻煩你了。希望你們好好的跳無(wú)
糾錯(cuò)后:真麻煩你了。希望你們好好的跳舞
糾錯(cuò)細(xì)節(jié):[('無(wú)', '舞', 14, 15)]
原句:少先隊(duì)員因該為老人讓坐
糾錯(cuò)后:少先隊(duì)員應(yīng)該為老人讓坐
糾錯(cuò)細(xì)節(jié):[('因該', '應(yīng)該', 4, 6)]
原句:機(jī)七學(xué)習(xí)是人工智能領(lǐng)遇最能體現(xiàn)智能的一個(gè)分知
糾錯(cuò)后:機(jī)器學(xué)習(xí)是人工智能領(lǐng)域最能體現(xiàn)智能的一個(gè)分知
糾錯(cuò)細(xì)節(jié):[('機(jī)七', '機(jī)器', 0, 2), ('領(lǐng)遇', '領(lǐng)域', 9, 11)]
原句:一只小魚(yú)船浮在平凈的河面上
糾錯(cuò)后:一只小魚(yú)船夫在平靜的河面上
糾錯(cuò)細(xì)節(jié):[('船浮', '船夫', 4, 6), ('平凈', '平靜', 7, 9)]
原句:我的家鄉(xiāng)是有明的漁米之鄉(xiāng)
糾錯(cuò)后:我的家鄉(xiāng)是有名的魚(yú)米之鄉(xiāng)
糾錯(cuò)細(xì)節(jié):[('有明', '有名', 5, 7), ('漁米', '魚(yú)米', 8, 10)]
??可以看到,訓(xùn)練好的kenlm模型對(duì)于常見(jiàn)的文本錯(cuò)誤具有一定的糾錯(cuò)能力,但也有一些沒(méi)有糾正過(guò)來(lái)。
??因?yàn)槭褂玫氖莕-gram模型,所以文本糾錯(cuò)的效果依賴于語(yǔ)料的質(zhì)量及語(yǔ)料大小。
總結(jié)
??本文介紹了如何使用kenlm工具進(jìn)行文本糾錯(cuò)。之所以寫(xiě)這篇文章,是因?yàn)榫W(wǎng)上人云亦云,很多文章都講到使用kenlm訓(xùn)練n-gram模型時(shí)必須使用分詞后的文件,但根據(jù)筆者自身的實(shí)踐,發(fā)現(xiàn)分詞后的文件并沒(méi)有糾錯(cuò)能力,反而是單個(gè)字的文件進(jìn)行訓(xùn)練有一定的糾錯(cuò)能力。希望大家不要迷信網(wǎng)上的所謂博客,還是要自己親身實(shí)踐下~
??n-gram模型是文本糾錯(cuò)中的統(tǒng)計(jì)語(yǔ)言模型,屬于較為簡(jiǎn)單的糾錯(cuò)方法,但有一定的使用價(jià)值,后續(xù)筆者將會(huì)為大家介紹更多的文本糾錯(cuò)相關(guān)內(nèi)容,歡迎大家關(guān)注~
??2021年7月26日于上海浦東,此日上海臺(tái)風(fēng)肆虐~
