句子对匹配(Sentence Pair Matching)问题是NLP中非常常见的一类问题,所谓“句子对匹配”,就是说给定两个句子S1和S2,任务目标是判断这两个句子是否具备某种类型的关系。如果形式化地对这个问题定义,可以理解如下:

意思是给定两个句子,需要学习一个映射函数,输入是两个句子对,经过映射函数变换,输出是任务分类标签集合中的某类标签。

典型的例子就是Paraphrase任务,即要判断两个句子是否语义等价,所以它的分类标签集合就是个{等价,不等价}的二值集合。除此外,还有很多其它类型的任务都属于句子对匹配,比如问答系统中相似问题匹配和Answer Selection。

我在前一篇文章中写了一个基于Doc2vec和Word2vec的无监督句子匹配方法,这里就顺便用传统的机器学习算法做一下。用机器学习算法处理的话,这里的映射函数就是用训练一个分类模型来拟合F,当分类模型训练好之后,对于未待分类的数据,就可以输入分类模型,用训练好的分类模型进行预测直接输出结果。

关于分类算法:

常见的分类模型有逻辑回归(LR)、朴素贝叶斯、SVM、GBDT和随机森林(RandomForest)等。本文选用的机器学习分类算法有:逻辑回归(LR)、SVM、GBDT和随机森林(RandomForest)。

由于Sklearn中集成了常见的机器学习算法,包括分类、回归、聚类等,所以本文使用的是Sklearn,版本是0.17.1。

关于特征选择:

由于最近一直在使用doc2vec和Word2vec,而且上篇文章中对比结果表示,用Doc2vec得到句子向量表示比Word2vec求均值得到句子向量表示要好,所以这里使用doc2vec得到句子的向量表示,向量维数为100维,直接将句子的100维doc2vec向量作为特征输入分类算法。

关于数据集:

数据集使用的是Quora发布的Question Pairs语义等价数据集,和上文是同一个数据集,可以点击这个链接下载点击打开链接,其中包含了40多万对标注好的问题对,如果两个问题语义等价,则label为1,否则为0。统计之后,共有53万多个问题。具体格式如下图所示:

统计出所有的问题之后训练得到每一个问题的doc2vec向量,作为分类算法的特征输入。

将语料库随机打乱之后,切分出10000对数据作为验证集,剩余的作为训练集。

下面是具体的训练代码:

数据加载和得到句子的doc2vec代码是同一份,放在前面:

  1. # coding:utf-8

  2. import numpy as np

  3. import csv

  4. import datetime

  5. from sklearn.ensemble import RandomForestClassifier

  6. import os

  7. import pandas as pd

  8. from sklearn import metrics, feature_extraction

  9. from sklearn.feature_extraction.text import TfidfTransformer, CountVectorizer

  10. cwd = os.getcwd()

  11. def load_data(datapath):

  12. data_train = pd.read_csv(datapath, sep='\t', encoding='utf-8')

  13. print data_train.shape

  14. qid1 = []

  15. qid2 = []

  16. question1 = []

  17. question2 = []

  18. labels = []

  19. count = 0

  20. for idx in range(data_train.id.shape[0]):

  21. # for idx in range(400):

  22. # count += 1

  23. # if count == 21: break

  24. print idx

  25. q1 = data_train.qid1[idx]

  26. q2 = data_train.qid2[idx]

  27. qid1.append(q1)

  28. qid2.append(q2)

  29. question1.append(data_train.question1[idx])

  30. question2.append(data_train.question2[idx])

  31. labels.append(data_train.is_duplicate[idx])

  32. return qid1, qid2, question1, question2, labels

  33. def load_doc2vec(word2vecpath):

  34. f = open(word2vecpath)

  35. embeddings_index = {}

  36. count = 0

  37. for line in f:

  38. # count += 1

  39. # if count == 10000: break

  40. values = line.split('\t')

  41. id = values[0]

  42. print id

  43. coefs = np.asarray(values[1].split(), dtype='float32')

  44. embeddings_index[int(id)+1] = coefs

  45. f.close()

  46. print('Total %s word vectors.' % len(embeddings_index))

  47. return embeddings_index

  48. def sentence_represention(qid, embeddings_index):

  49. vectors = np.zeros((len(qid), 100))

  50. for i in range(len(qid)):

  51. print i

  52. vectors[i] = embeddings_index.get(qid[i])

  53. return vectors

将main函数中的数据集路径和doc2vec路径换成自己的之后就可以直接使用了。

1.逻辑回归(LR):

  1. def main():

  2. start = datetime.datetime.now()

  3. datapath = 'D:/dataset/quora/quora_duplicate_questions_Chinese_seg.tsv'

  4. doc2vecpath = "D:/dataset/quora/vector2/quora_duplicate_question_doc2vec_100.vector"

  5. qid1, qid2, labels = load_data(datapath)

  6. embeddings_index = load_doc2vec(word2vecpath=doc2vecpath)

  7. vectors1 = sentence_represention(qid1, embeddings_index)

  8. vectors2 = sentence_represention(qid2, embeddings_index)

  9. vectors = np.hstack((vectors1, vectors2))

  10. labels = np.array(labels)

  11. VALIDATION_SPLIT = 10000

  12. VALIDATION_SPLIT0 = 1000

  13. indices = np.arange(vectors.shape[0])

  14. np.random.shuffle(indices)

  15. vectors = vectors[indices]

  16. labels = labels[indices]

  17. train_vectors = vectors[:-VALIDATION_SPLIT]

  18. train_labels = labels[:-VALIDATION_SPLIT]

  19. test_vectors = vectors[-VALIDATION_SPLIT:]

  20. test_labels = labels[-VALIDATION_SPLIT:]

  21. # train_vectors = vectors[:VALIDATION_SPLIT0]

  22. # train_labels = labels[:VALIDATION_SPLIT0]

  23. # test_vectors = vectors[-VALIDATION_SPLIT0:]

  24. # test_labels = labels[-VALIDATION_SPLIT0:]

  25. lr = LogisticRegression()

  26. print '***********************training************************'

  27. lr.fit(train_vectors, train_labels)

  28. print '***********************predict*************************'

  29. prediction = lr.predict(test_vectors)

  30. accuracy = metrics.accuracy_score(test_labels, prediction)

  31. print accuracy

  32. end = datetime.datetime.now()

  33. print end-start

  34. if __name__ == '__main__':

  35. main() # the whole one model

2.SVM:

  1. def main():

  2. start = datetime.datetime.now()

  3. datapath = 'D:/dataset/quora/quora_duplicate_questions_Chinese_seg.tsv'

  4. doc2vecpath = "D:/dataset/quora/vector2/quora_duplicate_question_doc2vec_100.vector"

  5. qid1, qid2, labels = load_data(datapath)

  6. embeddings_index = load_doc2vec(word2vecpath=doc2vecpath)

  7. vectors1 = sentence_represention(qid1, embeddings_index)

  8. vectors2 = sentence_represention(qid2, embeddings_index)

  9. vectors = np.hstack((vectors1, vectors2))

  10. labels = np.array(labels)

  11. VALIDATION_SPLIT = 10000

  12. VALIDATION_SPLIT0 = 1000

  13. indices = np.arange(vectors.shape[0])

  14. np.random.shuffle(indices)

  15. vectors = vectors[indices]

  16. labels = labels[indices]

  17. train_vectors = vectors[:-VALIDATION_SPLIT]

  18. train_labels = labels[:-VALIDATION_SPLIT]

  19. test_vectors = vectors[-VALIDATION_SPLIT:]

  20. test_labels = labels[-VALIDATION_SPLIT:]

  21. # train_vectors = vectors[:VALIDATION_SPLIT0]

  22. # train_labels = labels[:VALIDATION_SPLIT0]

  23. # test_vectors = vectors[-VALIDATION_SPLIT0:]

  24. # test_labels = labels[-VALIDATION_SPLIT0:]

  25. svm = SVC()

  26. print '***********************training************************'

  27. svm.fit(train_vectors, train_labels)

  28. print '***********************predict*************************'

  29. prediction = svm.predict(test_vectors)

  30. accuracy = metrics.accuracy_score(test_labels, prediction)

  31. print accuracy

  32. end = datetime.datetime.now()

  33. print end-start

  34. if __name__ == '__main__':

  35. main() # the whole one model

3.GBDT:

  1. def main():

  2. start = datetime.datetime.now()

  3. datapath = 'D:/dataset/quora/quora_duplicate_questions_Chinese_seg.tsv'

  4. doc2vecpath = "D:/dataset/quora/vector2/quora_duplicate_question_doc2vec_100.vector"

  5. qid1, qid2, labels = load_data(datapath)

  6. embeddings_index = load_doc2vec(word2vecpath=doc2vecpath)

  7. vectors1 = sentence_represention(qid1, embeddings_index)

  8. vectors2 = sentence_represention(qid2, embeddings_index)

  9. vectors = np.hstack((vectors1, vectors2))

  10. labels = np.array(labels)

  11. VALIDATION_SPLIT = 10000

  12. VALIDATION_SPLIT0 = 1000

  13. indices = np.arange(vectors.shape[0])

  14. np.random.shuffle(indices)

  15. vectors = vectors[indices]

  16. labels = labels[indices]

  17. train_vectors = vectors[:-VALIDATION_SPLIT]

  18. train_labels = labels[:-VALIDATION_SPLIT]

  19. test_vectors = vectors[-VALIDATION_SPLIT:]

  20. test_labels = labels[-VALIDATION_SPLIT:]

  21. # train_vectors = vectors[:VALIDATION_SPLIT0]

  22. # train_labels = labels[:VALIDATION_SPLIT0]

  23. # test_vectors = vectors[-VALIDATION_SPLIT0:]

  24. # test_labels = labels[-VALIDATION_SPLIT0:]

  25. gbdt = GradientBoostingClassifier(init=None, learning_rate=0.1, loss='deviance',

  26. max_depth=3, max_features=None, max_leaf_nodes=None,

  27. min_samples_leaf=1, min_samples_split=2,

  28. min_weight_fraction_leaf=0.0, n_estimators=100,

  29. random_state=None, subsample=1.0, verbose=0,

  30. warm_start=False)

  31. print '***********************training************************'

  32. gbdt.fit(train_vectors, train_labels)

  33. print '***********************predict*************************'

  34. prediction = gbdt.predict(test_vectors)

  35. accuracy = metrics.accuracy_score(test_labels, prediction)

  36. acc = gbdt.score(test_vectors, test_labels)

  37. print accuracy

  38. print acc

  39. end = datetime.datetime.now()

  40. print end-start

  41. if __name__ == '__main__':

  42. main() # the whole one model

4.随机森林(RandomForest):

  1. def main():

  2. start = datetime.datetime.now()

  3. datapath = 'D:/dataset/quora/quora_duplicate_questions_Chinese_seg.tsv'

  4. doc2vecpath = "D:/dataset/quora/vector2/quora_duplicate_question_doc2vec_100.vector"

  5. qid1, qid2, question1, question2, labels = load_data(datapath)

  6. embeddings_index = load_doc2vec(word2vecpath=doc2vecpath)

  7. vectors1 = sentence_represention(qid1, embeddings_index)

  8. vectors2 = sentence_represention(qid2, embeddings_index)

  9. vectors = np.hstack((vectors1, vectors2))

  10. labels = np.array(labels)

  11. VALIDATION_SPLIT = 10000

  12. VALIDATION_SPLIT0 = 1000

  13. indices = np.arange(vectors.shape[0])

  14. np.random.shuffle(indices)

  15. vectors = vectors[indices]

  16. labels = labels[indices]

  17. train_vectors = vectors[:-VALIDATION_SPLIT]

  18. train_labels = labels[:-VALIDATION_SPLIT]

  19. test_vectors = vectors[-VALIDATION_SPLIT:]

  20. test_labels = labels[-VALIDATION_SPLIT:]

  21. # train_vectors = vectors[:VALIDATION_SPLIT0]

  22. # train_labels = labels[:VALIDATION_SPLIT0]

  23. # test_vectors = vectors[-VALIDATION_SPLIT0:]

  24. # test_labels = labels[-VALIDATION_SPLIT0:]

  25. randomforest = RandomForestClassifier()

  26. print '***********************training************************'

  27. randomforest.fit(train_vectors, train_labels)

  28. print '***********************predict*************************'

  29. prediction = randomforest.predict(test_vectors)

  30. accuracy = metrics.accuracy_score(test_labels, prediction)

  31. print accuracy

  32. end = datetime.datetime.now()

  33. print end-start

  34. if __name__ == '__main__':

  35. main() # the whole one model

最终的结果如下:

LR 68.56%

SVM 69.77%

GBDT 71.4%

RandomForest 78.36%(跑了多次,最好的一次)

从准确率上来看,随机森林的效果最好。时间上面,SVM耗时最长。

未来:

其实本文在特征选择和分类算法的参数调整上还有很多可以深入的地方,我相信,通过继续挖掘更多的有用特征,以及对模型的参数进行调整还可以得到更好的结果。

详细代码参见我的GitHub,地址为:点击打开链接

深度学习笔记——基于传统机器学习算法(LR、SVM、GBDT、RandomForest)的句子对匹配方法相关推荐

  1. 吴恩达深度学习笔记——结构化机器学习项目(Structuring Machine Learning Projects)

    深度学习笔记导航 前言 传送门 结构化机器学习项目(Machine Learning Strategy) 机器学习策略概述 正交化(orthogonalization) 评价指标 数字评估指标的单一性 ...

  2. Opencv学习笔记 - OpenCV 4机器学习算法简介

    在机器学习中,一些比较流行方法的包括:支持向量机(SVM).人工神经网络(ANN).聚类.k-最近邻.决策树和深度学习.OpenCV支持并实现几乎所有这些方法,并有详细的文档说明(包含在Main mo ...

  3. 吴恩达深度学习笔记6-Course2-Week2【优化算法】

    优化算法 一.Mini-batch gradient descent(小批量梯度下降法) Mini-batch: 把整个训练数据集分成若干个小的训练集,即为Mini-batch. 为什么要分?梯度下降 ...

  4. 深度学习笔记--基于Pytorch搭建VGG16网络

    目录 1--VGG16网络 2--代码实现 3--参考 1--VGG16网络 具体原理参考 VGG 网络的原论文:VGG原论文 VGG 16 网络结构如下图所示: VGG 16 网络的实现流程如下图所 ...

  5. AI Studio 飞桨 零基础入门深度学习笔记1-深度学习的定义

    AI Studio 飞桨 零基础入门深度学习-笔记 人工智能.机器学习.深度学习的关系 机器学习 机器学习的实现 机器学习的方法论 案例:牛顿第二定律 确定模型参数 模型结构介绍 深度学习 神经网络的 ...

  6. 深度学习笔记之《解析卷积神经网络》附下载地址

    点击上方"Datawhale",选择"星标"公众号 第一时间获取价值内容 <解析卷积神经网络>是 @魏秀参 博士撰写的深度学习实践手册,主要以卷积神 ...

  7. 文献阅读笔记:基于深度学习的桥梁裂缝检测算法研究

    论文 | 基于深度学习的桥梁裂缝检测算法研究 作者 | 李良福.马卫飞.李 丽.陆 铖 期刊 | 自动化学报 时间 | 2019年9月 论文目的: 传统的图像处理算法不能很好地对桥梁裂缝进行检测 , ...

  8. 【深度学习】基于区域生长的图像分割算法!

    图像分割的目的是将图像划分为多个不同的区域,所以我们可以直接从寻找图像中的区域来设计分割算法.区域生长正是一种基于区域寻找的传统图像分割算法. 区域生长基本原理 区域生长(Region Growth) ...

  9. 《深度学习入门——基于Python的理论与实现》笔记

    PS:写这篇博客主要是记录下自己认为重要的部分以及阅读中遇到的些问题,加深自己的印象. 附上电子书及源代码: 链接:https://pan.baidu.com/s/1f2VFcnXSSK-u3wuvg ...

最新文章

  1. ATS 5.3.0命令行工具traffic_via
  2. java遍历集合元素_遍历java集合元素的方法
  3. mac电脑php中安装swoole扩展件
  4. 从MySQL得到最大的性能
  5. python_day24_class_类_继承
  6. java多线程-基础知识
  7. 防止各大网盘下载限速解决方案--idman
  8. TCP客户端和服务端
  9. 读书笔记-计算机视觉
  10. Windows Server 2012 R2 更改系统语言
  11. 神州优车拟41亿元收购宝沃汽车67%股权 1
  12. 大地测量——计算七参数(编程作业)
  13. Go实战--golang中获取公网ip、查看内网ip、检测ip类型、校验ip区间、ip地址string和int转换、根据ip判断地区国家运营商等
  14. 梅姨一定想不到 中国人最爱的英国货竟然是一本童书
  15. 云计算/大数据/Hadoop2.0/MongoDB/数据挖掘分析/视频教程
  16. 2----Android手机小白知识全集!! 刚入手
  17. 在线MySQL,SQL Server建表语句生成JSON测试数据工具
  18. 如何在Mac上删除iPhone和iPad iCloud备份?
  19. C语言实现小球落地问题
  20. Latex参考文献引用出现“?”

热门文章

  1. 无法查找网络工作组计算机,XP系统弹出“无法查看工作组计算机”提示怎么办?...
  2. Java文本框只有一行数据,Java只允许输入数目字的文本框
  3. 写微博picgp图床安装与问题解决(看这一篇就可以了)
  4. 独占一行 html_HTML基础-语义化标签
  5. 语言设计谁年龄大_这桌子谁设计的?脑洞够大,除能360°翻转,打台球,乒乓球都行...
  6. python爬虫导入数据库_python爬虫爬下来的数据怎么导入到MySQL
  7. c代码实现 ifft运算_fft算法c语言_matlab fft算法_ifft c语言
  8. 液晶弹性自由能计算_自由能方法应用(一)开放计算平台BRIDGE的介绍及使用案例...
  9. 附件文件无法保存到服务器,可能是目录属性设置问题,请与管理员联系,Discuz不能上传过大文件的解决办法...
  10. 底部分页栏_2020年执业药师考试教材各科目增加页数!最多203页