让AI做作业:基于PaddleNLP-Taskflow的错别字单项测试
引言
在上一个项目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的错别字单项测试相关推荐
- AI做题水平已超过CS博士?
高数考不好,不知道是多少人的噩梦. 如果说你高数考得还不如AI好,是不是就更难以接受了? 没错,来自OpenAI的Codex已经在MIT的7门高数课程题目中正确率达到81.1%,妥妥的MIT本科生水平 ...
- AI做题家卷疯了!高数考试正确率81%,竞赛题成绩超过计算机博士
梦晨 丰色 发自 凹非寺 量子位 | 公众号 QbitAI 高数考不好,不知道是多少人的噩梦. 如果说你高数考得还不如AI好,是不是就更难以接受了? 没错,来自OpenAI的Codex已经在MIT的7 ...
- 必做作业三:基于墨刀的原型设计——词典APP
必做作业三:基于墨刀的原型设计--词典APP 运行环境:IOS系统 作品运行地址:https://modao.cc/app/JmnRng02vm8mJDB1NmdswodOndgMHwJ 注:使用ch ...
- 基于PaddleNLP的中文对话文本匹配
★★★ 本文源自AI Studio社区精品项目,[点击此处]查看更多精品内容 >>> 基于PaddleNLP的中文对话文本匹配 一.赛题解析 1.1 赛题背景 文本匹配任务在自然语言 ...
- AI视觉组基于ESP32的裁判系统第一版本设计要求
简 介: 面对第十六届全国大学生智能车竞赛中新增加的一些组别的要求,比如室内AI组,对于车模任务增加的检测任务,设计了基于ESP32为核心的比赛系统.本文给出了对于比赛系统功能的要求. 关键词: 比赛 ...
- 吴恩达深度学习课程deeplearning.ai课程作业:Class 4 Week 4 Art Generation with Neural Style Transfer
吴恩达deeplearning.ai课程作业,自己写的答案. 补充说明: 1. 评论中总有人问为什么直接复制这些notebook运行不了?请不要直接复制粘贴,不可能运行通过的,这个只是notebook ...
- 吴恩达深度学习课程deeplearning.ai课程作业:Class 4 Week 4 Face Recognition for the Happy House
吴恩达deeplearning.ai课程作业,自己写的答案. 补充说明: 1. 评论中总有人问为什么直接复制这些notebook运行不了?请不要直接复制粘贴,不可能运行通过的,这个只是notebook ...
- 吴恩达深度学习课程deeplearning.ai课程作业:Class 4 Week 3 Car detection
吴恩达deeplearning.ai课程作业,自己写的答案. 补充说明: 1. 评论中总有人问为什么直接复制这些notebook运行不了?请不要直接复制粘贴,不可能运行通过的,这个只是notebook ...
- 吴恩达深度学习课程deeplearning.ai课程作业:Class 4 Week 2 Residual Networks
吴恩达deeplearning.ai课程作业,自己写的答案. 补充说明: 1. 评论中总有人问为什么直接复制这些notebook运行不了?请不要直接复制粘贴,不可能运行通过的,这个只是notebook ...
最新文章
- 工作5年才有自己博客...汗...
- 7-9 用天平找小球 (C语言)
- LeetCode Palindrome Linked List
- 第二十八期:Java线程池的四种用法与使用场景
- 服务器系统日志6008,DELL服务器宕机事件6008
- STM32示波器 信号发生器
- c语言 格式转换函数,C语言中的格式转换函数.doc
- 四叶草关闭啰嗦模式_利用OCC配置器关闭开机跑代码(啰嗦模式)教程
- mp3转换html5,五个免费在线mp3音频音乐编辑转换网站,实用的音频编辑软件
- 硬件_1bit为什么等于6db
- 推荐系统常用数据集介绍
- 预先下载的keras库中神经网络模型指定存放路径及如何上传的问题
- 亚马逊站外引流如何做?解析厨电大卖的高曝光秘诀
- window系统node彻底卸载
- tableau连接不上oracle,Oracle
- 计算机应用word优质课,全国“XX杯”说课大赛计算机应用基础类优秀作品:Word图文混排上课课件.ppt...
- Android 游戏设计教程:游戏元素和工具
- Android View截图
- Android 锁定屏幕方向 横向或竖向 支持Android10
- linux多系统引导管理,Linux 多重引导MBR与系统引导管理器GRUB.docx