问题对语义相似度计算-参赛总结

  • 时间段:2018.06.10~2018.07.20

问题对语义相似度计算(从0到0.5+)

  • 短短一个多月的时间,我学到了很多很多东西,从一个呆头小白初长成人。
  • 首先,必须感谢我的导师能给我这个机会从头到尾完整地参加这次比赛,至始至终地为我们出谋划策,和我们探讨问题并答疑解惑,而且提供了各种宝贵的学习资料和服务器资源。
  • 另外,也要特别感谢我的师兄一路无微不至的提点和帮助,和我一起找方法、看论文、搭模型、改代码,其实我们是从同一个起跑线开始的,到最后被师兄甩了好几条街 T_T。
  • 虽然,比赛期间遇到了很多挫折,刚开始我们真的是一头雾水、无从下手,面对参加同样比赛的其他优秀选手(“老油条”)心里还是蛮慌的,好在勤能补拙,有团队配合,能够齐心协力、互相帮助,最终比赛的结果还算令人满意。

一、相关比赛

1
2
3
任务:语句匹配问题、语义等价判别、语义等价判定、等价;(语句的意图匹配)
输入:一个语句对
输出:一个数值(0-1之间),表明该语句对的相似程度

二、数据形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
魔镜杯:脱敏数据,所有原始文本信息都被编码成单字ID序列和词语ID序列。
label,q1,q2
1,Q397345,Q538594
0,Q193805,Q699273
0,Q085471,Q676160
... ...

CCKS:中文的真实客服语料。
用微信都6年,微信没有微粒贷功能 4。 号码来微粒贷 0
微信消费算吗 还有多少钱没还 0
交易密码忘记了找回密码绑定的手机卡也掉了 怎么最近安全老是要改密码呢好麻烦 0
... ...

蚂蚁:蚂蚁金服金融大脑的实际应用场景。
1 怎么更改花呗手机号码 我的花呗是以前的手机号码,怎么更改成现在的支付宝的号码手机号 1
2 也开不了花呗,就这样了?完事了 真的嘛?就是花呗付款 0
3 花呗冻结以后还能开通吗 我的条件可以开通花呗借款吗 0
... ...

三、解决方案

(1)问题分析

  • 预测问题对的相似程度,即判别问题对是属于类别1还是类别0,很明显这是一个NLP领域的分类问题,然而区别于传统的文本分类问题:
区别 传统文本分类 问题对相似度计算
输入 只有一个输入 有两个输入
句子长度 文本较长 句子长短不一、且较简短
特征 文本特征 语义特征
。。。 。。。 。。。

(2)数据分析

  • 1、正负样本比例接近于 1:1;
  • 2、相似的句子之间一般都会含有公共词/字符;也会出现包含很多公共词/字符,但句子主语不一样导致两个句子不相似的情况;
  • 3、比赛的数据是没有经过预处理的(去停用词、繁体转简体、清洗);另外数据中也存在很多脏数据(标注有误、错别字、漏字、简写),也很容易导致分词错误;
  • 4、预训练的词向量数据(除非比赛方提供,否则还需要跟领域相关的语料来进行训练);

(3)分类模型

其实我们之前是没有接触过这种类型的比赛的,也没有很多参赛的经验,而是刚刚从零学起,一步一步地摸索,沿着前人的脚步再延伸。

  • 1、比赛方(魔镜杯)Demo:两个句子拼成一个文本,空格连接,以 tfidf 为特征,做逻辑回归;(研究官方Demo时发现代码里有bug:最后提交的是预测为0的概率,实际应该是1)
  • 2、借鉴官方Demo,两个句子拼接,使用传统CNN做文本分类,准确率 80% 左右;经测试q1和q2两个句子分开单独处理后再合并做分类效果是明显好于q1和q2先合并再处理后做分类的;
q1、q2 分开单独处理 共享卷积层 不共享卷积层
log_loss 0.258995 0.28949

最终单模型的最好效果:log_loss = 0.205189

比赛期间,我实现或者在实现的基础上改进前前后后大概搭建了20多个模型,其实很多模型都还有很大的提升空间,局限于比赛的时间和自己的知识能力,而且在模型的细微之处、参数的初始化以及调参方面自己都没有什么经验,以致自己实现的模型的效果都没有师兄的好 (;へ:)。
虽然我们没能进入拍拍贷“魔镜杯”比赛的决赛,但在导师的帮助和特殊关系下,我们也有幸了参加了 top10 选手精彩的决赛答辩(2018-7-24 09:00),真的受益匪浅。

(4)模型调参

  • 1、拍拍贷一同比赛的某位优秀选手(初赛第16名, 复赛第12名)分享的博客 智能客服问题相似度算法设计——第三届魔镜杯大赛第12名解决方案
  • 2、其实,很多参数我自己设置的都是默认参数,具体没有做很多的微调:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    embedding_dim = 300         # 词向量的维度
    seq_length = 25 # 文本的最大长度
    filter_sizes = [3] # 卷积核尺寸列表
    num_classes = 2 # 类别数

    is_pre_train = True # 是否为训练好的词向量
    is_trainable = True # 动态/静态词向量

    num_filters = 300 # 卷积核数目
    rnn_num_layers = 2 # LSTM 隐藏层的个数
    attention_size = 300 # Attention 层的大小
    rnn_hidden_size = 300 # LSTM 隐藏层的大小
    dropout_keep_prob = 0.5 # dropout 保留比例
    learning_rate = 1e-3 # 学习率(设置自动衰减)
    batch_size = 128 # 每批训练的大小
  • 3、参数初始化:跟上面博客里分享的一样,TensorFlow里面参数初始化不同,对结果的影响非常大,师兄推荐也是使用 Xavier 初始化;原本想用keras再实现一遍的,一方面不太熟悉,另一方面由于时间紧迫未能完成。

  • 4、决赛答辩里,我们了解到很多选手并没有使用官方给定词级和字符级的词向量(不知道训练方法、参数、模型等),都自己训练了两种词向量(word2vec、glove);另外也有用 w_vector * w_tfidf 作为 w 的词向量。
  • 5、重点关注字向量:由于中文分词难度较大,特别是不同领域内的领域分词没有很好的解决方案(比赛数据为金融领域数据源),而且实验的效果也表明词级别是好于字级别的。
  • 6、BatchNormalization + Spatial Dropout 1D

(5)特征工程

1、人工设计特征这部分是我们团队中来也公司的几个小伙伴做的, 他们参考并设计了很多有趣的特征。

2、其他选手

  • 计算QA pair的几种相似度:编辑距离、马氏距离、闵可夫斯基距离、WMD
  • 使用 SVD、NMF对句中词向量降维
  • 根据共现图,统计节点的degree,得到了两个比较强的特征:coo_q1_q2_degree_diff(问题1和问题2的degree的差异)、coo_max_degree(问题对最大的degree,进一步离散化做1-hot又得到3个特征)
  • 问题对公共邻居的数量/比例
  • 第一名:提取问题出入度、pagerank等特征;问题出现的次数以及频繁程度特征;将所有已知的问题构建同义问题集。问题集的构建不参与训练,只用于数据增强;

3、数据增强

  • 第一名的方法
    1
    2
    3
    4
    5
    6
    假设 Q1 在所有样本里出现2次,分别是
    1,Q1,Q2
    1,Q3,Q1
    模型无法正确学习Q1与Q2/Q3的相同,而是会认为只要input里有Q1即为正样本。
    需要通过数据处理引导模型进行“比较”,而不是“拟合”。
    解决方案:通过构建一部分补充集(负例),对冲所有不平衡的问题。

4、后处理

  • 传递关系
    • 相似:(AB=1,AC=1)—> BC=1
    • 不相似:(AB=1,AC=0)—> BC=0
  • 第一名的方法:infer机制:除了判断test集的每个样本得分以外,还会通过已知同义问题集的其他样本比对进行加权;融合时轻微降低得分过高的模型权重,补偿正样本过多的影响;将已知确认的样本修正为0/1。

比别人差的一个重要原因:传递关系没有考虑到闭包!我们大概推了1253条,然而别人正例推了12568个样本,负例推了5129个样本。 ╥﹏╥

(6)模型融合

  • 1、多模型的融合最常用的一个方法就是求平均,我使用这个方法后 logloss 有很大的提升(加权平均的几个结果都是线上提交后 logloss 在 0.205189~0.209739 之间)。
求平均的数量 2 4 7 8 9
线上提交 logloss 0.187845 0.185329 0.182613 0.179808 0.179063
  • 2、同一个模型提升效果的常用方法就是多折交叉验证求平均,由于我们组内 GPU 服务器有限,这个就由模型效果比较好的师兄来完成了,而且提升也是非常明显的。
  • 3、另外,也用了堆叠和混合(stacking与blending)。
    • 每个模型 word level(官方词向量)
    • 每个模型 word level(word2vec)
    • 每个模型 word level(glove)
    • 每个模型 char level(官方字向量)
    • 每个模型 char level(word2vec)
    • 每个模型 char level(glove)
  • 4、kaggle比赛集成指南
  • 5、模型微调(Finetune)
    • 第一名的方法:gensim训练词向量;模型使用non_trainable词向量进行训练;将除了embedding的layer全部freeze,用低学习率finetune词向量层。
小 trick 贡献度
多模型的预测结果求平均 logloss 降低 2.6 个百分点
同一个模型10折交叉验证 logloss 降低 2 个 百分点
传递关系推导 logloss 降低 3.1 个千分点

四、比赛总结

  • 1、比赛成绩(logloss / F1)
拍拍贷 初赛成绩(359只队伍) 复赛成绩(95只队伍)
我们 0.166100(第22名) 0.162495(第21名)
moka_tree 0.163249(第16名) 0.151729(第12名)
SKY 0.141329(第1名) 0.142658(第1名)
CCKS 初赛成绩(138只队伍) 复赛成绩(50只队伍)
我们 0.85142(第24名) 0.84586(第4名)
ThunderUp 0.86485(第1名) 0.85131(第1名)
  • 2、经验体会
    • 刚开始,我们都是尝试各种模型,不知道哪一个好,在这个上面花了不少时间,其实从平时就应该开始积累,关注最新研究、最新模型,多看一下论坛、kaggle、quora、github、和NLP相关的公众号等。
    • 一定要从数据本身上做探索,研究各种特征,因为到比赛后期模型基本都相似了,很难再有更大的提升;从决赛答辩来看,前10的选手在数据特征上都下了非常大的功夫,比如图特征等。
    • 一定要做交叉验证,求平均。比赛方提供的训练集如果只用了 0.9 的数据来训练模型,那么模型很大程度会丢失剩下的 0.1 的信息,如果做了交叉验证的话,就可以兼顾到所有训练集的特征信息。
    • 从比赛角度讲,深度学习框架 keras 是好于 TensorFlow 的,因为 keras 一般在参数调试、参数初始化以及模型搭建上面都整合的非常好;从科研角度讲,Tensorflow 具有清晰的流程,可以帮助你更好的理解深度学习的完整过程。
    • 到了比赛后期,多模型的融合一定会有帮助,因为这样可以结合不同的模型的优缺点;模型融合最简单的方法是就是求平均,再复杂点就是对不同的模型依据效果的好坏赋予不同的权重在加权求和。
    • 之前一直很纳闷人工设计的传统特征是怎样可以和深度学习模型相结合的,通过这次比赛,我也学习到了很多传统的NLP模型(xgboost、lightgbm、随机森林、极端随机树等),设计的特征可以加入到最后一层MLP层进行训练。
    • 一定要有团队配合,“三个臭皮匠,顶个诸葛亮”,“1+1>2”,真的真的可以从别人身上学习到很多很多的东西。
    • 一定要多看论文、多写代码,多请教师兄、导师,“纸上得来终觉浅,绝知此事要躬行。”,“冰冻三尺,非一日之寒。”,调参经验、模型的搭建很多都是来自平时的积累、练习。
    • 作为一个小白,一定要比别人花更多的时间和努力,才能笨鸟先飞、勤能补拙。
    • 再忙再累也要多运动、多锻炼,身体是革命的本钱,一定要爱惜身体,督促自己,实验室固然安逸,但整天坐着身体的机能肯定会下降,发际线正在颤抖。
    • “路漫漫其修远兮,我将上下而求索。”

五、参考文献

  • [1] Huang P S, He X, Gao J, et al. Learning deep structured semantic models for web search using clickthrough data[C]// ACM International Conference on Conference on Information & Knowledge Management. ACM, 2013:2333-2338.
  • [2] Lan W, Xu W. Neural Network Models for Paraphrase Identification, Semantic Textual Similarity, Natural Language Inference, and Question Answering[J]. 2018.
  • [3] Wang Z, Hamza W, Florian R. Bilateral Multi-Perspective Matching for Natural Language Sentences[J]. 2017.
  • [4] Ghaeini R, Hasan S A, Datla V, et al. DR-BiLSTM: Dependent Reading Bidirectional LSTM for Natural Language Inference[J]. 2018.

其他比赛选手总结

坚持原创技术分享,您的支持将鼓励我继续创作!
0%