引言
自然语言生成任务(Natural Language Generation)是自然语言处理领域内的一个重要研究方向,指的是计算机通过模型或算法,从文本、语音等各种形式的输入中生成自然语言文本输出的过程。
我们知道,任何知识都能被描述为文本或者说语言,从而先人的智慧才被记录在书卷上代代相传。因此,绝大多数的自然语言处理任务都可以描述为自然语言生成任务,甚至是文本生成任务,将文本作为输入并将新的文本作为输出,这也是近两年大火的T5模型(Text-to-Text Transfer Transformer)的初衷。举例来说,文本分类任务可以理解为输出类别名,如猫/狗、是/否;文本纠错任务可以理解为输入有错误的文本并理解,输出正确的文本描述;智能问答可以理解为根据背景知识及问句进行推理,输出相应的回答......
可以说,文本生成类任务的应用相当之广,本篇将介绍一些常见的文本生成任务,其中也包含一些曾经并不属于文本生成类任务,但如今也能使用NLG技术进行解决的任务。
文本摘要任务
什么是文本摘要
文本摘要任务指的是用精炼的文本来概括整篇文章的大意,使得用户能够通过阅读摘要来大致了解文章的主要内容。
常见的文本摘要技术
从实现手法来说,文本摘要任务主要分为以下三种:
- 抽取式摘要:从原文档中提取现成的句子作为摘要句。
- 压缩式摘要:对原文档的冗余信息进行过滤,压缩文本作为摘要。
- 生成式摘要:基于NLG技术,根据源文档内容,由算法模型自己生成自然语言描述。
以下是一个基于mT5模型(T5模型的多语言版)的文本摘要样例。
python
import re
import torch
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
# 载入模型
tokenizer = AutoTokenizer.from_pretrained("csebuetnlp/mT5_multilingual_XLSum")
model = AutoModelForSeq2SeqLM.from_pretrained("csebuetnlp/mT5_multilingual_XLSum")
WHITESPACE_HANDLER = lambda k: re.sub('\s+', ' ', re.sub('\n+', ' ', k.strip()))
text = """自动信任协商主要解决跨安全域的信任建立问题,使陌生实体通过反复的、双向的访问控制策略和数字证书的相互披露而逐步建立信任关系。由于信任建立的方式独特和应用环境复杂,自动信任协商面临多方面的安全威胁,针对协商的攻击大多超出常规防范措施所保护的范围,因此有必要对自动信任协商中的攻击手段进行专门分析。按攻击特点对自动信任协商中存在的各种攻击方式进行分类,并介绍了相应的防御措施,总结了当前研究工作的不足,对未来的研究进行了展望"""
text = WHITESPACE_HANDLER(text)
input_ids = tokenizer([text], return_tensors="pt", padding="max_length", truncation=True, max_length=512)["input_ids"]
# 生成结果文本
output_ids = model.generate(input_ids=input_ids, max_length=84, no_repeat_ngram_size=2, num_beams=4)[0]
output_text = tokenizer.decode(output_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)
print("原始文本: ", text)
print("摘要文本: ", output_text)
运行结果
原始文本: 自动信任协商主要解决跨安全域的信任建立问题,使陌生实体通过反复的、双向的访问控制策略和数字证书的相互披露而逐步建立信任关系。由于信任建立的方式独特和应用环境复杂,自动信任协商面临多方面的安全威胁,针对协商的攻击大多超出常规防范措施所保护的范围,因此有必要对自动信任协商中的攻击手段进行专门分析。按攻击特点对自动信任协商中存在的各种攻击方式进行分类,并介绍了相应的防御措施,总结了当前研究工作的不足,对未来的研究进行了展望
摘要文本: 自动信任协商(AI)是互信关系建立的最新研究工作的一部分。
文本纠错任务
什么是文本纠错
在日常生活中,不管是微信聊天、微博推文甚至是出版书籍中,我们都或多或少地会发现文本中的错别字现象。
这些错别字可能源于语音输入时的口音偏差,如"飞机"被识别成了"灰机";也可能是拼音输入时误触了临近键位或者选错了结果,如"飞机"被识别成了"得急"、"肥鸡";亦或是手写输入时写成了形近字,如"战栗"被识别为了"战粟"......
常见的错误类型包括
- 拼写错误:中文课程->中文磕碜;明天会议->明天会易
- 语法错误:他昨天去参加会议了->他昨天将要去参加会议
- 标点符号错误:您好,请多指教!->您好,请多指教???
- 知识性错误:上海黄浦区->上海黄埔区
- 重复性错误:您好,请问您今天有空吗?->您好,请问您今天有空吗吗吗吗吗吗
- 遗漏性错误:他昨天去参加会议了->他昨天去参加了
- 语序性错误:他昨天去参加会议了->他昨天去会议参加了
- 多语言错误:他昨天去参加会议了->他昨天去参加huiyi了
- ......
总之,文本错误可能是千奇百怪的。对于人类而言,凭借着常识与上下文,实现语义理解尚不是什么难事,有时只是些许影响阅读体验;而对于一些特定的文本下游任务,如命名实体识别或意图识别,一条不加处理的错误输入文本可能会导致南辕北辙的识别结果。
文本纠错任务指的是通过自然语言处理技术对文本中出现的错误进行检测和纠正的过程。目前已经成为自然语言处理领域中的一个重要分支,被广泛地应用于搜索引擎、机器翻译、智能客服等各种领域。纵然由于文本错误的多样性,我们往往难以将所有错误通通识别并纠正成功,但是如果能尽可能多且正确地识别文本中的错误,能够大大降低人工审核的成本,也不失为一桩美事~
常见的文本纠错技术
常见的文本纠错技术主要有以下几种:
- 基于规则的文本纠错技术
- 基于语言模型的文本纠错技术
- 基于MLM的文本纠错技术
- 基于NLG的文本纠错技术
基于规则的文本纠错技术
这种文本纠错技术是通过实现定义的规则来检查文本中的拼写、语法、标点符号等常见错误,假如"金字塔"常被误写为"金子塔",则在数据库中加入两者的映射关系。由于这种传统方法需要大量的人工工作以及专家对于语言的深刻理解,因此难以处理海量文本或较为复杂的语言错误。
基于语言模型的文本纠错技术
基于语言模型的文本纠错技术包括错误检测和错误纠正,这种方法同样比较简单粗暴,方法速度快,扩展性强,效果一般。常见的模型有Kenlm。
- 错误检测:使用
jieba
中文分词器对句子进行切词,然后结合字粒度和词粒度两方面的疑似错误结果,形成疑似错误位置候选集。 - 错误纠正:遍历所有的候选集并使用音似、形似词典替换错误位置的词,然后通过语言模型计算句子困惑度,最后比较并排序所有候选集结果,得到最优纠正词。
基于MLM的文本纠错技术
我们知道,BERT在预训练阶段使用了Masked Language Model掩码语言模型(MLM)及Next Sentence Prediction下一句预测(NSP)两个任务,其中MLM任务中有15%*10%的Token会被替换为随机的其他词汇,迫使模型更多地依赖于上下文信息去预测Mask词汇,在一定程度上赋予了模型纠错能力。
因此,我们将BERT的MLM任务做一下简单的修改,将输入设计为错误的词汇,输出为正确的词汇,做一下简单的fine tune,即可轻松实现文本纠错功能。
例如,ACL2020的Soft-Masked BERT模型(论文笔记),设计了一个二重网络来进行文本纠错,其中"错误检测网络"通过Bi-GRU识别每个字符错误的概率,"错误纠正网络"倾向将错误概率更高的词Mask掉,并预测出真实词汇。
基于NLG的文本纠错技术
上述提到的Mask方法只能用于输入与输出等长的情况,但是实际应用中往往会出现两者不等长的情况,如错字或多字。一种可能的解决办法是,在原有的BERT模型后嵌入一层Transformer Decoder,即将"文本纠错"任务等价于"将错误的文本翻译成正确的文本",此时我们没法保证输出文本与原始文本中正确的部分一定能保持完全一致,可能在语义不变的情况下,会生成了一种新的表达方式。
一个文本纠错工具集:pycorrector
pycorrector是一个文本纠错工具集,内置了KenLM、MacBERT、Transformer等多种文本纠错模型。
- pycorrector的项目地址:https://github.com/shibing624/pycorrector
- 一个基于MacBERT的线上Demo:https://huggingface.co/spaces/shibing624/pycorrector
pycorrector不仅可以通过"import pycorrector"调用,也提供了Huggingface的预训练模型调用方式,以下是一个基于Huggingface的MacBERT4CSC调用样例。
python
import torch
from transformers import BertTokenizer, BertForMaskedLM
# 载入模型
tokenizer = BertTokenizer.from_pretrained("shibing624/macbert4csc-base-chinese")
model = BertForMaskedLM.from_pretrained("shibing624/macbert4csc-base-chinese")
text = "大家好,一起来参加DataWhale的《ChatGPT使用指南》组队学习课乘吧!"
input_ids = tokenizer([text], padding=True, return_tensors='pt')
# 生成结果文本
with torch.no_grad():
outputs = model(**input_ids)
output_ids = torch.argmax(outputs.logits, dim=-1)
output_text = tokenizer.decode(output_ids[0], skip_special_tokens=True).replace(' ', '')
print("原始文本: ", text)
print("纠错文本: ", output_text)
# 查看修改点
import operator
def get_errors(corrected_text, origin_text):
sub_details = []
for i, ori_char in enumerate(origin_text):
if ori_char in [' ', '"', '"', ''', ''', '琊', '\n', '...', '---', '擤']:
# add unk word
corrected_text = corrected_text[:i] + ori_char + corrected_text[i:]
continue
if i >= len(corrected_text):
continue
if ori_char != corrected_text[i]:
if ori_char.lower() == corrected_text[i]:
# pass english upper char
corrected_text = corrected_text[:i] + ori_char + corrected_text[i + 1:]
continue
sub_details.append((ori_char, corrected_text[i], i, i + 1))
sub_details = sorted(sub_details, key=operator.itemgetter(2))
return corrected_text, sub_details
correct_text, details = get_errors(output_text[:len(text)], text)
print(details)
运行结果
原始文本: 大家好,一起来参加DataWhale的《ChatGPT使用指南》组队学习课乘吧!
纠错文本: 大家好,一起来参加datawhale的《chatgpt使用指南》组队学习课程吧!
[('乘', '程', 37, 38)]
机器翻译任务
什么是机器翻译
机器翻译,又称为自动翻译,是利用计算机将一种自然语言(源语言)转换为另一种自然语言(目标语言)的过程。据不完全统计,世界上约有7000种语言,两两配对约有 70002
70002
种组合,这些语言中又不乏一词多义、垂类知识等现象,因此能够使用更少的标注数据,或者无监督地让计算机真正地理解输入语言的含义,并"信"、"达"、"雅"地转化为输出语言,是历来学者们的研究重心。
众所周知,机器翻译一直是自然语言处理领域备受关注的研究方向,也是自然语言处理技术最早展露头角的任务之一。如今市面上的机器翻译工具层出不穷,如大家常用的百度翻译、谷歌翻译,乃至小时候科幻片里才有的AI同声传译,如讯飞听见同传。简单来说可以将其划分为通用领域(多语种)、垂直领域、术语定制化、领域自适应、人工适应、语音翻译等。
常见的机器翻译技术
从机器翻译的发展历程来看,主要经历了如下几个阶段:
- 基于规则的方法
- 基于统计的方法
- 基于神经网络的方法
基于规则的方法需要建立各类知识库,描述源语言和目标语言的词法、句法以及语义知识,有时知识无关的世界知识。
基于统计的方法认为对于一条源语言 � ,任何一条目标语言 � 都可能是它的译文,只是可能性有高有低。对于源语言中的每个词 �� 及目标语言中的每个词 �� ,判断词对齐的概率,再通过期望最大算法(如EM算法)得到最大词对齐概率的对齐方式。这便是基于词的翻译模型。显然,将翻译的最小单位设计成词是不符合语法的,因此后来又延申出了基于短语的翻译方法,将最小翻译单位设计成连续的词串。
2013年,一种用于机器翻译的新型端到端编码器-解码器架构问世,将CNN用于隐含表征挖掘,将RNN用于将隐含向量转化为目标语言,标志了神经机器翻译开端。后来,Attention、Transformer、BERT等技术被相继提出,大大提升了翻译的质量。
以下是一个基于transformers实现机器翻译的简单样例
python
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
tokenizer = AutoTokenizer.from_pretrained("Helsinki-NLP/opus-mt-zh-en")
model = AutoModelForSeq2SeqLM.from_pretrained("Helsinki-NLP/opus-mt-zh-en")
text = "大家好,一起来参加DataWhale的《ChatGPT使用指南》组队学习课程吧!"
inputs = tokenizer(text, return_tensors="pt", )
outputs = model.generate(inputs["input_ids"], max_length=40, num_beams=4, early_stopping=True)
translated_sentence = tokenizer.decode(outputs[0], skip_special_tokens=True)
print('原始文本: ', text)
print('翻译文本: ', translated_sentence)
运行结果
原始文本: 大家好,一起来参加DataWhale的《ChatGPT使用指南》组队学习课程吧!
翻译文本: Hey, guys, let's join the ChatGPT team at DataWhale.