[TOC]
在贝壳一直做内容生成相关的工作,在此对过去大半年的工作做一个复盘和思考。
1.NLG的概念和意义
1.1 NLG简介
1.1.1 什么是NLG?
- 自然语言生成 - NLG 是 NLP 的重要组成部分。NLU 负责理解内容,NLG 负责生成内容,它的公式表达为NLP = NLU + NLG。以智能音箱为例,当用户说“几点了?”,首先需要利用 NLU 技术判断用户意图,理解用户想要什么,然后利用 NLG 技术说出“现在是6点50分”。NLG可以用于对话系统和一些需要机器内容
对于对话系统,有三种方式:
- 规则模版。优势:实现简单,效果可控;劣势:缺乏多样性
- 生成模型。seq2seq 和 transformer, 优势:无需规则;劣势: 效果不可控
- 检索式模型。文本检索与排序从问答库中挑选;优点:数据来源于已生成的回复,通顺性高;劣势:不能生成新的回复文本
NLG 可以将非语言格式的数据转换成人类可以理解的语言格式,如文章、报告等。目前NLG有2种方式:
(1)text-to-text:文本到文本的生成
(2)data-to-text:数据到文本的生成
1.1.2 NLG的3个level
- 简单的数据合并
- 模板化的 NLG
- 高级 NLG :它理解输入数据的意图,并考虑上下文,智能化的整理语言,并将结果呈现在用户可以轻松阅读和理解的叙述中。
1.1.3 NLG的6个步骤
第一步:内容确定,决定文本应该包含哪些信息。
第二步:文本结构,合理的组织文本的顺序。例如在报道一场篮球比赛时,会优先表达「什么时间」「什么地点」「哪2支球队」,然后再表达「比赛的概况」,最后表达「比赛的结局」。
第三步:句子聚合,多个信息合并到一个句子里表达可能会更加流畅,也更易于阅读。
第四步:语法化,通过一些连接词将这些句子组织成自然语言。
第五步:参考表达式生成,它跟语法化的本质区别在于需要识别出内容的领域,然后使用该领域的词汇。
第六步:语言实现,当所有相关的单词和短语都已经确定时,需要将它们组合起来形成一个结构良好的完整句子。
1.1.4 NLG的3种典型应用
- NLG 的不管如何应用,大部分都是下面的3种目的:
(1)能够大规模的产生个性化内容
(2)帮助人类洞察数据,让数据更容易理解
(3)加速内容生产
1.2 为什么需要NLG?
文本内容本身就拥有很大的业务价值,一方面生产的文章内容可以增加用户的停留时间,另一方面像推荐理由这类的短文本可以吸引用户的点击,同时,目前很多文章、标题和推荐理由都是由运营或者经纪人书写的,需要的人力成本高,因此通过使用机器大规模生产文本可以起到降本提效的效果。
1.3 NLG技术
文本生成的三种主流方法各自的优劣势:
- 规划式:根据结构化的信息,通过语法规则、树形规则等方式规划生成进文本中,可以抽象为三个阶段。宏观规划解决“说什么内容”,微观规划解决“怎么说”,包括语法句子粒度的规划,以及最后的表层优化对结果进行微调。其优势是控制力极强、准确率较高,特别适合新闻播报等模版化场景。而劣势是很难做到端到端的优化,损失信息上限也不高。
- 抽取式:顾名思义,在原文信息中抽取一部分作为输出。可以通过编码端的表征在解码端转化为多种不同的分类任务,来实现端到端的优化。其优势在于:能降低复杂度,较好控制与原文的相关性。而劣势在于:容易受原文的束缚,泛化能力不强。
- 生成式:通过编码端的表征,在解码端完成序列生成的任务,可以实现完全的端到端优化,可以完成多模态的任务。其在泛化能力上具有压倒性优势,但劣势是控制难度极大,建模复杂度也很高。
而我们的内容平台的建设就是基于这三步。
2 NLG平台从0到1的建设
整体而言,目前贝壳内容带来的用户日活、月日比、留存等数据指标并不乐观,房产类内容更新频率低(周更或月更),用户一次性消费(看过后不会再看),内容本身偏严肃性,缺乏吸引力。
不过从MAU角度而言,内容还是可以起到召回用户的作用,通过精准push或者经纪人转发的方式,最近几日没使用APP的用户被召回的数量还是很可观的,这一切也需要基于内容的建设。
2.1 基于标签的数据聚合
整体目标:通过机器算法提升内容的生产效率和内容质量,并通过精准化的推荐分发给用户,提升平台整体的商机量和MAU;
为了能快速上线、拓展场景,我们采用了基于内容主题词的模版内容+房源卡片聚合的方法。首先设定多个内容主题,如500万内,降价房等,为每个主题词定义一套计算逻辑,从房源列表中召回满足条件的房源,与标题、导语组合成文章。标题、导语中会添加地理维度占位符,如小区,城市等,在生产文章时,可以填充这些占位符裂变出多个粒度的文章内容,月产文章可达到数十万,重复文章会进行去重。
规划式生成
上述方式生产的文章几乎没有内容信息,都是些房源引导用户点击;为了生产有内容信息的文章,我们将模版与代码解耦,使用python编写数据处理逻辑,liquid编写模版,最后通过liquidpy渲染生成文章内容;步骤如下:
- 运营撰写文章样稿,并拆解成一块块模版,附加数据约束条件;
- 需求评估,通过则RD进入开发;
- 数据处理+模版编写(hive+python+liquid)
- 渲染成文,线上投放
这样生产的内容信息量十足。
2.2 基于无监督学习的文本生成
卖点创意是指通过内容挖掘算法来自动生成房源真正有温度、有亮点的内容描述。 可以参考美团的发现页面中的店铺,就是通过从用户评论中抽取内容描述作为店铺的推荐标语,让人有点击的欲望。核心指标为CTR。
TextRank算法是一种仿照PageRank的无监督摘要抽取方法。PageRank主要用于对在线搜索结果中的网页进行排序。以概率d按照存在的超链接随机跳转,以概率转移矩阵中的概率从超链接跳转到下一个页面;或以概率(1-d)进行完全随机跳转,这时以等概率(1/n)跳转到任意网页
$$PR = \frac{1-d}{N}+d\sum {\frac{PR}{|OUT(v_j)|}}$$
注意以下几点:
- 转移矩阵,2行1列,表示b->c 的连接,计算时相当于b分了部分权重给c
- rank leak: 某个节点只有入链,会导致其他节点rank为0,
- rank sink: 某节点只有出链
- 阻尼因子d,解决dead ends问题,这个因子代表了用户按照跳转链接或是直接输入网址来上网的概率
TextRank只是把网页替换成了句子,将句子作为节点,句子间的相似度作为边来构建图模型,根据计算公式迭代计算每个句子的TextRank得分,但是这样计算出来的矩阵是不满足马尔可夫矩阵性质的,所以可以使用softmax对每一列做处理进行改良。
2.3 基于监督学习的文本生成
将卖点抽取问题建模成文本分类问题,注意几点:
标注时做好交叉验证和校验。
训练词向量时无需去除停用词,但要去除低频词,如数字等等。标注员在标注时会考虑停用词,有停用词的句子更完整。
训练模型时输入数据仅保留中文数据,冻结embedding向量,学习率调低
模型准确率到了93%,再也提升不了,拿最好的模型去run下训练集和验证集,看看是哪些样本一直识别不了,看看是否需要重新标注。
|
|
2.4 基于seq2seq的文本生成
2014年提出的Seq2Seq Model,是解决这类问题一个非常通用的思路,本质是将输入句子或其中的词Token做Embedding后,输入循环神经网络中作为源句的表示,这一部分称为Encoder;另一部分生成端在每一个位置同样通过循环神经网络,循环输出对应的Token,这一部分称为Decoder。通过两个循环神经网络连接Encoder和Decoder,可以将两个平行表示连接起来。
另外一个非常重要的,就是Attention机制,其本质思想是获取两端的某种权重关系,即在Decoder端生成的词和Encoder端的某些信息更相关。
RNN在梯度计算过程中存在连乘,导致梯度趋于0或者趋于无穷大,使得模型无法有效地学习到长距离的依赖关系
LSTM是RNN的一种常见的改进模型,引用了门机制去解决梯度爆炸或者梯度消散的问题。门计算所需要用到的参数,由模型自己去进行学习。每一个门都有对应的参数,每一个门的每次计算,是根据当前的输入前一刻的状态,以及内部状态,来计算门的值是什么,最后再对整个状态进行更新。
GRU是另一个对RNN进行改进的模型,可以看作是LSTM的变形。相对于LSTM ,GRU模型减少了一个门,参数量也会变少。因此,最终GRU的速度比RNN、LSTM更快一些。
在seq2seq模型里,实际上输入的是一段序列文本,生成的也是一段序列文本
Encoder:seq2seq的编码器是单层或多层的RNN(双向),会对输入的文本进行编码变成一个向量输出。
Decoder:seq2seq的解码器,也是一个单层或多层的RNN(非双向),根据context信息对每一步进行解码,输出对应的文本。
这里提到的每步context,最简单的方法是直接拿encoder的输入文本信息的最后一个状态,或者是整个状态进行加总,得到一个固定的向量。然后,再将这个向量作为decoder的context进行输入。
但这样的问题是,这个context是一个固定长度的向量,表达能力比较有限,所以在这个基础上,又提出了Attention机制。
Attention机制:每步解码都会根据当前状态对encoder的文本进行动态权重计算,然后对权重进行归一化。得到归一化后,再算出一个当前加权后的context,作为decode的context。这样处理后的表达能力就会就会更强一些。
Luong Attention 相较 Bahdanau Attention 主要有以下几点区别:
- $c_t$计算方式不同,Luong: $c_t=\sum h_dh_e$ 巴达脑: $ct=\sum h{d-1}h_e$
- decoder输入输出不同: Luong Attention: $W_t[c_t;h_t]$ Bahdanau:$[ct, h{t-1}]$ ,
全局注意力模式会将 encoder 的每一步 hidden state 进行注意力计算,而局部注意力模式则计算部分范围的 hidden state。
损失函数:对每一步单词计算交叉熵,累加
Beam search: 贪心搜索;可能会产生的问题是:可能都是十分相近的句子。
Copy机制最初设计用于解决OOV问题。当生成一段文本的时候,这个生成单词可以有两种来源:一种是通过普通seq2seq生成;另一种是从原文本拷贝过来。比如普通的生成任务里,他往往有大量的OOV(out of vocabulary),这样的词是无法生成的,以至于回复效果会变差。
注意力的得分的明显特点是,它经过了归一化,代表了这段文本中不同单词在当前步骤的重要程度,可以看作拷贝不同单词的概率
将每步输出的单词概率看作一个混合模型(生成的单词概率分布与拷贝原文的单词概率分布的混合),利用注意力得分作为拷贝单词的概率。
普通seq2seq存在生成回复相关性不够高、生成回复为否定句或负面情感的问题。
Copy机制+seq2seq:提高了回复相关性,但依然无法解决回复为否定句或负面情感的问题。
主题控制+seq2seq:既提高回复相关性,也可以控制回复语义,提升回复效果,但可能出现回复不通顺的问题,并存在否定句式与负面回复。
属性控制+seq2seq:比较能满足场景需要,但有一定比例的通用回复,可以通过改进Beam Search、后排序的办法来提高个性化回复的得分,从而提高回复多样性
Beam search 解决多样性:
通过增加惩罚项:比如对同一组的第二、第三选项进行降权,避免搜索结果来自同一路径
计算每条路径的概率分,后面生成的话跟第一组相似,就对该组进行降权,避免组与组之间相似度过高
Coverage Loss: 若该词之前出现过了,$c_{i}^t$就会很大,loss优化时就需要$a_i^t $变小,代表这个位置的词被注意的概率变小
让模型自己去学习它想说什么:
输入静态标签信息,数据预处理清洗后
对目标文本做NLU识别出其中涉及到的标签或者说实体,将这部分标签与静态标签信息做个融合,这部分标签作为
Pointer network让decoder可以根据输入序列决定输出的长度
decoder输出的结果,和encoder状态计算一个attention分布,argmax后结果作为decoder新的输入,知道end出现
适合做summary,直接从input中挑字出来
训练一个$p_{gen}$
3 评估方法
项目中使用的人工评估的方式,多样化的描述更好,不一定要和目标越接近越好
- 基于词重叠率的方法
- 机器翻译 & 摘要抽取 常用指标
- 基于词重叠率的方法是指基于词汇的级别计算模型的生成文本和人工参考文本之间的相似性,比较经典的代表有 BLEU、METEOR 和 ROUGE,其中 BLEU 和 METEOR 常用于机器翻译任务,ROUGE 常用于自动文本摘要。
- 词向量评价指标(在论文中一般很少使用)
- 词向量评价是通过 Word2Vec、Sent2Vec 等方法将句子转换为向量表示,这样一个句子就被映射到一个低维空间,句向量在一定程度上表征了其含义,再通过余弦相似度等方法就可以计算两个句子之间的相似程度。
- 使用词向量的好处是,可以一定程度上增加答案的多样性,因为这里大多采用词语相似度进行表征,相比词重叠中要求出现完全相同的词语,限制降低了很多。
3.1 词重叠率
参考:评估指标整理
BLEU
核心思想
- 比较候选译文和参考译文里的 n-gram 的重合程度,重合程度越高就认为译文质量越高。unigram用于衡量单词翻译的精确性,高阶n-gram用于衡量句子翻译的流畅性。 实践中,通常是取N=1~4,然后对进行加权平均。
假设机器翻译的译文C和一个参考翻译S1如下:
C: a cat is on the table
S1: there is a cat on the table
计算各个gram精确率
p1 计算 a cat is on the table 分别都在参考翻译S1中 所以 p1 = 1
p2 (a, cat)在, (cat is) 没在, (is on) 没在, (on the) 在, (the table)在 所以p2 = 3/5
p3 (a cat is)不在, (cat is on)不在, (is on the)不在, (on the table)在 所以 p3 = 1/4
这样计算的结果明显不正确,因此在计算时,往往会加上修正和长度惩罚
- 缺点:
- 只看重精确率,不看重召回率。
- 存在常用词干扰(可以用截断的方法解决)
- 短句得分较高。即使引入了brevity penalty,也还是不够。
- 改进
- 截断:改进常用词干扰
- brevity penalty:改进短句得分较高的问题
ROUGE
核心思想
大致分为四种:ROUGE-N,ROUGE-L,ROUGE-W,ROUGE-S。常用的是前两种(-N与-L)
ROUGE-N (将BLEU的精确率优化为召回率)
ROUGE-L (将BLEU的n-gram优化为公共子序列),计算的是候选摘要与参考摘要的最长公共子序列长度,长度越长,得分越高,基于F值。
ROUGE-W (将ROUGE-L的连续匹配给予更高的奖励)
ROUGE-S (允许n-gram出现跳词(skip)),即跳跃二元组(skip bigram)。例如句子 “I have a cat” 的 Skip 2-gram 包括 (I, have),(I, a),(I, cat),(have, a),(have, cat),(a, cat)。
ROUGE的出现很大程度上是为了解决NMT的漏翻问题(低召回率),因为它不考虑候选译文是否流畅。
NIST
NIST(National Institute of standards and Technology)方法是在BLEU方法上的一种改进。
最主要的是引入了每个n-gram的信息量(information) 的概念。BLEU算法只是单纯的将n-gram的数目加起来,而nist是在得到信息量累加起来再除以整个译文的n-gram片段数目。这样相当于对于一些出现少的重点的词权重就给的大了。
TER
是一种基于距离的评价方法,用来评定机器翻译结果的译后编辑的工作量。
距离被定义为将一个序列转换成另一个序列所需要的最少编辑操作次数。操作次数越多,距离越大,序列之间的相似性越低;相反距离越小,表示一个句子越容易改写成另一个句子,序列之间的相似性越高。
$$score= \frac {edit(c,t)}{l}$$
其中 edit(c,r) 是指机器翻译生成的候选译文 c 和参考译文 r 之间的距离,l 是归一化因子,通常为参考译文的长度。在距离计算中所有的操作的代价都为 1。在计算距离时,优先考虑移位操作,再计算编辑距离,也就是增加、删除和替换操作的次数。直到移位操作无法减少编辑距离时,将编辑距离和移位操作的次数累加得到TER 计算的距离。
3.2 基于语言模型的评估方法
PPL
perplexity(困惑度)用来度量一个概率分布或概率模型预测样本的好坏程度。困惑度越低,翻译质量越好
核心思想
- (1)根据参考句子,学习一个语言模型P;
- (2)根据语言模型P,计算候选句子的得分;
- (3)根据句子长度对上述得分进行Normalize
公式:
$$PPL(W)=P(w_1w_2…w_N)^{-\frac{1}{N}}$$
缺点
- 数据集越大,困惑度下降得越快
- 数据中的标点会对模型的PPL产生很大影响
- 常用词干扰
基于 bert 的评分指标
BERTSCORE:
对两个生成句和参考句(word piece 进行 tokenize)分别用 bert 提取特征,然后对 2 个句子的每一个词分别计算内积,可以得到一个相似性矩阵。基于这个矩阵,我们可以分别对参考句和生成句做一个最大相似性得分的累加然后归一化,得到 bertscore 的 precision,recall 和 F1
还可以适用IDF进行加权计算。
PTM
浅层词嵌入: word2vec,无法解决一词多义,OOV问题
预训练编码器: elmo, gpt-1, bert, xlnet
将外部领域数据整合训练: LIBERT,SenseBERT
模型太大,需要模型压缩
剪枝、知识蒸馏、模型替换
其他
MEMM判别模型,考虑了相邻状态的依赖,
CRF解决标记偏置问题
LSTM+CRF: s=A+P , logP(y|X) = s - log()
xgboost对特征值做聚合统计,按照特征值密度分布,构造直方图计算特征值分布面积,划分分布成若干个桶
每个桶面积相同,将桶边界上的特征值作为split point的候选分裂点。 计算特征收益可以多线程进行
word2vec直接sum,不再拼接,舍弃隐层,用两种方式进行优化
负采样: 加速模型计算(每次更新采样词的权重),保障模型训练效果;
LSA(基于概率图模型的生成模型)基于共现矩阵构建词向量,采用SVD进行矩阵分解
特征提取 | ||
---|---|---|
elmo | LSTM | |
GPT | t ran sformer | |
bert | t ran sformer |