引言

在上一个项目ERNIE for CSC:【的、地、得】傻傻分不清?救星来了!中,我们介绍了如何从0开始训练一个文本纠错模型。

文章的最后,提到了PaddleNLP的Taskflow。本文就基于文本纠错的Taskflow,展开一个趣味项目:如何让AI做改错别字的作业。

错别字纠正历来是语文考试的“保留曲目”,想必下面这种形式的习题大家再熟悉不过了吧?

本文研究的就是如何基于PaddleNLP的Taskflow,实现AI自动答题,并检测下它的“语文水平”。

PaddleNLP Taskflow介绍

paddlenlp.Taskflow是旨在提供开箱即用的NLP预置任务,覆盖自然语言理解与自然语言生成两大核心应用,在中文场景上提供产业级的效果与极致的预测性能。

任务清单

当前paddlenlp.Taskflow支持以下任务,本文用到的文本纠错是其中一种。

自然语言理解任务 自然语言生成任务
中文分词 生成式问答
词性标注 智能写诗
命名实体识别 文本翻译(TODO)
文本纠错 开放域对话(TODO)
句法分析 自动对联(TODO)
情感分析

随着版本迭代paddlenlp.Taskflow会持续开放更多的应用场景。

用法

接着我们来看看它的用法。

from paddlenlp import Taskflowcorrector = Taskflow("text_correction")
corrector('遇到逆竟时,我们必须勇于面对,而且要愈挫愈勇,这样我们才能朝著成功之路前进。')
>>> [{'source': '遇到逆竟时,我们必须勇于面对,而且要愈挫愈勇,这样我们才能朝著成功之路前进。', 'target': '遇到逆境时,我们必须勇于面对,而且要愈挫愈勇,这样我们才能朝著成功之路前进。', 'errors': [{'position': 3, 'correction': {'竟': '境'}}]}]corrector(['遇到逆竟时,我们必须勇于面对,而且要愈挫愈勇,这样我们才能朝著成功之路前进。','人生就是如此,经过磨练才能让自己更加拙壮,才能使自己更加乐观。'])
>>> [{'source': '遇到逆竟时,我们必须勇于面对,而且要愈挫愈勇,这样我们才能朝著成功之路前进。', 'target': '遇到逆境时,我们必须勇于面对,而且要愈挫愈勇,这样我们才能朝著成功之路前进。', 'errors': [{'position': 3, 'correction': {'竟': '境'}}]}, {'source': '人生就是如此,经过磨练才能让自己更加拙壮,才能使自己更加乐观。', 'target': '人生就是如此,经过磨练才能让自己更加茁壮,才能使自己更加乐观。', 'errors': [{'position': 18, 'correction': {'拙': '茁'}}]}]

如果看到这个示例还存在疑问,不妨想想PaddleHub,其实两者非常类似,对吧?其实就是Paddle训练好了模型,提供非常简单的方式供用户调用。

至于……为什么有了PaddleHub,又造了paddlenlp.Taskflow这个轮子……我也不知道

作为用户,关注它们好不好用就行了吧

环境准备

# 本项目paddlenlp的版本要升到2.1
!pip install -U paddlenlp
!pip install pypinyin --upgrade

错别字检测与结果封装

from paddlenlp import Taskflow
text_correction = Taskflow("text_correction")
text = '若成长是一篇著作,那么烦恼便是藏在段落深处的措别字;如果成长是一张白纸,那么烦恼便是附在背面的一个瑕疵'
result = text_correction(text)
[2021-11-04 23:43:35,039] [    INFO] - Already cached /home/aistudio/.paddlenlp/models/ernie-1.0/vocab.txt
# 查看检测到错字的位置
result[0]['errors'][0]['position']
# 查看更正信息
result[0]['errors'][0]['correction']
{'措': '错'}
# 做个后处理,拼接纠错效果
postprocess= text[:result[0]['errors'][0]['position']] + str(result[0]['errors'][0]['correction']) + text[result[0]['errors'][0]['position']+1:]
text[:result[0]['errors'][0]['position']] + list(result[0]['errors'][0]['correction'].keys())[0] + '(' + list(result[0]['errors'][0]['correction'].values())[0] + ')' + text[result[0]['errors'][0]['position']+1:]
'若成长是一篇著作,那么烦恼便是藏在段落深处的措(错)别字;如果成长是一张白纸,那么烦恼便是附在背面的一个瑕疵'

在上面的操作中,我们通过比较“暴力”的封装,对测试语句进行了纠错,组合成类似于答题需要的效果。

但是,很显然这个过程还可用优化一番,比如说,不是通过“暴力”拼接括号,而是通过替换的方式,至少看起来会比较合理些;同时,这种做法也为同时处理存在多个错别字的句子,埋下了伏笔。

# 字符串替换模型,将字符串中,指定索引位的文字替换成另一个
def replace_char(string, char, index):string = list(string)string[index] = charreturn ''.join(string)
replace_char(text, (list(result[0]['errors'][0]['correction'].keys())[0] + '(' + list(result[0]['errors'][0]['correction'].values())[0] + ')'), result[0]['errors'][0]['position'])
'若成长是一篇著作,那么烦恼便是藏在段落深处的措(错)别字;如果成长是一张白纸,那么烦恼便是附在背面的一个瑕疵'

中文断句的处理

前文我们实现的错别字更正,只能更正一个句子。如果语句长度太长,我们就会看到模型罢工了……

很显然,受限于当前算力和模型结果,让NLP处理太长的语句,也没什么太大的意义。

因此,如果我们要让这个文本纠错模型,处理一整个大的段落,就需要对其进行中文分句。

import re
def cut_sent(para):para = re.sub('([。!?\?])([^”’])', r"\1\n\2", para)  # 单字符断句符para = re.sub('(\.{6})([^”’])', r"\1\n\2", para)  # 英文省略号para = re.sub('(\…{2})([^”’])', r"\1\n\2", para)  # 中文省略号para = re.sub('([。!?\?][”’])([^,。!?\?])', r'\1\n\2', para)# 如果双引号前有终止符,那么双引号才是句子的终点,把分句符\n放到双引号后,注意前面的几句都小心保留了双引号para = para.rstrip()  # 段尾如果有多余的\n就去掉它# 很多规则中会考虑分号;,但是这里我把它忽略不计,破折号、英文双引号等同样忽略,需要的再做些简单调整即可。return para.split("\n")

实现段落分句可以有很多形式——极端点的,参考分词训练个模型也可以。不过本文使用的是基于正则表达式的方法,显然效率高了不少,在大部分情况下也比较够用。

参考链接:
用python进行精细中文分句(基于正则表达式)

接下来,我们用下面这道精心设计的段落,检测下文本纠错模型逐句检测改正的效果。

para = "初一那年的一个周末,劳禄的母亲第一次来到穿流不息的县城,到学校来看我。见到母亲,我迫不急待地说,“妈,带了什么好吃的没有?” 母亲兴奋地塞给我一盒包装得美仑美奂的营养液。我惊讶地问母亲:“咱家那么困难,买它干什么?”母亲笑容可鞠地说:“顾名思意,营养液嘛,补脑子,喝了它准能考上大学。”我摸挲着那盒营养液,嘟囔着:“那么贵,大慨又借钱了吧?” 母亲一笑:“没有!是用手镯换的”。那知漂亮得银手镯是外祖母传给母亲的,是贫穷的母亲最贵重得东西了,多年来一直舍不得戴,压在箱底。"
sents = cut_sent(para)
print("\n".join(sents))
results = text_correction(cut_sent(para))
for idx, item in enumerate(sents):    res = text_correction(item)if (len(res[0]['errors'])) > 0:for i, error in enumerate(res[0]['errors']):if i == 0:item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), res[0]['errors'][i]['position'])else:# 如果句子中有多处错字,那么每替换前面一个字,后面的错字索引往后移动3位:即括号+字=3位p = res[0]['errors'][i]['position'] + i * 3item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), p)print(item)else:print(item)
初一那年的一个周末,劳禄的母亲第一次来到穿流不息的县城,到学校来看我。
见到母亲,我迫不急(及)待地说,“妈,带了什么好吃的没有?”母亲兴奋地塞给我一盒包装得仑(轮)仑美奂的营养液。
我惊讶地问母亲:“咱家那么困难,买它干什么?”
母亲笑容可鞠地说:“顾名思意,营养液嘛,补脑子,喝了它准能考上大学。”
我摸挲(叩)着那盒营养液,嘟囔着:“那么贵,大慨又借钱了吧?”母亲一笑:“没有!是用手镯换的”。
那知(只)漂亮得(的)银手镯是外祖母传给母亲的,是贫穷的母亲最贵重得(的)东西了,多年来一直舍不得戴,压在箱底。

就这样,一个AI错别字检测答题器基本诞生了!

其实,这个段落中存在很多个错别字,使用paddlenlp.Taskflow只找到了其中一部分,如果去考试,很可能挂科啊。

因此,如果是在工业场景,需要在预训练模型的基础上,更加丰富数据集,以获得更好的效果。本文稍后会给出一些补充数据集的思路。

Word文档纠错

接下来,我们继续丰富在不同场景下的paddlenlp.Taskflow文本纠错实现。word文档是我们工作中非常常用的一种形式,为省去一点复制粘贴的时间,现在我们研究下如何直接进行整个word文档的智能纠错

我们知道,虽然word文档自带了语法识别功能,但显然也不是完美的……比如下面的例子:
某点小说错别字盘点(一)

这里面大部分的错字问题都逃过了word的语法识别——如果一早就能识别到,作者可能码字的时候早就改过来了……

那么,我们就来看看,paddlenlp.Taskflow内置模型对于网络小说的错别字识别效果如何?同最后,我们会把检测结果保存到一个新的word文档中。

# 安装依赖库
!pip install python-docx
from docx import Document
from docx.shared import Inches
def get_paragraphs_text(path):"""获取所有段落的文本:param path: word路径:return: list类型,如:['Test', 'hello world', ...]"""document = Document(path) # 提取正文文本paragraphs_text = ""for paragraph in document.paragraphs:# 拼接一个list,包括段落的结构和内容paragraphs_text += paragraph.text + "\n"return paragraphs_text
text = get_paragraphs_text('csc-qd.docx')
print("\n".join(cut_sent(text)))
csc_result = text_correction(cut_sent(text))
for idx, item in enumerate(cut_sent(text)):if item is not '': res = text_correction(item)if (len(res[0]['errors'])) > 0:for i, error in enumerate(res[0]['errors']):if i == 0:item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), res[0]['errors'][i]['position'])else:p = res[0]['errors'][i]['position'] + i * 3item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), p)print(item)else:print(item)
终于领着一家大小浩浩荡荡的(地)从苍(沧)山里杀了出来
只是那初春的风儿惹的(得)众女满脸陶醉
照的(得)那些云朵丝丝发光,看上去十分震撼
只听得见前面的马蹄声和马儿打响鼻地(的)声音
一个个活的挺滋润
然后又去靖王府拜见那位相熟地(的)王爷
了了这两椿来往
所以等范(反)闲入太学就职地时候
这位以十七稚龄,便官至五品地朝中大红人
这些学生们的隔膜感渐渐退祛(去)
但是他地诗名毕竟早已流传在外
也曾随着上司四处查看举子入京后地(的)状况
想到五竹叔在澹(澳)州讲过地(的)故事
既然不是市(重)恩之举
范闲(雅)略略一惊,清亮的眸子里马上回(恢)复了平静
一丝欣慰之外,更多是的对范闲(畴)似乎安于仕途,而产生某种放心。
后几日,首先领着婉儿回了相府。
“查自然是要查的,但不是你这般莽撞的(地)查下去,”李长寿道
敖乙很轻松的就被转移了注意力。
李长寿此刻也是听的(得)颇为感慨。
两条灵鱼,姜思儿吃的最是欢快
敖乙与姜思儿依依不舍的告别。
李长寿带着灵娥对守门仙人做了个道揖
李长寿淡定的(地)点点头
海神教主庙难得在白天清冷(冷清)了一次
或许是因为这些人被朝廷压榨的(得)太狠
我很担心老卢会不顾一切的继续朝建奴(女)发起进攻。
我不认为那些带着大军去了河南的宦(赛)官会好心的(地)把自己的弹药分给老卢。
你说,他怎么就得罪了杨嗣昌,高起(启)潜这些恶人的?
洪承畴悠悠的(地)道:
老老实实的做槛(地)车养足精神
不,我尽心竭力的(地)挽救这棵枯树,直到枯树寿终正寝。
钱多多翘着脚躺在自己的床上,大脚趾上还挂着一只鞋子不停的晃啊晃的,却怎么都不愿意从脚上掉下里(礼)。
何常氏忧心忡忡的看着钱多多道:
何常氏无奈的走到门口
司离人转头无语的撇了李神坛一眼
毕竟这种清理师门的戏码,就应该打的(得)特别激烈
这人惊恐的一屁股坐在地上,还手忙脚乱的(地)往后退去。
所有人超(抄)那边看去
李神坛无奈的低头看了一眼
罗岚慢慢的(地)向后退去
天地间浮现出一条又一条大道秩链,它们在嘎嘣嘎嘣的断裂
那位无上生灵咳出一口血,霍的仰头望去。
不让让那离去的真身观照此世!
一定会不顾一切的(地)回来
又像是不可抹名状的生物被磨灭后的碎屑!

应该说,paddlenlp.Taskflow的文本纠错模型现在在【的、地、得】区分上有一定造诣——大概是数据集的关系。

虽然检错纠错准确性效果还是有待提高,但看起来比回答精心设计的考题时好了不少?

new_document = Document()
for idx, item in enumerate(cut_sent(text)):if item is not '': res = text_correction(item)if (len(res[0]['errors'])) > 0:for i, error in enumerate(res[0]['errors']):if i == 0:item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), res[0]['errors'][i]['position'])else:p = res[0]['errors'][i]['position'] + i * 3item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), p)new_document.add_paragraph(item)else:new_document.add_paragraph(item)
# 结果保存到新文档
new_document.save('csc-result.docx')

PDF作业答题

我们再让AI来做道题,这次面对的文本格式是PDF。

!pip install pdfplumber
import pdfplumber
import pandas as pdwith pdfplumber.open("12345.pdf") as pdf:page = pdf.pages[0]   # 第一页的信息text = page.extract_text()print(text)
基础知识·汉字
6、下面的句子中没有错别字的是( )。
A.书藉是人类进步的阶梯。
B.老师经常利用课余时间哺导我们学习。
C.初中学习生活即将结束,同学们都格外珍惜这段时光。
D.梦园世界杯,中国队从西安起飞。
for idx, item in enumerate(cut_sent(text)):if item is not '': res = text_correction(item)if (len(res[0]['errors'])) > 0:for i, error in enumerate(res[0]['errors']):if i == 0:item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), res[0]['errors'][i]['position'])else:p = res[0]['errors'][i]['position'] + i * 3item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), p)print(item)else:print(item)
基础知识·汉字
6、下面的句子中没有错别字的是( )。
A.书藉(戒)是人类进步的阶梯。
B.老师经常利用课余时间哺(陪)导我们学习。
C.初中学习生活即将结束,同学们都格外珍惜这段时光。
D.梦园(圆)世界杯,中国队从西安起飞。

在A选项中,其实模型已经定位到了错别字,只不过改得有点离谱……总体来说,这题虽然答得磕磕碰碰,好歹AI是把正确答案选出来了。不过,处理PDF时,换行问题还是比较让人头疼的,比如同一个题目,如果C选项换行了并且没有处理好,答题结果就变了。

PDF换行问题

with pdfplumber.open("14540300364943.pdf") as pdf:page = pdf.pages[0]   # 第一页的信息text = page.extract_text()print(text)
基础知识·汉字
6、下面的句子中没有错别字的一项是( )。
A.书藉是人类进步的阶梯。
B.老师经常利用课余时间哺导我们学习。
C.初中学习生活即将结束,同学们都格外珍惜这
段时光。
D.梦园世界杯,中国队从西安起飞。
for idx, item in enumerate(cut_sent(text)):if item is not '': res = text_correction(item)if (len(res[0]['errors'])) > 0:for i, error in enumerate(res[0]['errors']):if i == 0:item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), res[0]['errors'][i]['position'])else:p = res[0]['errors'][i]['position'] + i * 3item = replace_char(item, (list(res[0]['errors'][i]['correction'].keys())[0] + '(' + list(res[0]['errors'][i]['correction'].values())[0] + ')'), p)print(item)else:print(item)else:print(item)
基础知识·汉字
6、下面的句子中没有错别字的一项(像)是( )。
A.书藉(戒)是人类进步的阶梯。
B.老师经常利用课余时间哺(陪)导我们学习。
C.初中学习生活即将结束,同学们都格外珍惜这
段(短)时光。
D.梦园(圆)世界杯,中国队从西安起飞。

因为换行后的语句直接被送入模型预测,显然发生了误解。

小结与思考

paddlenlp.Taskflow前面做的这些题目看,如果直接参加错别字检测考试,估计也就拿个50-60分,显然不太合格。

不过,众所周知,深度学习模型是数据“喂”出来的,相信该模型要是“见过”《五年模拟三年高考》《黄冈密卷》等等等,跑出来成绩应该能更上一层楼吧?

这里给出补充数据集的几个思路:

  • 百度文档中有关【错别字专项】的全系列
  • 《咬文嚼字》整理出的最常见错别字
  • 更多为中文文本纠错任务自动生成的数据

数据集的标注方式也有多种,比如sgml格式数据可以这样标注:

考虑到语文考试内容就那些,个人感觉,如果补充了针对性数据集,让AI又好又快地做起作业来还是比较有希望的。

让AI做作业:基于PaddleNLP-Taskflow的错别字单项测试相关推荐

  1. AI做题水平已超过CS博士?

    高数考不好,不知道是多少人的噩梦. 如果说你高数考得还不如AI好,是不是就更难以接受了? 没错,来自OpenAI的Codex已经在MIT的7门高数课程题目中正确率达到81.1%,妥妥的MIT本科生水平 ...

  2. AI做题家卷疯了!高数考试正确率81%,竞赛题成绩超过计算机博士

    梦晨 丰色 发自 凹非寺 量子位 | 公众号 QbitAI 高数考不好,不知道是多少人的噩梦. 如果说你高数考得还不如AI好,是不是就更难以接受了? 没错,来自OpenAI的Codex已经在MIT的7 ...

  3. 必做作业三:基于墨刀的原型设计——词典APP

    必做作业三:基于墨刀的原型设计--词典APP 运行环境:IOS系统 作品运行地址:https://modao.cc/app/JmnRng02vm8mJDB1NmdswodOndgMHwJ 注:使用ch ...

  4. 基于PaddleNLP的中文对话文本匹配

    ★★★ 本文源自AI Studio社区精品项目,[点击此处]查看更多精品内容 >>> 基于PaddleNLP的中文对话文本匹配 一.赛题解析 1.1 赛题背景 文本匹配任务在自然语言 ...

  5. AI视觉组基于ESP32的裁判系统第一版本设计要求

    简 介: 面对第十六届全国大学生智能车竞赛中新增加的一些组别的要求,比如室内AI组,对于车模任务增加的检测任务,设计了基于ESP32为核心的比赛系统.本文给出了对于比赛系统功能的要求. 关键词: 比赛 ...

  6. 吴恩达深度学习课程deeplearning.ai课程作业:Class 4 Week 4 Art Generation with Neural Style Transfer

    吴恩达deeplearning.ai课程作业,自己写的答案. 补充说明: 1. 评论中总有人问为什么直接复制这些notebook运行不了?请不要直接复制粘贴,不可能运行通过的,这个只是notebook ...

  7. 吴恩达深度学习课程deeplearning.ai课程作业:Class 4 Week 4 Face Recognition for the Happy House

    吴恩达deeplearning.ai课程作业,自己写的答案. 补充说明: 1. 评论中总有人问为什么直接复制这些notebook运行不了?请不要直接复制粘贴,不可能运行通过的,这个只是notebook ...

  8. 吴恩达深度学习课程deeplearning.ai课程作业:Class 4 Week 3 Car detection

    吴恩达deeplearning.ai课程作业,自己写的答案. 补充说明: 1. 评论中总有人问为什么直接复制这些notebook运行不了?请不要直接复制粘贴,不可能运行通过的,这个只是notebook ...

  9. 吴恩达深度学习课程deeplearning.ai课程作业:Class 4 Week 2 Residual Networks

    吴恩达deeplearning.ai课程作业,自己写的答案. 补充说明: 1. 评论中总有人问为什么直接复制这些notebook运行不了?请不要直接复制粘贴,不可能运行通过的,这个只是notebook ...

最新文章

  1. 工作5年才有自己博客...汗...
  2. 7-9 用天平找小球 (C语言)
  3. LeetCode Palindrome Linked List
  4. 第二十八期:Java线程池的四种用法与使用场景
  5. 服务器系统日志6008,DELL服务器宕机事件6008
  6. STM32示波器 信号发生器
  7. c语言 格式转换函数,C语言中的格式转换函数.doc
  8. 四叶草关闭啰嗦模式_利用OCC配置器关闭开机跑代码(啰嗦模式)教程
  9. mp3转换html5,五个免费在线mp3音频音乐编辑转换网站,实用的音频编辑软件
  10. 硬件_1bit为什么等于6db
  11. 推荐系统常用数据集介绍
  12. 预先下载的keras库中神经网络模型指定存放路径及如何上传的问题
  13. 亚马逊站外引流如何做?解析厨电大卖的高曝光秘诀
  14. window系统node彻底卸载
  15. tableau连接不上oracle,Oracle
  16. 计算机应用word优质课,全国“XX杯”说课大赛计算机应用基础类优秀作品:Word图文混排上课课件.ppt...
  17. Android 游戏设计教程:游戏元素和工具
  18. Android View截图
  19. Android 锁定屏幕方向 横向或竖向 支持Android10
  20. linux多系统引导管理,Linux 多重引导MBR与系统引导管理器GRUB.docx

热门文章

  1. c++ mupdf 提取pdf文件里面图片
  2. Excel只删除开头和末尾空格,中间不管的2种操作
  3. 关于spacing和重采样、降采样的理解
  4. Linux发行版幽灵漏洞的backport
  5. 有理样条曲线学习笔记(一)
  6. 机器人总动员拟人_《机器人总动员》从三个角度解析这部电影带给我们的思考与感动...
  7. PLC协议宏通信功能介绍
  8. 电子体温计为什么会说不如水银准,分析了一下,这个锅它不背!!!
  9. QT操作Word汇总
  10. 首个智能制造领域5G专网建成:广东联通+格力+华为共同打造!