中文文本糾錯演算法–錯別字糾正的二三事
- 2019 年 11 月 27 日
- 筆記
本文首先介紹一下:
1)錯別字的類型有哪些
2)錯別字糾正的關鍵技術和關鍵點
3)簡要介紹我們項目中採用的文本糾錯框架
4)介紹錯別字項目的個人體會
5)幾個現成的工具包 ,百度nlp平台最近也推出了文本糾錯模組,處於內測中,所以沒有進行比較。如果有小夥伴能告知比較好的中文文本糾錯package,歡迎留言討論!感謝!
簡單總結了一下中文別字錯誤類型:
1. 別字:感帽,隨然,傳然,嘔土
2. 人名,地名錯誤:哈蜜(正:哈密)
3. 拼音錯誤:咳數(ke shu)—> ke sou,
4. 知識性錯誤:廣州黃浦(埔)
5. 用戶發音、方言糾錯:我系東北滴黑社會,俚蛾幾現在在我手上。(我是東北的黑社會,你兒子現在在我手上。)
6. 重複性錯誤:在 上 上面 上面 那 什麼 啊
7. 口語化問題:呃 。呃 ,啊,那用戶名稱是叫什麼呢?(正:那用戶名稱是叫什麼呢?)
錯別字糾正的主要技術:
- 錯別字詞典,編輯距離,語言模型(ngram LM,DNN LM,基於字的模型?基於詞的模型?)
- 三個關鍵點:分詞品質、領域相關詞表品質、語言模型的種類和品質
在最近的項目中,我們採用了pycorrector的糾錯邏輯,如下圖所示:

寫在前面:
一點總結:
1. 效果:現有錯別字糾正package大部分是通用領域的錯別字檢查,缺乏統一的評判標準,效果參差不齊。長句效果差,短句、單詞效果好一些,未來應用到產品中,也要根據標點符號截成短句,再進行錯別字檢查。
2. 口語化、重複性的問題,所有package不能解決此類問題。
3. 誤判率的問題!!!錯別字糾正功能有可能把正確的句子改成錯誤的。。這就要求,正確率x要遠大於誤判率y。假設有m個問題,其中2%是有錯別字的,m*2%*x>m*(1-2%)*y,根據個人的經驗,誤判率y是可以控制在1%以下的,如果有比較好的詞表,可以控制在0.5%以下。根據上述不等式,誤判率控制在0.5%以下,正確率達到24.5%就能滿足上述不等式。
4. 項目中,若測試數據不含重複錯別字樣本(錯別字:帳單,其中的帳這個錯別字只出現過一次),錯別字糾正的正確率達到了50%,誤判率0.49%左右。若包含重複樣本,正確率達到了70%以上。
後面這三點比較關鍵:
5. 項目中使用了基於n-gram語言模型,使用kenLM訓練得到的,DNN LM和n-gram LM各有優缺點,這裡賣個關子,感興趣的可以思考一下二者區別。另外,基於字的語言模型,誤判率會較高;基於詞的語言模型,誤判率會低一些(符合我個人的判斷,在我的實驗里情況也確實如此)。
6. 訓練語言模型的語料中並不clean,包含了很多錯別字,這會提高誤判率。使用更乾淨的語料有助於降低誤判率,提高正確率。
7. 專業相關詞表很關鍵,沒有高品質的詞表,很多字也會被誤認為是錯別字,所以也會提高誤判率。
測試樣本:
'感帽了','你兒字今年幾歲了', '少先隊員因該為老人讓坐','隨然今天很熱','傳然給我','嘔土不止','哈蜜瓜','廣州黃浦','在 上 上面 上面 那 什麼 啊','呃 。呃 ,啊,那用戶名稱是叫什麼呢?', '我生病了,咳數了好幾天', '對京東新人度大打折扣','我想買哥蘋果手機'
效果評價簡介:
a. 單詞、短句效果:一共13個測試樣本,9/13表示13個樣本中,糾正了9個錯誤。(長句效果差,沒有考慮)
b. 速度:考慮了13個樣本的總時間(用all表示,單位統一為秒),以及平均每個樣本的糾錯時間(用avg表示)
其中, with print 表示該糾錯方法的用時包含了「輸出到terminal的時間」,without print表示該糾錯方法的用時沒有包含「輸出到terminal的時間」。這麼劃分的原因是 輸出到terminal比較耗時,部分package可以選擇輸出or不輸出。
c. 可擴展性:主要(1)考慮該糾錯方法是否包含 自定義的錯別字詞典,方便個性化訂製;(2)考慮該糾錯方法,是否提供模型程式碼方便,在小娜的文本上進行訓練語言模型。
幾個現成的工具包:
1. https://github.com/shibing624/pycorrector pycorrector
簡介:考慮了音似、形似錯字(或變體字)糾正,可用於中文拼音、筆畫輸入法的錯誤糾正,能夠給出給出出錯位置。
語言模型:
- Kenlm(統計語言模型工具)
- RNNLM(TensorFlow、PaddlePaddle均有實現棧式雙向LSTM的語言模型)
程式碼:
import pycorrector
corrected_sent, detail = pycorrector.correct('少先隊員因該為老人讓坐')
print(corrected_sent, detail)
單詞、短句效果:9/13 效果尚可
速度:0.366050 all, 0.028157692 avg ;
可擴展性:詞典可擴展,可使用自己的語料進行訓練,該repo使用的是人民日報數據。擴展性強。
測試樣本效果:'感帽了','你兒字今年幾歲了', '少先隊員因該為老人讓坐','隨然今天很熱','傳然給我','嘔土不止','哈蜜瓜','廣州黃浦','在 上 上面 上面 那 什麼 啊','呃 。呃 ,啊,那用戶名稱是叫什麼呢?', '我生病了,咳數了好幾天', '對京東新人度大打折扣','我想買哥蘋果手機'
2. https://github.com/ccheng16/correction 10 months ago
簡介:
- 使用語言模型計算句子或序列的合理性
- bigram, trigram, 4-gram 結合,並對每個字的分數求平均以平滑每個字的得分
- 根據Median Absolute Deviation算出outlier分數,並結合jieba分詞結果確定需要修改的範圍
- 根據形近字、音近字構成的混淆集合列出候選字,並對需要修改的範圍逐字改正
- 句子中的錯誤會使分詞結果更加細碎,結合替換字之後的分詞結果確定需要改正的字
- 探測句末語氣詞,如有錯誤直接改正
特點:
訓練的語言模型很多,根據介紹看,整體比較完善,看起來高大上。不過code跑不起來,作者沒回應—–後面再改一下作者程式碼,看看能否跑起來。
3. https://github.com/PengheLiu/Cn_Speck_Checker 2 years ago
簡介:
針對醫學數據訓練出來的,基於編輯距離,可自行訓練–效果一般,統計詞頻和共現資訊,不太完善,返回大量candidates
特點:
- 人們通常越往後字打錯的可能越大,因而可以考慮每個字在單詞中的位置給予一定權重,這中方法有助於改進上面的第一種「傳然」- "雖然"的情況;
- 考慮拼音的重要性,對漢語來講,通常人們打錯時拼音是拼對的,只是選擇時候選擇錯了,因而對候選詞也可以優先選擇同拼音的字。
單詞、短句效果:1/13 效果差,因為訓練語料是醫學文章
速度:None
可擴展性:詞典+模型。擴展性還可以。
測試樣本效果:'感帽了','你兒字今年幾歲了', '少先隊員因該為老人讓坐','隨然今天很熱','傳然給我','嘔土不止','哈蜜瓜','廣州黃浦','在 上 上面 上面 那 什麼 啊','呃 。呃 ,啊,那用戶名稱是叫什麼呢?', '我生病了,咳數了好幾天', '對京東新人度大打折扣','我想買哥蘋果手機'
4. proofreadv1 — 效果一般,主要用於搜索引擎中的搜索關鍵詞的別字糾錯 5 years ago
詞頻字典+bi-gram
https://github.com/apanly/proofreadv1
模型比較老舊,不考慮
5. https://github.com/taozhijiang/chinese_correct_wsd 3 years ago
京東客服機器人語料做的中文糾錯–更接近我們的應用場景,主要解決同音自動糾錯問
題,比如:
對京東新人度大打折扣 — > 對京東信任度大打折扣
我想買哥蘋果手機 糾正句:我想買個蘋果手機
但程式碼多年未更新,目前跑不起來。
6. https://github.com/beyondacm/Autochecker4Chinese 9 months ago
original sentence:感帽,隨然,傳然,嘔土
corrected sentence:感冒,雖然,傳染,嘔吐
original sentence:對京東新人度大打折扣,我想買哥蘋果手機
corrected sentence:對京東新人度大打折扣,中國買賣蘋果手機
單詞、短句效果:5/13 效果差
速度:2.860311 all , 0.220023 avg;with print
可擴展性:詞典可擴展,不使用自己的語料進行訓練。擴展性一般。
測試樣本效果:'感帽了','你兒字今年幾歲了', '少先隊員因該為老人讓坐','隨然今天很熱','傳然給我','嘔土不止','哈蜜瓜','廣州黃浦','在 上 上面 上面 那 什麼 啊','呃 。呃 ,啊,那用戶名稱是叫什麼呢?', '我生病了,咳數了好幾天', '對京東新人度大打折扣','我想買哥蘋果手機'
7. https://github.com/SeanLee97/xmnlp 3-4 months ago
nlp工具包,包含分詞、情感分析,沒有專註於錯別字糾正,效果較差
單詞、短句效果:3/13 效果差
速度:2.860311 all , 0.220023 avg;without print: 0:00:00.000017 all
可擴展性:既沒發現詞典、也沒發現模型。擴展性較差。
測試樣本效果:'感帽了','你兒字今年幾歲了', '少先隊員因該為老人讓坐','隨然今天很熱','傳然給我','嘔土不止','哈蜜瓜','廣州黃浦','在 上 上面 上面 那 什麼 啊','呃 。呃 ,啊,那用戶名稱是叫什麼呢?', '我生病了,咳數了好幾天', '對京東新人度大打折扣','我想買哥蘋果手機'
項目做的比較急,調研的package不多,如果有更好的方案,求告知,謝謝啦!
本文轉載自公眾號:機器學習小知識,作者 楊洋