导读

汉语短文本对话立场检测的主要任务就是通过以对话的一个人的立场为主要立场,而判断另一个人针对该人的回话的立场。立场包括支持,反对,中立三种立场。基于对话的立场检测应用方向很广,比如人机对话系统,机器需要判断对方说话的立场是什么来决定自己回话的立场;比如情感挖掘,和一个支持者的立场进行对话,就能判断出该对话者的情感倾向。

本文采用深度学习的方法,使用双向 LSTM 神经网络进行对给定答案的微博对话语料进行训练。每一份训练样例包含博主的话和回话者的对话,博主和回话者的话都有各自对话的立场表示标注,回话者还有针对博主的立场方向标注自己的立场。本文用的新颖方法是将博主和回话者的话分别经过双向 LSTM,将结果拼接到一起,在经过池化层和线性层得到分类结果。通过该结果和标准的答案比较,通过交叉熵得出损失值,反向传播梯度,更新参数,达到训练模型的效果。最后通过调参得出在测试集上效果最佳的模型为最终的模型。并使用该模型,对人工输入的对话进行真实的立场预测。

文本数据

这里的是很多组人工处理过的数据文本。

随便拿出来一个原始数据进行举例:

[PO]为post,博主说的话,[RE]为response,回答博主的话。而立场检测就是为了站在博主的立场,来检测其他回复的立场。所以需要标记post的立场,这里是积极的,positive,简称p,这里用[PO]STANCE#p表示;而回复response是不支持post的观点的,就是消极的,negative,简称n;但是有时候也是中立的,不支持也不反对post的话,那就是中立的,middle,简称m。

那么这里对数据进行处理:

又因为句子本身的情感极性也会对立场判断有影响,所以再标上每个句子的极性:[PO]是个积极的句子,这里用[PO]POLAR#p来表示,即post 极性为positive;[RE]极性为消极的,即这里用[RE]POLAR#n来表示:

文本数据处理

1.中文余料的清洗

一段文本,中英文都会有,所以对中英文都得分别处理。对中文的处理:

(1)繁体转简体

(2)全角英文字母转半角

(3)全角中文标点转半角

举个例子

代码为:

2.对英文语料的清洗

因为中文中掺杂着英文是很正常的事,所以还是有必要处理下英文的文本。

对英文的处理分为以下几个方面:

为了好区分,下面用下划线(_)表示空格

(1)将缩写词用空格分开:

比如Tom’s改为Tom_’s;I’ve改为I_ ‘ve;don’t改为do_n‘t;we’re改为we_’re;you’d改为you_’d;we’ll改为we_’ll

(2)一些标点符号需要和词分开:

比如 , 改为 _,_ ;!改为_!_;(改为_(_;)改为_)_;?改为_?_

(3)连续两个以上的空格修改为一个空格

(4)全都改为小写

代码为:

训练集和测试集

训练集是作为训练模型用的数据集,测试集是测试训练集训练出来的模型的效果。这里用的训练集和测试集数据对数分别为:7321对和2090对。(如果再完美些,可以加上开发集。这里数据有限,省略了开发集。)

建立字典

通过训练集对每一个词建立字典的目的是为了接下来的数据操作,因为计算机无法对文本进行处理,只能对数字进行识别并处理。但是测试集里的词一般都不会都在训练集里出现,所以也需要设置未出现的词unknown,简写unk;之后写批处理batch的时候也需要进行空白填补padding,简称pad。这两个也都需要放进字典里。

建立字典的主要代码

其中想了解HyperParams类代码,在下面的链接里我会附上github源代码。

序列数字化

这个和字典是对应的,字典是将词对应上数字,这里是通过字典将句子或label变成数字。

代码为

算法实现流程

(1)文本数字化因为每个文本里有很多组数据,每组数据里都有一个post,一个response,一个label(金标,用来表示)。训练的时候都是选取几组数据来训练的,这个几组数据也就是之后调参用的批处理大小batch_size,这里默认为1,也就是一组数据。因为之前这些数据都是分好词的,所以这里直接通过word字典直接数字化即可。然后将数据放进网络开始进行一系列处理。

(2)embedding层因为要给这两个post,response分别对每个数字一个编码,也就是将它向量化,这里叫做embedding layer。最终的到两个embedding向量。将每个数字放到维度为embed_size的向量空间。这样每个词都有自己的唯一表示。这里初始化embedding有两种:一种是通过当前文本进行训练学习,也即是刚开始可以随机初始化或者都初始化为0,随机初始化过程中可以用概率分布来控制数据分布,比如正态分布;另一种是通过外部预训练好的词向量,将它拷贝到当前网络的embedding layer的权重里。这俩种初始化方法可以作为之后调参的方法。

(3)dropout层然后经过dropout层,因为一般情况下,随着数据量增大的时候,网络学习的精度也就越高,但是这样的效果其实不是我们想要的,会达到过拟合的效果。所以就需要减少数据,在神经网络中,为了减少数据,只能从节点入手,去掉节点即可,这样实现就是讲想要去掉的节点的权重设为0即可,dropout就是这样的功能。Dropout层有一个参数,float型的,表示网络中每个隐藏层中需要留下可用节点的比率,比如0.6,就表示保留60%,使每层40%的节点失活。经过dropout层不会改变维度大小,也就是说原本什么维度,输出还是什么维度。

(4)biLSTM层将这两个post,response的数据经过biLSTM层,biLSTM层里有两个设置参数的地方,为hidden_size和hidden_num,hidden_size为隐层中的节点(也可以说是参数)个数,hidden_num表示有多少层隐层。这两个设置也是之后调参用的数据。输出为两个值,outputs(这里包含预测的信息)和C(状态数据,用不上,舍去)。

(5)拼接之后将post和response两个outputs合并到一起,维度对上即可。比如此时post维度为(1,5,128),response维度为(1,10,128),那么合并之后为(1,15,128)。其中维度具体为(批处理大小,句子长度,隐层参数大小*2),注释:乘2是因为单向的LSTM该位置为隐层参数大小,双向LSTM就为两个隐层拼接到一起的,所以这里为两个隐层大小,故乘2。

(6)池化上述数据经过max_pooling层最大池化层(当然也有avg_pooling平均池化层,min_pooling最小池化层,常用的为max_pooling)。选取指定维度的最大值,最终维度变为(2*hidden_size,label_size)。

(7)线性层再经过一个Linear Layer线性层,就是讲一个维度映射到另一个维度上。这里将维度变为(hidden_size/2,label_size)。因为2*hidden_size比较大一般,直接降到1维会丢到很多信息。所以需要两个线性层。

(8)线性层再经过一个Linear Layer线性层,维度变为(1,label_size)。(9)Softmax化:之后经过Softmax层,概率化,也叫归一化。

(10)选最大值下标选出最大值的下标,即为idx_pred,这个就是预测的结果的数字,如果想看到具体分类,需要通过label字典转换。

(11)求损失并更新参数最后将这个预测结果idx_pred和真实的label作为参数给交叉熵损失函数,损失函数反向传播梯度,更新参数。

上述流程图为

biLSTM神经网络搭建

简单的来说,该神经网络总结为post和response先分别经过Embedding层;然后进行dropout;之后将其结果放入biLSTM里,获得输出;然后将该输出concat到一起;再经过pooling层;最后经过线性层映射到分类上即可。

注:其中最后过线性层之前的数据有些庞大,大概有百个数值,直接映射3分类上,会使得数据损失的信息较大。所以这里采用两次经过线性层,中间用了一个激活函数进行非线性变换。

网络代码初始化

网络数据流动

训练的整体流程

一些因素对F1值的影响

如果还没了解F1值的话,这里有我之前写的通俗易懂的文章

详谈P(查准率),R(查全率),F1值

通过控制变量法,对以下因素进行测试:

1.词向量维度,embed_size即Word Embedding size,词被映射到的向量空间的大小

2.因为神经网路要学习到训练文本的每一个细节,这样会导致在文本数量很多的时候,出现过拟合现象。为了避免这样的现象,本文调参采用了dropout方法。Dropout使网络的部分连接部分节点的权重为0,导致该节点失活,从而达到防止过拟合的效果。设置每层神经网络不失活节点比例为x,则dropout=x。将dropout层加入到Embedding层和biLSTM层,防止两者过拟合。

3.隐层里参数的个数即hidden_size。hidden_size越大,训练的精度越高,但是也就会越容易过拟合。所以这些也需要通过调参来选择最好的参数。

4.批处理的大小batch_size,这里表示一批性处理多少训练语料。不同数据量的batch大小不同,batch越大GPU训练速度越快,但是精度可能会降低,所以需要通过调参来决定具体选择的大小为多少。

5.隐藏层的数量hidden_num,数量越大,训练速度越慢,一般很有可能出现过拟合现象。在简单的网络中,一般隐藏层数为1即可,但是也要看看层数为2的效果,不好的话,就用1层隐藏层。所以,这里需要通过调参获得。

6.权重衰退weight_decay,为了防止过拟合,在原本损失函数的基础上,加上L2正则化,而weight_decay就是这个正则化的lambda参数,一般设置为1e-8,所以调参的时候调整是否使用权重衰退即可。

7.修剪梯度clip_grad,为了防止梯度爆炸(gradient explosion)。原理为:损失函数反向传播的时候,使得每个参数都有了梯度gradient,如果所有的梯度平方和sum_sq_gradient大于clip_grad,那么求出缩放因子:

scale_factor = clip_grad / sum_sq _gradient

接着改变每个gradient,使每个gradient都乘scale_factor,达到缩放的效果,使每个梯度的sum_sq_gradient都被限制在clip_grad里,来达到防止梯度爆炸的效果。通常设置为10,那么调参的内容为是否需要clip_grad机制。

8.学习率衰退lr_decay,一般设置为1e-8,公式为:

lr = lr/(1+step*lr_decay)#lr为学习率,step为当前迭代次数

因为一般情况下循环迭代次数越多的时候,学习率的步伐就应该越来越小,这样才能慢慢接近函数的极值点,。但是有时候也不一定会有效,所以这里需要通过调参来查看是否需要开启lr_decay。

9.外部词向量,即提前提前训练好的词向量,这里指word2vec。因为以前自然语言处理用的是one-hot方法进行对每个词进行编码向量化的,维度为1*字典大小,就一位是1其余位都为0,但是这样在数据量大的情况下会让计算机达到难以计算困难的情况,而且每个词都是独立存在的,之间没有计算相似度的可能性。所以Word2vec在2012年被Google提出来,目的是将文本生成词向量模型,其中包括两个模型,分别是CBOW(continous bag of words)和Skip-Gram。这两个模型分别从两个不同的角度建立词向量模型。其中CBOW是通过一个或多个单词的上下文来对这个词进行预测,而这里用的正是CBOW方法训练的词向量。

所以最终选择的参数为

实例测试

测试流程

(1)  从键盘获取post,response的文本。

(2)  然后用jieba分词器进行分词。

(3)  通过word字典将文本转换成数字序列。

(4)  使用上述最佳的模型model。

(5)  将数字化的post,response输入到model里。

(6)  得到每个种类的得分。

(7)  然后找出最大的得分的位置。

(8)  通过label字典,得到对应的立场文字描述即可。

伪代码为

测试样例

总结

本文有一些不足:

  1. 在使用外部词向量的时候,人工加入的两种标签在外部向量中是没有的,这里只能用unk表示。因为数据量太小,不能用自己的这个数据来训练词向量。

  2. 本文的精确度很低,感觉可以用attention机制等方法来提高F1值。

源代码,请点击这里获取


更多精彩内容,请关注 深度学习自然语言处理 公众号,就是下方啦!跟随小博主,每天进步一丢丢!哈哈!

基于汉语短文本对话的立场检测系统理论与实践相关推荐

  1. 巧用词语角色:基于目标自适应图的跨目标立场检测

    ©PaperWeekly 原创 · 作者|梁斌.傅勇昊 学校|哈尔滨工业大学(深圳) 研究方向|情感分析.立场识别 摘要 跨目标立场检测(cross-target stance detection)的 ...

  2. 自然语言处理之基于biLSTM的pytorch立场检测实现

    七月 上海 | 高性能计算之GPU CUDA培训 7月27-29日三天密集式学习  快速带你入门阅读全文> 正文共1468个字,15张图,预计阅读时间10分钟. LSTM理解了,biLSTM其实 ...

  3. 【论文翻译】2020.8 清华大学AI课题组——大型中文短文本对话数据集(A Large-Scale Chinese Short-Text Conversation Dataset)

    大型中文短文本对话数据集 写在前面: 研究用,原创翻译,转载请标明出处:第一次译文,之后会跟进完善.侵删.   今年暑假末,清华大学公开了大型对话数据集及预训练模型.该数据集融合各大社交媒体对话数据库 ...

  4. ChatGPT推出后,立场检测技术将如何发展?

    (ChatGPT推出后,立场检测技术将如何发展?) 简介:这篇论文主要探讨了在ChatGPT推出之后,立场检测技术可能会有哪些发展. 首先,该论文对ChatGPT进行了介绍,ChatGPT是基于GPT ...

  5. 原创 | 基于AI的智能急性颅内出血类型检测

    作者:杨毅远 本文约6400字,建议阅读10分钟 本文介绍了通过AI技术检测急性颅内出血类型方面的知识. 颅内出血(颅骨内出血)是医疗领域严重的健康问题,需要快速且经常进行密集的医学治疗.在美国,颅内 ...

  6. 无关于目标or特定于目标:简单且有效的零样本立场检测对比学习方法

    ©PaperWeekly 原创 · 作者 | 梁斌.陈子潇 单位 | 哈尔滨工业大学(深圳) 研究方向 | 情感分析.立场检测 内容简介 零样本立场检测(zero-shot stance detect ...

  7. 毕业设计 : 基于stm32的微信天气机器人 - 天气检测 环境监测 微信机器人

    0 简介 Hi,大家好,这里是三文工作室,今天向大家介绍一个 单片机项目 基于stm32的微信天气机器人 - 天气检测 环境监测 微信机器人 大家可用于 课程设计 或 毕业设计 print(" ...

  8. 基于双门限法的语音端点检测及语音分割

    voice_activity_detection Audio Split 基于双门限法的语音端点检测及语音分割 代码在我的github上voice_activity_detection 如果您觉得有一 ...

  9. 立场检测stance detection

    stance detection,可理解为"立场检测",stance即为人对个体.事物.事件所表现出的看法或者态度,如"支持.反对".stance detect ...

  10. 论文浅尝 | 利用常识知识图增强零样本和少样本立场检测

    笔记整理:张嘉芮,天津大学硕士 链接:https://aclanthology.org/2021.findings-acl.278.pd 动机 传统的数据驱动方法不适用于零样本和少样本的场景.对于人类 ...

最新文章

  1. C# GDAL 学习一
  2. 组建核心团队时的困惑
  3. 如何快速是DNS修改生效
  4. android开发岗_android应用开发
  5. C++标准pdf 分享
  6. nyoj359Delete it
  7. access开发精要(13)-货币与数字类型格式(1)
  8. 关于C#的Main(String[] args)参数输入问题
  9. [objective-c] 08 - 内存管理
  10. android layout(l, t, r, b);,服务器里的a,t,l,r,b是什么意思? Android编程中关于layout(l,t,r,b)函数的问题...
  11. MS SQL入门基础:管理触发器
  12. python导入selenium快捷键_python,_Selenium工具自动打开的浏览器和用快捷方式打开的样式不一样?,python - phpStudy...
  13. Coursera ML 逻辑回归与正则化
  14. 数学建模之数据比较与影响因素分析
  15. Burp Suite —— 验证码识别、切换IP
  16. dreamweaver php网站模板,用DreamWeaver模板工具批量制作网页
  17. 经典网页设计:20个优秀的电子商务网站设计案例
  18. 一键生成动漫头像微信小程序源码
  19. 你到底要一台什么样的笔记本
  20. 从零学习 InfiniBand-network架构(十) —— IB协议中全局ID

热门文章

  1. Excel多表头导出(.net)
  2. 解决微信浏览器无法使用reload()刷新页面
  3. thinkphp 表单令牌
  4. 使用opensl 的BufferQueueAudioPlayer对wav文件的播放
  5. 敏捷开发免费管理工具——火星人预览(四)
  6. Excel Rendering Limitations
  7. 20190928 On Java8 第二十三章 注解
  8. 20190906 On Java8 第十八章 字符串
  9. 【尚锐科技课堂】安全健康位置云平台系统
  10. 机器学习、数据分析类面经分享