[自然语言处理] 基于pycorrector实现文本纠错
文本纠错(Text Error Correction)技术旨在自动修正输入文本中的拼写、语法、标点符号等错误,以提高文本的准确性、通顺性和规范性。该技术可以通过自然语言处理技术实现,基于上下文和语言规则对文本进行分析和推断,发现其中的错误,并给出正确的替换或修改建议。
pycorrector是一个开源中文文本纠错工具,它支持对中文文本进行音似、形似和语法错误的纠正。此工具是使用Python3进行开发的,并整合了Kenlm、ConvSeq2Seq、BERT、MacBERT、ELECTRA、ERNIE、Transformer等多种模型来实现文本纠错功能。pycorrector官方仓库地址为:pycorrector。pycorrector安装命令如下:
pip install -U pycorrector
本文旨在介绍如何调用pycorrector提供的函数接口来进行文本纠错。事实上,pycorrector官方仓库已经提供了详尽的使用教程,可进一步深入了解pycorrector的使用方法。此外,文章PyCorrector文本纠错工具实践和代码详解也系统性地介绍了pycorrector的使用。
# jupyter notebook环境去除warning
import warnings
warnings.filterwarnings("ignore")
1 pycorrector相关背景
本节一些内容和图片来自:pycorrector源码解读。
应用背景
中文文本纠错任务的应用背景和常见错误类型如下图所示,pycorrector专注于解决"音似、形字、语法、专名错误"等类型的错误。

数据集
在文本纠错任务中,数据集的质量和数量往往比模型本身更为重要。这也是许多实际场景任务所面临的共同问题。因为模型之间的差别并不大,文本纠错模型的精度更多取决于训练数据规模。

技术思路
一般文本纠错任务有两种技术实现方式:基于规则的文本纠错和基于机器学习/深度学习的文本纠错。由于大语言模型效果很好,所以现有文本纠错方法了解即可。
基于规则的中文文本纠错技术思路如下:
- 分词:首先使用分词工具将输入的文本进行分词处理,将句子拆分成一个个词语。
- 错误检测:使用规则匹配的方式,对分词后的文本进行错误检测。常见的错误包括拼写错误、词序错误、词语冗余等。例如,可以使用字典或语料库来匹配常用词汇,如果某个词不在字典或语料库中,则认为它是一个可能的错误。
- 错误纠正:一旦发现错误,可以根据规则进行纠正。纠错的方法包括拼写纠正、词序调整、词语替换等。例如,可以利用编辑距离或拼音近似匹配算法来进行拼写纠正;可以使用语言模型预测概率来判断词序是否正确;可以使用同义词词典来进行词语替换。
基于机器学习/深度学习的文本纠错技术思路如下:
- 基于Sequence-to-Sequence模型:使用编码器-解码器结构的序列到序列模型,将输入的错误文本作为源序列,目标文本(正确文本)作为目标序列进行训练。通过最小化误差来调整模型的参数,实现对错误文本的纠错。
- 基于Transformer模型:Transformer模型是一种注意力机制的深度学习模型,广泛应用于自然语言处理任务中,如机器翻译和文本生成。在文本纠错任务中,可以使用Transformer模型将错误文本转化为正确文本,通过损失函数进行训练和优化。
- 基于语言模型的强化学习方法:使用语言模型来生成候选纠错结果,并通过强化学习算法来评估和选择最佳的纠错建议。这种方法可以通过与外部环境进行交互,不断提升纠错性能。
- 基于预训练模型,如GPT系列模型或BERT模型。其中BERT是一种预训练语言模型,具有良好的上下文理解能力。在文本纠错中,可以使用BERT模型进行编码和解码操作,通过自监督学习来训练模型,使其具备纠正错误文本的能力。
工业解决方案
尽管以GPT为代表的大语言模型在文本纠错方面展现出潜力,但其计算资源要求较高,需要训练数据和强大的计算能力。目前,工业界已有的文本纠错技术仍然具备优势和广泛应用场景。



2 pycorrector使用说明
2.1 基于规则的中文文本纠错
pycorrector中基于规则的中文文本纠错接口默认使用Kenlm模型。具体来说,pycorrector基于Kenlm统计语言模型工具训练了中文NGram语言模型,结合规则方法、混淆集可以快速纠正中文拼写错误,但效果一般。
文本纠错
用于文本纠错的correct函数会从路径~/.pycorrector/datasets/zh_giga.no_cna_cmn.prune01244.klm加载kenlm语言模型文件,如果检测没有该文件, 则模型会自动联网下载。当然也可以手动下载klm模型文件(2.8G)并放置于该位置。
import pycorrector
# include_symbol: 是否包含标点符号,默认为True
# threshold: 纠错阈值,默认为57
corrected_sent, detail = pycorrector.correct("人群穿流不息,少先队员因该为老人让坐!",include_symbol=True,threshold=60)
# corrected_sent: 纠错后的句子
# detail: 纠错信息,[wrong, right, begin_pos, end_pos]
corrected_sent, detail
('人群川流不息,少先队员应该为老人让座!',
[('穿流不息', '川流不息', 2, 6), ('因该', '应该', 11, 13), ('坐', '座', 17, 18)])
错误检测
pycorrector提供detect函数来检测并返回输入文本中可能存在的语言错误和错误类型。
import pycorrector
idx_errors = pycorrector.detect('人群穿流不息,少先队员因该为老人让坐!')
print(idx_errors)
[['穿流不息', 2, 6, 'proper'], ['因该', 11, 13, 'word'], ['坐', 17, 18, 'char']]
成语、专名纠错
pycorrector提供了专门用于对成语和专名进行纠错的函数,如下所示:
from pycorrector.proper_corrector import ProperCorrector
from pycorrector import config
m = ProperCorrector(proper_name_path=config.proper_name_path)
x = [
'这块名表带带相传',
'这块名表代代相传',
'这场比赛我甘败下风',
'这场比赛我甘拜下封',
'早上在拼哆哆上买了点葡桃',
]
for i in x:
print(i, ' -> ', m.proper_correct(i))
这块名表带带相传 -> ('这块名表代代相传', [('带带相传', '代代相传', 4, 8)])
这块名表代代相传 -> ('这块名表代代相传', [])
这场比赛我甘败下风 -> ('这场比赛我甘拜下风', [('甘败下风', '甘拜下风', 5, 9)])
这场比赛我甘拜下封 -> ('这场比赛我甘拜下风', [('甘拜下封', '甘拜下风', 5, 9)])
早上在拼哆哆上买了点葡桃 -> ('早上在拼多多上买了点葡桃', [('拼哆哆', '拼多多', 3, 6)])
自定义混淆集
pycorrector通过加载自定义混淆集,支持用户纠正已知的错误,实际就是字符串替换。
from pycorrector import ConfusionCorrector, Corrector
if __name__ == '__main__':
error_sentences = [
'买iphonex,要多少钱', # 漏召回
'哪里卖苹果吧?请大叔给我让坐', # 漏召回
'共同实际控制人萧华、霍荣铨、张旗康', # 误杀
'上述承诺内容系本人真实意思表示', # 正常
'大家一哄而伞怎么回事', # 成语
]
m = Corrector()
for i in error_sentences:
print(i, ' -> ', m.detect(i), m.correct(i))
print('*' * 42)
# 自定义混淆集
custom_confusion = {'得事': '的事', '天地无垠': '天地无限', '交通先行': '交通限行', '苹果吧': '苹果八', 'iphonex': 'iphoneX', '小明同学': '小茗同学', '萧华': '萧华',
'张旗康': '张旗康', '一哄而伞': '一哄而散', 'happt': 'happen', 'shylock': 'shylock', '份额': '份额', '天俺门': '天安门'}
m = ConfusionCorrector(custom_confusion_path_or_dict=custom_confusion)
for i in error_sentences:
print(i, ' -> ', m.confusion_correct(i))
买iphonex,要多少钱 -> [['钱', 12, 13, 'char']] ('买iphonex,要多少钱', [])
哪里卖苹果吧?请大叔给我让坐 -> [] ('哪里卖苹果吧?请大叔给我让坐', [])
共同实际控制人萧华、霍荣铨、张旗康 -> [['霍荣铨', 10, 13, 'word'], ['张旗康', 14, 17, 'word']] ('共同实际控制人萧华、霍荣铨、张启康', [('张旗康', '张启康', 14, 17)])
上述承诺内容系本人真实意思表示 -> [['系', 6, 7, 'char']] ('上述承诺内容系本人真实意思表示', [])
大家一哄而伞怎么回事 -> [['一哄', 2, 4, 'word'], ['伞', 5, 6, 'char']] ('大家一哄而散怎么回事', [('伞', '散', 5, 6)])
******************************************
买iphonex,要多少钱 -> ('买iphoneX,要多少钱', [['iphonex', 'iphoneX', 1, 8]])
哪里卖苹果吧?请大叔给我让坐 -> ('哪里卖苹果八?请大叔给我让坐', [['苹果吧', '苹果八', 3, 6]])
共同实际控制人萧华、霍荣铨、张旗康 -> ('共同实际控制人萧华、霍荣铨、张旗康', [['萧华', '萧华', 7, 9], ['张旗康', '张旗康', 14, 17]])
上述承诺内容系本人真实意思表示 -> ('上述承诺内容系本人真实意思表示', [])
大家一哄而伞怎么回事 -> ('大家一哄而散怎么回事', [['一哄而伞', '一哄而散', 2, 6]])
自定义语言模型
pycorrector提供了用于加载自定义语言模型的代码,如下所示:
# 自定义模型路径
lm_path = './custom.klm'
model = Corrector(language_model_path=lm_path)
英文拼写纠错
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)
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)]
pycorrect也支持自定义的词频字典设置,以防止误纠错。如下所示,shylock被纠错为shock,可以设置shylock出现频率比shock高来避免纠错。
from pycorrector.en_spell import EnSpell
# # 定义一个字符串变量
sent = "what is your name? shylock?"
# 创建一个EnSpell类的实例对象
spell = EnSpell()
corrected_text, details = spell.correct(sent)
# shylock被纠错为shock
print(sent, '=>', corrected_text, details)
print('-' * 42)
# 定义一个包含词频信息的字典
# 设置shylock出现频次比shock高
my_dict = {'your': 120, 'name': 2, 'is': 1, 'shock': 2, 'shylock': 1, 'what': 1}
# 创建一个EnSpell类的实例对象,并传入自定义词频字典
spell = EnSpell(word_freq_dict=my_dict)
corrected_text, details = spell.correct(sent)
print(sent, '=>', corrected_text, details)
what is your name? shylock? => what is your name? shock? [('shylock', 'shock', 19, 26)]
------------------------------------------
what is your name? shylock? => what is your name? shylock? []
中文简繁互换
pycorrector支持中文简体和繁体的互换,如下所示:
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)
學而時習之,不亦說乎 => 学而时习之,不亦说乎
学而时习之,不亦说乎 => 學而時習之,不亦說乎
2.2 基于深度学习的中文文本纠错
pycorrector提供多个基于深度学习的中文文本纠错模型,一般而言,使用深度学习进行中文文本纠错可以获得比基于规则纠错更好的效果。pycorrector在SIGHAN2015数据集数据集下对各种深度学习模型进行了评测,SIGHAN2015数据集是一个经典公开的用于中文文本纠错任务的数据集,并得出以下结论:
- 中文拼写纠错模型效果最好的是MacBert-CSC,模型名称是shibing624/macbert4csc-base-chinese,huggingface model:shibing624/macbert4csc-base-chinese
- 中文语法纠错模型效果最好的是BART-CSC,模型名称是shibing624/bart4csc-base-chinese,huggingface model:shibing624/bart4csc-base-chinese
- 最具潜力的模型是Mengzi-T5-CSC,模型名称是shibing624/mengzi-t5-base-chinese-correction,huggingface model:shibing624/mengzi-t5-base-chinese-correction,未改变模型结构,仅fine-tune中文纠错数据集,已经在
SIGHAN 2015取得接近SOTA的效果 - 基于ChatGLM-6B的纠错微调模型效果也不错,模型名称是shibing624/chatglm-6b-csc-zh-lora,huggingface model:shibing624/chatglm-6b-csc-zh-lora,大模型不仅能改错还能润色句子,但是模型太大,推理速度慢
在pycorrector中调用MacBert-CSC模型进行文本纠错的代码如下,该代码将自动加载macbert4csc-base-chinese提供的纠错模型。
from pycorrector.macbert.macbert_corrector import MacBertCorrector
from pycorrector import ConfusionCorrector
if __name__ == '__main__':
error_sentences = [
'少先队员因该为老人让坐',
'机七学习是人工智能领遇最能体现智能的一个分知',
]
m = MacBertCorrector()
# add confusion corrector for postprocess
confusion_dict = {"喝小明同学": "喝小茗同学", "老人让坐": "老人让座", "平净": "平静", "分知": "分支"}
cm = ConfusionCorrector(custom_confusion_path_or_dict=confusion_dict)
for line in error_sentences:
correct_sent, err = m.macbert_correct(line)
print("query:{} => {} err:{}".format(line, correct_sent, err))
correct_sent, err = cm.confusion_correct(correct_sent)
if err:
print("added confusion: {} err: {}".format(correct_sent, err))
此外,pycorrector也推荐使用PaddleNLP进行文本纠错。PaddleNLP提供了覆盖包括文本纠错在内的多个产业级NLP预置模型。关于PaddleNLP的安装和使用见其官方仓库:PaddleNLP。
from paddlenlp import Taskflow
corrector = Taskflow("text_correction")
# 单条输入
corrector('遇到逆竟时,我们必须勇于面对,而且要愈挫愈勇。')
[{'source': '遇到逆竟时,我们必须勇于面对,而且要愈挫愈勇。',
'target': '遇到逆境时,我们必须勇于面对,而且要愈挫愈勇。',
'errors': [{'position': 3, 'correction': {'竟': '境'}}]}]
# 批量预测
corrector(['遇到逆竟时,我们必须勇于面对,而且要愈挫愈勇。', '人生就是如此,经过磨练才能让自己更加拙壮,才能使自己更加乐观。'])
[{'source': '遇到逆竟时,我们必须勇于面对,而且要愈挫愈勇。',
'target': '遇到逆境时,我们必须勇于面对,而且要愈挫愈勇。',
'errors': [{'position': 3, 'correction': {'竟': '境'}}]},
{'source': '人生就是如此,经过磨练才能让自己更加拙壮,才能使自己更加乐观。',
'target': '人生就是如此,经过磨炼才能让自己更加茁壮,才能使自己更加乐观。',
'errors': [{'position': 10, 'correction': {'练': '炼'}},
{'position': 18, 'correction': {'拙': '茁'}}]}]
实际上,无论是基于规则的中文文本纠错算法还是其他基于深度学习模型的文本纠错算法,它们的效果都不如深度学习大模型(例如ChatGPT)。即使是PaddleNLP提供的纠错模型,在中文自然语言处理任务中也有相当高的精度,但面对一些简单的纠错案例时,效果也可能不佳。如下所示,“穿流不息”被错误地纠正为“传流不息”。因此,在实际应用时,应该根据具体场景定制相应的模型。如果是工业应用,在算力要求不高的情况下,应该尽可能选择开源大语言模型。
corrector('人群穿流不息,少先队员因该为老人让坐')
[{'source': '人群穿流不息,少先队员因该为老人让坐',
'target': '人群传流不息,少先队员应该为老人让坐',
'errors': [{'position': 2, 'correction': {'穿': '传'}},
{'position': 11, 'correction': {'因': '应'}}]}]
3 参考
[自然语言处理] 基于pycorrector实现文本纠错的更多相关文章
- 文本纠错:提升OCR任务准确率的方法理解
文本纠错:提升OCR任务准确率的方法理解 摘要:错字率是OCR任务中的重要指标,文本纠错需要机器具备人类水平相当的语言理解能力.随着人工智能应用的成熟,越来越多的纠错方法被提出. 近年来深度学习在O ...
- 从编辑距离、BK树到文本纠错
搜索引擎里有一个很重要的话题,就是文本纠错,主要有两种做法,一是从词典纠错,一是分析用户搜索日志,今天我们探讨使用基于词典的方式纠错,核心思想就是基于编辑距离,使用BK树.下面我们来逐一探讨: 编辑距 ...
- 【新词发现】基于SNS的文本数据挖掘、短语挖掘
互联网时代的社会语言学:基于SNS的文本数据挖掘 python实现 https://github.com/jtyoui/Jtyoui/tree/master/jtyoui/word 这是一个无监督训 ...
- tensorflow实现基于LSTM的文本分类方法
tensorflow实现基于LSTM的文本分类方法 作者:u010223750 引言 学习一段时间的tensor flow之后,想找个项目试试手,然后想起了之前在看Theano教程中的一个文本分类的实 ...
- 一文详解如何用 TensorFlow 实现基于 LSTM 的文本分类(附源码)
雷锋网按:本文作者陆池,原文载于作者个人博客,雷锋网已获授权. 引言 学习一段时间的tensor flow之后,想找个项目试试手,然后想起了之前在看Theano教程中的一个文本分类的实例,这个星期就用 ...
- 基于 Spark 的文本情感分析
转载自:https://www.ibm.com/developerworks/cn/cognitive/library/cc-1606-spark-seniment-analysis/index.ht ...
- (4.2)基于LingPipe的文本基本极性分析【demo】
酒店评论情感分析系统(四)—— 基于LingPipe的文本基本极性分析[demo] (Positive (favorable) vs. Negative (unfavorable)) 这篇文章为Lin ...
- 调用百度API进行文本纠错
毕设做的是文本纠错方面,然后今天进组见研究生导师 .老师对我做的东西蛮感兴趣.然后介绍自己现在做的一些项目,其中有个模块需要有用到文本纠错功能. 要求1:有多人同时在线编辑文档,然后文档功能有类似Wo ...
- NLP之基于TextCNN的文本情感分类
TextCNN @ 目录 TextCNN 1.理论 1.1 基础概念 最大汇聚(池化)层: 1.2 textCNN模型结构 2.实验 2.1 实验步骤 2.2 算法模型 1.理论 1.1 基础概念 在 ...
- 互联网时代的社会语言学:基于SNS的文本数据挖掘
今年上半年,我在人人网实习了一段时间,期间得到了很多宝贵的数据,并做了一些还算有意义的事情,在这里和大家一块儿分享.感谢人人网提供的数据 与工作环境,感谢赵继承博士.詹卫东老师的支持和建议.在这项工作 ...
随机推荐
- Apikit SaaS 10.9.0 版本更新: 接口测试支持通过 URL 请求大型文件,支持导出为 Postman 格式文件
Hi,大家好! Eolink Apikit 即将在 2023年 6月 8日晚 18:00 开始更新 10.9.0 版本.本次版本更新主要是对多个应用级资源合并,并基于此简化付费套餐和降低费率. 本次应 ...
- JUC同步锁原理源码解析三----CountDownLatch、CyclicBarrier
JUC同步锁原理源码解析三----CountDownLatch.CyclicBarrier CountDownLatch.CyclicBarrier的来源 1.CountDownLatch的来源 A ...
- GPT3的技术突破:实现更精准的语义分析
目录 2. 技术原理及概念 3. 实现步骤与流程 4. 应用示例与代码实现讲解 5. 优化与改进 6. 结论与展望 7. 附录:常见问题与解答 GPT-3技术突破:实现更精准的语义分析 近年来,人工智 ...
- Maven资源大于配置问题
资源大于配置问题 <!--pom.xml中在build中配置resources,来防止我们资源导出失败的问题--> <build> <resources> < ...
- 将 -Xms 参数设置和-Xmx 参数的相等,对比 -Xms参数 设置为-Xmx 参数的一半,有哪些优势?
将 -Xms 参数设置为与 -Xmx 参数相等,相比于将 -Xms 参数设置为 -Xmx 参数的一半,具有以下优势: 1. 程序启动时间更短 当将 -Xms 参数设置为与 -Xmx 参数相等时,JVM ...
- 如何使用libswscale库将YUV420P格式的图像序列转换为RGB24格式输出?
一.视频格式转换初始化 将视频中的图像帧按照一定比例缩放或指定宽高进行放大和缩小是视频编辑中最为常见的操作之一,这里我们将1920x1080的yuv图像序列转换成640x480的rgb图像序列,并输出 ...
- P7561[JOISC 2021 Day2] 道路の建設案 (Road Construction) 题解
P7561[JOISC 2021 Day2] 道路の建設案 (Road Construction) 题解 题目描述 JOI 国是一个 \(x\times y\) 的二维平面,王国里有 \(n\) 个城 ...
- 简约版八股文(day1)
Java基础 面向对象的三大基本特征 封装:将一些数据和对这些数据的操作封装在一起,形成一个独立的实体.隐藏内部的操作细节,并向外提供一些接口,来暴露对象的功能. 继承:继承是指子类继承父类,子类获得 ...
- 数据安全没保证?GaussDB(for Redis)为你保驾护航
摘要:GaussDB (for Redis)通过账号管理.权限隔离.高危命令禁删/重命名.安全IP免密登录.实例回收站等企业级特性,保障用户数据库数据和信息安全. 本文分享自华为云社区<数据安全 ...
- 使用Hexo搭建个人博客网站
参考CSDN上的博客.特此感谢wsmrzx.