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

from:http://www.zhuzongkui.top/2018/08/10/competition-summary/

问题对语义相似度计算(从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_loss0.2589950.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 之间)。
求平均的数量24789
线上提交 logloss0.1878450.1853290.1826130.1798080.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_tree0.163249(第16名)0.151729(第12名)
SKY0.141329(第1名)0.142658(第1名)
CCKS初赛成绩(138只队伍)复赛成绩(50只队伍)
我们0.85142(第24名)0.84586(第4名)
ThunderUp0.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.

其他比赛选手总结

 

 

 

 

 

 

 

 

 

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用pytorch实现BERT语义相似度计算可以分为以下几个步骤: 步骤1:准备数据 首先,要导入必要的库和模型,如torch、torchvision、transformers等。然后,加载预训练的BERT模型和Tokenizer,如BertTokenizer和BertModel。接着,将输入的文本进行分词处理,并使用Tokenizer将分词后的文本转换为BERT模型可以接受的格式。 步骤2:数据预处理 在此步骤中,要对输入的文本进行预处理。BERT模型的输入包括input_ids、attention_mask和token_type_ids。input_ids是文本的token序列,attention_mask用于标记哪些token是有效的,token_type_ids用于区分输入的文本句子对。 步骤3:加载BERT模型 使用transformers库加载预训练的BERT模型,如BertModel。然后,将预处理后的数据作为输入传入BERT模型,获取模型的输出。 步骤4:计算语义相似度 BERT模型的输出是一个包含表示文本语义信息的隐藏向量,可以使用这些向量计算语义相似度。常见的计算方式包括余弦相似度和欧氏距离等。 步骤5:评估语义相似度 为了评估语义相似度的性能,可以使用一些标准的评估指标,如Pearson相关系数、Spearman相关系数和Kendall相关系数等。 步骤6:模型训练和优化 可以使用已标注的语义相似度数据进行模型的训练,使用优化方法如反向传播算法和随机梯度下降等来优化模型的参数。 步骤7:模型应用 完成模型的训练后,可以将其应用于实际的语义相似度计算任务中。通过输入两个文本,经过预处理和BERT模型的计算,可以得到它们之间的语义相似度分数。 上述是使用pytorch实现BERT语义相似度计算的主要步骤,具体的实现细节可以根据具体情况和求进行调整和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值