View on GitHub

pycorrector

pycorrector is a toolkit for text error correction. 文本纠错,Kenlm,Seq2Seq_Attention,BERT,MacBERT,ELECTRA,ERNIE,Transformer等模型实现,开箱即用。

alt text

PyPI version Contributions welcome GitHub contributors License Apache 2.0 python_vesion GitHub issues Wechat Group

pycorrector

中文文本纠错工具。音似、形似错字(或变体字)纠正,可用于中文拼音、笔画输入法的错误纠正。python3.6开发。

pycorrector依据语言模型检测错别字位置,通过拼音音似特征、笔画五笔编辑距离特征及语言模型困惑度特征纠正错别字。

Guide

Question

中文文本纠错任务,常见错误类型包括:

当然,针对不同业务场景,这些问题并不一定全部存在,比如输入法中需要处理前四种,搜索引擎需要处理所有类型,语音识别后文本纠错只需要处理前两种, 其中’形似字错误’主要针对五笔或者笔画手写输入等。本项目重点解决其中的谐音、混淆音、形似字错误、中文拼音全拼、语法错误带来的纠错任务。

Solution

规则的解决思路

  1. 中文纠错分为两步走,第一步是错误检测,第二步是错误纠正;
  2. 错误检测部分先通过结巴中文分词器切词,由于句子中含有错别字,所以切词结果往往会有切分错误的情况,这样从字粒度和词粒度两方面检测错误, 整合这两种粒度的疑似错误结果,形成疑似错误位置候选集;
  3. 错误纠正部分,是遍历所有的疑似错误位置,并使用音似、形似词典替换错误位置的词,然后通过语言模型计算句子困惑度,对所有候选集结果比较并排序,得到最优纠正词。

PS:网友源码解读

深度模型的解决思路

  1. 端到端的深度模型可以避免人工提取特征,减少人工工作量,RNN序列模型对文本任务拟合能力强,rnn_attention在英文文本纠错比赛中取得第一名成绩,证明应用效果不错;
  2. CRF会计算全局最优输出节点的条件概率,对句子中特定错误类型的检测,会根据整句话判定该错误,阿里参赛2016中文语法纠错任务并取得第一名,证明应用效果不错;
  3. Seq2Seq模型是使用Encoder-Decoder结构解决序列转换问题,目前在序列转换任务中(如机器翻译、对话生成、文本摘要、图像描述)使用最广泛、效果最好的模型之一;
  4. BERT/ELECTRA/ERNIE/MacBERT等预训练模型强大的语言表征能力,对NLP届带来翻天覆地的改变,海量的训练数据拟合的语言模型效果无与伦比,基于其MASK掩码的特征,可以简单改造预训练模型用于纠错,加上fine-tune,效果轻松达到最优。

Feature

模型

错误检测

错误纠正

思考

  1. 现在的处理手段,在词粒度的错误召回还不错,但错误纠正的准确率还有待提高,更多优质的纠错集及纠错词库会有提升,我更希望算法上有更大的突破。
  2. 另外,现在的文本错误不再局限于字词粒度上的拼写错误,需要提高中文语法错误检测(CGED, Chinese Grammar Error Diagnosis)及纠正能力,列在TODO中,后续调研。

Demo

http://42.193.145.218/product/corrector/

Evaluate

查看评估结论 提供评估脚本[pycorrector/utils/eval.py](/pycorrector/pycorrector/utils/eval.py)和评估执行脚本[examples/evaluate_models.py](/pycorrector/examples/evaluate_models.py),该脚本有两个功能: - 构建评估样本集:评估集[pycorrector/data/eval_corpus.json](/pycorrector/pycorrector/data/eval_corpus.json), 包括字粒度错误100条、词粒度错误100条、语法错误100条,正确句子200条。用户可以修改条数生成其他评估样本分布。 - 计算两个数据集的纠错准召率:采用保守计算方式,简单把纠错之后与正确句子完成匹配的视为正确,否则为错。 ### 测试环境: - 机器:linux(centos7) 线上机 - CPU:28核 Intel(R) Xeon(R) Gold 5117 CPU @ 2.00GHz - GPU:Tesla P40,显存 22919 MiB(22 GB) - 内存:251 GB | 数据集 | 模型 | cpu/gpu | 准确率 | 召回率 | 每百条预测时长(秒) | QPS | | :------- | :--------- | :--------- | :---------: | :---------: | :---------: | :---------: | | sighan_15 | rule | cpu | 17.98% | 15.37% | 11 | 9 | | sighan_15 | bert | gpu | 37.62% | 36.46% | 95 | 1.05 | | sighan_15 | ernie | gpu | 29.70% | 28.13% | 102 | 0.98 | | **sighan_15** | **macbert** | **gpu** | **63.64%** | **63.64%** | **2** | **50** | | corpus500 | rule | cpu | 48.60% | 28.13% | 11 | 9 | | corpus500 | bert | gpu | 58.60% | 35.00% | 95 | 1.05 | | corpus500 | ernie | gpu | 59.80% | 41.33% | 102 | 0.98 | | corpus500 | macbert | gpu | 56.20% | 42.67% | 2 | 50 |

Install

通过以上两种方法的任何一种完成安装都可以。如果不想安装依赖包,直接使用docker拉取安装好的部署环境即可。

安装依赖

使用示例:

docker

Usage

示例base_demo.py

import pycorrector

corrected_sent, detail = pycorrector.correct('少先队员因该为老人让坐')
print(corrected_sent, detail)

output:

少先队员应该为老人让座 [('因该', '应该', 4, 6), ('坐', '座', 10, 11)]

规则方法默认会从路径~/.pycorrector/datasets/zh_giga.no_cna_cmn.prune01244.klm加载kenlm语言模型文件,如果检测没有该文件,则程序会自动联网下载。当然也可以手动下载模型文件(2.8G)并放置于该位置。

查看更多使用说明 - 错误检测 示例[detect_demo.py](/pycorrector/examples/detect_demo.py) ```python import pycorrector idx_errors = pycorrector.detect('少先队员因该为老人让坐') print(idx_errors) ``` output: ``` [['因该', 4, 6, 'word'], ['坐', 10, 11, 'char']] ``` > 返回类型是`list`, `[error_word, begin_pos, end_pos, error_type]`,`pos`索引位置以0开始。 - 关闭字粒度纠错 示例[disable_char_error.py](/pycorrector/examples/disable_char_error.py) ```python import pycorrector error_sentence_1 = '我的喉咙发炎了要买点阿莫细林吃' correct_sent = pycorrector.correct(error_sentence_1) print(correct_sent) ``` output: ``` '我的喉咙发炎了要买点阿莫西林吉', [('细林', '西林', 12, 14), ('吃', '吉', 14, 15)] ``` 上例中`吃`发生误纠,如下代码关闭字粒度纠错: ```python import pycorrector error_sentence_1 = '我的喉咙发炎了要买点阿莫细林吃' pycorrector.enable_char_error(enable=False) correct_sent = pycorrector.correct(error_sentence_1) print(correct_sent) ``` output: ``` '我的喉咙发炎了要买点阿莫西林吃', [('细林', '西林', 12, 14)] ``` 默认字粒度、词粒度的纠错都打开,一般情况下单字错误发生较少,而且字粒度纠错准确率较低。关闭字粒度纠错,这样可以提高纠错准确率,提高纠错速度。 > 默认`enable_char_error`方法的`enable`参数为`True`,即打开错字纠正,这种方式可以召回字粒度错误,但是整体准确率会低; > 如果追求准确率而不追求召回率的话,建议将`enable`设为`False`,仅使用错词纠正。 - 加载自定义混淆集 通过加载自定义混淆集,支持用户纠正已知的错误,包括两方面功能:1)错误补召回;2)误杀加白。 示例[use_custom_confusion.py](/pycorrector/examples/use_custom_confusion.py) ```python import pycorrector pycorrector.set_log_level('INFO') error_sentences = [ '买iphonex,要多少钱', '共同实际控制人萧华、霍荣铨、张旗康', ] for line in error_sentences: print(pycorrector.correct(line)) print('*' * 42) pycorrector.set_custom_confusion_dict(path='./my_custom_confusion.txt') for line in error_sentences: print(pycorrector.correct(line)) ``` output: ``` ('买iphonex,要多少钱', []) # "iphonex"漏召,应该是"iphoneX" ('共同实际控制人萧华、霍荣铨、张启康', [['张旗康', '张启康', 14, 17]]) # "张启康"误杀,应该不用纠 ***************************************************** ('买iphonex,要多少钱', [['iphonex', 'iphoneX', 1, 8]]) ('共同实际控制人萧华、霍荣铨、张旗康', []) ``` 具体demo见[example/use_custom_confusion.py](/pycorrector/examples/use_custom_confusion.py),其中`./my_custom_confusion.txt`的内容格式如下,以空格间隔: ``` iPhone差 iPhoneX 100 张旗康 张旗康 ``` > `set_custom_confusion_dict`方法的`path`参数为用户自定义混淆集文件路径。 - 加载自定义语言模型 默认提供下载并使用的kenlm语言模型`zh_giga.no_cna_cmn.prune01244.klm`文件是2.8G,内存较小的电脑使用`pycorrector`程序可能会吃力些。 支持用户加载自己训练的kenlm语言模型,或使用2014版人民日报数据训练的模型,模型小(140M),准确率低些。 示例[load_custom_language_model.py](/pycorrector/examples/load_custom_language_model.py),其中[people2014corpus_chars.klm(密码o5e9)](https://pan.baidu.com/s/1I2GElyHy_MAdek3YaziFYw)是自定义语言模型文件。 ```python from pycorrector import Corrector import os pwd_path = os.path.abspath(os.path.dirname(__file__)) lm_path = os.path.join(pwd_path, './people2014corpus_chars.klm') model = Corrector(language_model_path=lm_path) corrected_sent, detail = model.correct('少先队员因该为老人让坐') print(corrected_sent, detail) ``` output: ``` 少先队员应该为老人让座 [('因该', '应该', 4, 6), ('坐', '座', 10, 11)] ``` - 英文拼写纠错 支持英文单词的拼写错误纠正。 示例[en_correct_demo.py](/pycorrector/examples/en_correct_demo.py) ```python import pycorrector sent = "what happending? how to speling it, can you gorrect it?" corrected_text, details = pycorrector.en_correct(sent) print(sent, '=>', corrected_text) print(details) ``` output: ``` what happending? how to speling it, can you gorrect it? => what happening? how to spelling it, can you correct it? [('happending', 'happening', 5, 15), ('speling', 'spelling', 24, 31), ('gorrect', 'correct', 44, 51)] ``` - 中文简繁互换 支持中文繁体到简体的转换,和简体到繁体的转换。 示例[traditional_simplified_chinese_demo.py](/pycorrector/examples/traditional_simplified_chinese_demo.py) ```python import pycorrector traditional_sentence = '憂郁的臺灣烏龜' simplified_sentence = pycorrector.traditional2simplified(traditional_sentence) print(traditional_sentence, '=>', simplified_sentence) simplified_sentence = '忧郁的台湾乌龟' traditional_sentence = pycorrector.simplified2traditional(simplified_sentence) print(simplified_sentence, '=>', traditional_sentence) ``` output: ``` 憂郁的臺灣烏龜 => 忧郁的台湾乌龟 忧郁的台湾乌龟 => 憂郁的臺灣烏龜 ``` - 命令行模式 支持批量文本纠错 ``` python -m pycorrector -h usage: __main__.py [-h] -o OUTPUT [-n] [-d] input @description: positional arguments: input the input file path, file encode need utf-8. optional arguments: -h, --help show this help message and exit -o OUTPUT, --output OUTPUT the output file path. -n, --no_char disable char detect mode. -d, --detail print detail info ``` case: ``` python -m pycorrector input.txt -o out.txt -n -d ``` > 输入文件:`input.txt`;输出文件:`out.txt `;关闭字粒度纠错;打印详细纠错信息;纠错结果以`\t`间隔

Deep Model Usage

安装依赖

pip install -r requirements-dev.txt

介绍

本项目的初衷之一是比对、共享各种文本纠错方法,抛砖引玉的作用,如果对大家在文本纠错任务上有一点小小的启发就是我莫大的荣幸了。

主要使用了多种深度模型应用于文本纠错任务,分别是前面模型小节介绍的seq2seqtransformerbertmacbertelectra,各模型方法内置于pycorrector文件夹下,有README.md详细指导,各模型可独立运行,相互之间无依赖。

使用方法

各模型均可独立的预处理数据、训练、预测。

基于MacBert预训练模型的纠错

示例macbert_demo.py,详细教程参考README

  1. 模型下载

下载fine-tune后的预训练MacBert MLM模型-密码QKz3,解压后放置于~/.pycorrector/dataset/macbert_models/chinese_finetuned_correction目录下。

macbert_models
└── chinese_finetuned_correction
    ├── config.json
    ├── added_tokens.json
    ├── pytorch_model.bin
    ├── special_tokens_map.json
    ├── tokenizer_config.json
    └── vocab.txt
  1. 纠错
import sys

sys.path.append("..")
from pycorrector.macbert.macbert_corrector import MacBertCorrector

if __name__ == '__main__':
    error_sentences = [
        '真麻烦你了。希望你们好好的跳无',
        '少先队员因该为老人让坐',
        '机七学习是人工智能领遇最能体现智能的一个分知',
        '一只小鱼船浮在平净的河面上',
        '我的家乡是有明的渔米之乡',
    ]

    m = MacBertCorrector()
    for line in error_sentences:
        correct_sent, err = m.macbert_correct(line)
        print("query:{} => {}, err:{}".format(line, correct_sent, err))

output:

query:真麻烦你了。希望你们好好的跳无 => 真麻烦你了。希望你们好好的跳舞, err:[('无', '舞', 14, 15)]
query:少先队员因该为老人让坐 => 少先队员应该为老人让坐, err:[('因', '应', 4, 5)]
query:机七学习是人工智能领遇最能体现智能的一个分知 => 机器学习是人工智能领域最能体现智能的一个分知, err:[('七', '器', 1, 2), ('遇', '域', 10, 11)]
query:一只小鱼船浮在平净的河面上 => 一只小鱼船浮在平净的河面上, err:[]
query:我的家乡是有明的渔米之乡 => 我的家乡是有名的渔米之乡, err:[('明', '名', 6, 7)]
查看Seq2Seq模型 - Seq2Seq模型 [seq2seq](./pycorrector/seq2seq) 模型使用示例: #### 配置 通过修改`config.py`。 #### 数据预处理 ``` cd seq2seq # 数据预处理 python preprocess.py ``` 自动新建文件夹output,在output下生成`train.txt`和`test.txt`文件,以TAB("\t")间隔错误文本和纠正文本,文本以空格切分词,文件内容示例: ``` 希 望 少 吸 烟 。 希 望 烟 民 们 少 吸 烟 。 以 前 , 包 括 中 国 , 我 国 也 是 。 以 前 , 不 仅 中 国 , 我 国 也 是 。 我 现 在 好 得 多 了 。 我 现 在 好 多 了 。 ``` #### 训练 ``` python train.py ``` 设置`config.py`中`arch='convseq2seq'`,训练sighan数据集(2104条样本),200个epoch,单卡P40GPU训练耗时:3分钟。 #### 预测 ``` python infer.py ``` 预测输出效果样例截图: ![result image](/pycorrector/docs/git_image/convseq2seq_ret.png) PS: 1. 如果训练数据太少(不足万条),深度模型拟合不足,会出现预测结果全为`unk`的情况,解决方法:增大训练样本集,使用下方提供的纠错熟语料(nlpcc2018+hsk,130万对句子)测试。 2. 深度模型训练耗时长,有GPU尽量用GPU,加速训练,节省时间。

Dataset

数据集 语料 下载链接 压缩包大小
人民日报2014版语料 人民日报2014版 百度网盘(密码uc11)
飞书(密码cHcu)
383M
NLPCC 2018 GEC官方数据集 NLPCC2018-GEC 官方trainingdata 114M
NLPCC 2018+HSK熟语料 nlpcc2018+hsk+CGED 百度网盘(密码m6fg)
飞书(密码gl9y)
215M
NLPCC 2018+HSK原始语料 HSK+Lang8 百度网盘(密码n31j)
飞书(密码Q9LH)
81M
  1. NLPCC 2018 GEC官方数据集NLPCC2018-GEC, 训练集trainingdata[解压后114.5MB],该数据格式是原始文本,未做切词处理。
  2. 汉语水平考试(HSK)和lang8原始平行语料[HSK+Lang8]百度网盘(密码n31j),该数据集已经切词,可用作数据扩增
  3. 以上语料,再加上CGED16、CGED17、CGED18的数据,经过以字切分,繁体转简体,打乱数据顺序的预处理后,生成用于纠错的熟语料(nlpcc2018+hsk),网盘链接:https://pan.baidu.com/s/1BkDru60nQXaDVLRSr7ktfA 密码:m6fg [130万对句子,215MB]

Custom Language Model

什么是语言模型?-wiki

语言模型对于纠错步骤至关重要,当前默认使用的是从千兆中文文本训练的中文语言模型zh_giga.no_cna_cmn.prune01244.klm(2.8G), 此处也提供人民日报2014版语料训练得到的轻量版语言模型people2014corpus_chars.klm(密码o5e9)

大家可以用中文维基(繁体转简体,pycorrector.utils.text_utils下有此功能)等语料数据训练通用的语言模型,或者也可以用专业领域语料训练更专用的语言模型。更适用的语言模型,对于纠错效果会有比较好的提升。

  1. kenlm语言模型训练工具的使用,请见博客:http://blog.csdn.net/mingzai624/article/details/79560063
  2. 附上训练语料<人民日报2014版熟语料>,包括: 1)标准人工切词及词性数据people2014.tar.gz, 2)未切词文本数据people2014_words.txt, 3)kenlm训练字粒度语言模型文件及其二进制文件people2014corpus_chars.arps/klm, 4)kenlm词粒度语言模型文件及其二进制文件people2014corpus_words.arps/klm。

尊重版权,传播请注明出处。

Todo

Contact

Cite

如果你在研究中使用了pycorrector,请按如下格式引用:

@software{pycorrector,
  author = {Xu Ming},
  title = {pycorrector: Text Error Correction Tool},
  year = {2020},
  url = {https://github.com/shibing624/pycorrector},
}

License

pycorrector 的授权协议为 Apache License 2.0,可免费用做商业用途。请在产品说明中附加pycorrector的链接和授权协议。pycorrector受版权法保护,侵权必究。

Contribute

项目代码还很粗糙,如果大家对代码有所改进,欢迎提交回本项目,在提交之前,注意以下两点:

之后即可提交PR。

Reference