关键词自动采集生成内容系统-无需任何打理(文章节选自《自然语言处理技术入门与实战》(一句话)自动生成模型)
优采云 发布时间: 2021-12-08 13:18关键词自动采集生成内容系统-无需任何打理(文章节选自《自然语言处理技术入门与实战》(一句话)自动生成模型)
文章 摘自《自然语言处理技术介绍与实战》
在自然语言处理中,另一个重要的应用领域是文本的自动书写。关键词、关键短语和自动摘要提取都属于该领域的应用。但是,这些应用程序是从多到少生成的。这里我们介绍另一个应用:从少到多的生成,包括句子复制、从关键词生成、主题生成文章、或段落等。
基于关键词的自动文本生成模型
本章第一节介绍了一些基于关键词生成一段文本的处理技术。主要通过应用关键词抽取、同义词识别等技术实现。下面对实现过程进行解释和介绍。
场景
在投放搜索引擎广告时,我们需要为该广告写一个句子描述。一般来说,模型的输入是一些关键词。比如我们要投放的广告是鲜花广告,假设广告的关键词是:“鲜花”和“便宜”。对于这个输入,我们希望生成一定数量的候选单句广告描述。
对于这种情况,您还可以输入一个句子。比如我之前手动写过一个例子:“这个周末小白花只要99元,还有包邮包邮!”。有必要在此句子的基础上重现一定数量的表达不同但含义相似的句子。这里介绍一种基于关键词的文本(一句话)自动生成模型。
原则
模型处理流程如图1所示。
图1
首先,根据输入数据的类型进行不同的处理。如果输入为关键词,则在语料库中选择与输入关键词相同的句子。如果输入是句子,则在语料库中选择与输入句子相似度大于指定阈值的句子。
对于关键词语料库中句的提取算法,使用上一章介绍的方法。具体算法选择,大家可以根据自己语料库的形式自由选择。
图2
句子相似度计算,这里按照图2左侧虚线框内的流程计算:
首先,对要计算的两个句子进行分词。对于分词后的句子,判断是否满足模板变换。若满足则直接将句子放入候选集中,相似度置0,若不满足则转步骤c)计算。
判断两个句子是否满足模板变换的流程图如图2右侧虚线框所标的过程所示:完全一样,只是位置不同,满足模板变换的条件。(2)如果词不完全一样,看不同词之间能否进行同义词变换。如果可以进行同义词变换,变换后的两个句子是一个句子中常用词的集合,如果该集合是一个句子中所有词的集合,也满足模板变换条件。(3)如果上面两步不满足,那么这两个句子不满足Template转换。
计算两个句子剩余词的词距。如果两句中剩下的词分别是第1句:“鲜花”、“多少钱”、“免运费”。句子 2:“鲜花”、“便宜”、“免费送货”。那么距离矩阵如下表所示:
得到相似矩阵后,将两个句子中的相似词替换为一个,假设我们这里将“free shipping”替换为“free shipping”。那么这两个句子的词向量就变成了:sentence 1:、sentence 2:。
对于两个句子分别构造bi-gram统计向量,有:(1)句子1:,,,. (2)句子2:,,,.
这两个句子的相似度由以下公式计算:
所以上例的相似度为:1.0-2.0*2/8=0.5。
完成候选句子的提取后,需要根据候选句子的个数来判断后续的操作。如果选择的候选句子大于或等于所需数量,则根据句子相似度从低到高选择指定数量的句子。否则,必须复制该句子。这里采用同义词替换和根据指定模板重写的方案。
完成
计算候选句的代码如下:
映射结果 = new HashMap();
if (type == 0) {//输入为 关键词
结果 = getKeyWordsSentence(keyWordsList);
}别的 {
结果 = getWordSimSentence(句子);
}
//如果候选集的数量大于或等于所需的数量,结果将被裁剪
如果 (result.size() >= number) {
结果 = 子(结果,数字);
}别的 {
//如果候选集的个数小于需要的个数,则将结果相加
结果 = 添加(结果,数字);
}
首先,根据输入的内容形式选择不同的句子生成模式。这一步的关键是语料的处理和相似关键词和相似句子的筛选。对于关键词的筛选,我们使用Bloom的算法,当然也可以使用索引搜索。对于候选句子,我们首先使用关键词对语料进行初步筛选。确定概率较高的句子作为后续计算的句子。
对于得到的候选结果,我们以map的形式保存,其中key为后续句子,value为与目标的相似度。之后,相似度从低到高排序。关于地图的排序,我们在上一章已经介绍过了,这里不再赘述。
实现句子相似度过滤计算的代码如下。
for (String sen: 句子列表) {
//对要识别的句子进行分词处理
List wordsList1 = parse(sentence);
List wordsList2 = parse(sen);
//首先判断两个句子是否满足目标变换
boolean isPatternSim = isPatternSimSentence(wordsList1, wordsList2);
if (!isPatternSim) {//不符合目标变换
//先计算两个句子的bi-gram相似度
double tmp = getBigramSim(wordsList1, wordsList2);
//这里的过滤条件是相似度小于阈值,因为bi-gram的相似度越小,两者越相似
如果(阈值> tmp){
结果.put(sen,tmp);
}
}别的 {
result.put(sen,0.0);
}
}
首先对待识别的两个句子进行分词,对分词结果进行模板转换识别。如果满足模板转换的条件,则将该句子视为候选句子并分配最小概率。如果不是,计算两个bi-grams的相似度。然后根据阈值进行过滤。
这里使用的bi-gram进行了改进,而传统的bi-gram不需要进行缩放。这里做这个计算是为了避免不同长度的字符的影响。对于相似度的度量,您也可以根据自己的实际情况选择合适的度量方法。
扩张
本节处理的场景是:从文本到文本的生成。该场景一般主要涉及文本摘要、句子压缩、文本复制、句子融合等文本处理技术。其中,本节涉及两个方面的技术:文本摘要和句子重写。上面提到的文本摘要主要涉及:关键词抽取、词组抽取、句子抽取等。句子复制根据实现方式的不同,大致可以分为以下几种类型。
基于同义词的重写方法。这也是本节使用的方法。这种方法是词汇层面的,可以在很大程度上保证替换后的文本与原文一致。缺点是会降低句子的流畅度。当然也可以结合隐马尔可夫模型来修正句子搭配,提升整体效果。
基于模板的重写方法。这也是本节使用的方法。这种方法的基本思想是从大量采集的语料中统计归纳出一个固定的模板,系统根据输入的句子和模板的匹配情况决定如何生成不同的表达方式。假设存在以下模板。
rzv n, aa ——> aa, rzv n
那么对于(输入):this/rzv,flowers/n,true/a,cheap/a可以转换为(output):true/a,cheap/a,this/rzv,flowers/n 这种方法的特点是容易实现了,处理速度也快,但问题是模板的通用性很难把握。如果模板设计得太死板,就会难以处理复杂的句子结构,能够处理的语言现象也会受到一定的约束。如果模板设计得太灵活,往往会产生错误的匹配。
基于统计模型和语义分析生成模型的重写方法。这类方法是根据语料库中的数据进行统计,得到大量的转换概率分布,然后根据已知的先验知识替换输入的语料库。这种方法的句子是根据分析结果生成的。从某种意义上说,生成是在分析的指导下实现的。因此,重写的句子可能具有良好的句子结构。但是它所依赖的语料库非常庞大,需要人工标注大量数据。对于这些问题,新的深度学习技术可以解决部分问题。同时,
RNN模型实现文本自动生成
6.1. 第2节介绍了一些基于短文本输入获取长文本的处理技术。这里主要使用RNN网络,利用其处理序列数据的能力实现文本序列数据的自动填充。下面是对其实现细节的解释和介绍。
场景
在做广告的过程中,我们可能会遇到这样的场景:从一个句子中生成一个描述文本,文本长度在200到300字之间。输入也可能是某个主题关键词。
这时候我们就需要一种算法,可以根据少量的文本输入生成大量的文本。这是一个算法:RNN算法。在5.第3节中,我们介绍了这个算法,用于实现拼音到汉字的转换。其实这两个场景的模式是一样的,都是根据给定的文本信息生成一些其他的文本信息。区别在于前者是生成当前元素对应的汉字,这里是生成当前元素对应的下一个汉字。
原则
正如在 5. 部分 3 中一样,我们在这里仍然使用 Simple RNN 模型。所以整个计算流程图如图3所示。
图 3
在特征选择的过程中,我们需要更多地考虑上下段落的联系、段落的长度、段落中的情感变化、措辞变化等描述符提取。这样可以更好的实现文章的自然转移。
在生成的文章中,形容词和副词的使用可以给予更高的比例,因为形容词和副词一般不影响文章的结构和意义的表达,但同时可以增加文章的吸引力。比如最好的、最漂亮的、最便宜的等等,基本上都是百搭的词。不同的名词或动名词可以组合使用。同时,读者看到后普遍有想了解更多的愿望。
与主题相关的词可以用在很多地方。如果可以用与主题相关的词代替,尽量用与主题相关的词代替。因为这样不仅可以提高文章的连续性,还可以增加主题的曝光度。
以上是针对广告场景的一些经验谈。其他场景的模式可能不适合,但您可以根据自己的场景确定具体的优化策略。
具体计算过程与5.第3节基本相同,这里不再赘述。
代码
实现特征训练计算的代码如下:
公共双列火车(列表 x,列表 y){
已经训练 = 真;
double minError = Double.MAX_VALUE;
for (int i = 0; i
//定义更新数组
double[][] weightLayer0_update = new double[weightLayer0.length][weightLayer0[0].length];
double[][] weightLayer1_update = new double[weightLayer1.length][weightLayer1[0].length];
double[][] weightLayerh_update = new double[weightLayerh.length][weightLayerh[0].length];
List hiddenLayerInput = new ArrayList();
列表 outputLayerDelta = new ArrayList();
double[] hiddenLayerInitial = new double[hiddenLayers];
//为初始隐藏层变量赋值0
Arrays.fill(hiddenLayerInitial, 0.0);
hiddenLayerInput.add(hiddenLayerInitial);
双整体错误 = 0.0;
//前向网络计算预测误差
整体错误 = 传播网络(x,y,hiddenLayerInput,
outputLayerDelta,整体错误);
如果(整体错误
minError = 整体错误;
}别的 {
继续;
}
first2HiddenLayer = Arrays.copyOf(hiddenLayerInput.get(hiddenLayerInput.size()-1), hiddenLayerInput.get(hiddenLayerInput.size()-1).length);
double[] hidden2InputDelta = new double[weightLayerh_update.length];
//调整权重矩阵到后向网络
hidden2InputDelta = backwardNetWork(x, hiddenLayerInput,
outputLayerDelta, hidden2InputDelta,weightLayer0_update, weightLayer1_update, weightLayerh_update);
weightLayer0 = matrixAdd(weightLayer0, matrixPlus(weightLayer0_update, alpha));
weightLayer1 = matrixAdd(weightLayer1, matrixPlus(weightLayer1_update, alpha));
weightLayerh = matrixAdd(weightLayerh, matrixPlus(weightLayerh_update, alpha));
}
返回 -1.0;
}
首先,初始化要调整的变量。这一步完成后,使用前向网络预测输入值。预测完成后,使用后向网络根据预测误差调整每个权重向量。
在这个过程中需要注意的是,每次权重更新都不是完全更新,而是根据学习率α进行更新。其他步骤与前面描述的基本相同。
实现预测计算的代码如下:
公共双[]预测(双[] x){
如果(!已经训练){
new IllegalAccessError("模型没有经过训练,无法预测!!!");
}
double[] x2FirstLayer = matrixDot(x, weightLayer0);
double[] firstLayer2Hidden = matrixDot(first2HiddenLayer, weightLayerh);
如果(x2FirstLayer.length != firstLayer2Hidden.length){
new IllegalArgumentException("x2FirstLayer 的长度不等于 firstLayer2Hidden 的长度!");
}
for (int i = 0; i
firstLayer2Hidden[i] += x2FirstLayer[i];
}
firstLayer2Hidden = sigmoid(firstLayer2Hidden);
double[] hiddenLayer2Out = matrixDot(firstLayer2Hidden, weightLayer1);
hiddenLayer2Out = sigmoid(hiddenLayer2Out);
返回 hiddenLayer2Out;
}
在预测之前,需要确定模型是否经过训练。如果没有完成训练,则必须先训练预测模型。当然,这是与特定业务逻辑相关的验证。这主要是针对预测和训练分离的情况。如果训练和预测在同一个过程中,则不需要验证。
得到训练模型后,按照前向网络的过程逐步计算,最终得到预测值。因为我们这里是一个分类问题,所以我们最终选择概率最大的词作为最终输出。
扩张
文本生成根据输入方式的不同可以分为以下几种类型:
文本到文本生成。即输入是文本,输出也是文本。
图片转文字。也就是说,输入是图像,输出是文本。
数据到文本。也就是说,输入是数据,输出是文本。
其他。即输入形式不是以上三种,输出的也是文本。因为这类输入比较难概括,所以归为other。
其中,第三类2、最近发展非常快,尤其是随着深度学习、知识图谱等前沿技术的发展。基于图像生成文本描述的实验结果正在不断刷新。基于GAN(Adversarial Neural Network)的图像文本生成技术实现了非常大的图谱,不仅可以根据图片生成非常好的描述,还可以根据文本输入生成对应的图片。
从数据生成文本,目前主要应用于新闻写作领域。中文和英文都有很大的进步。英文版以美联社为代表,中文版以腾讯为代表。当然,这两者都不是单纯的以数据作为输入,而是综合了以上四种情况的新闻写作。
从技术上讲,主流的实现方式有两种:一种是基于符号的,用知识图谱表示。这种方法使用了更多的人类先验知识,对文本的处理收录更多的语义。元素。另一种是基于统计(connection),即在大量文本的基础上学习不同文本的组合,然后根据输入推断出可能的组合作为输出。随着深度学习和知识图谱的结合,两者之间存在明显的融合现象,应该是实现未来技术突破的重要节点。