python 文本相似度计算函数_四种计算文本相似度的方法对比
作者:Yves Peirsman
编译:Bing
编者按:本文作者为Yves Peirsman,是NLP领域的专家。在这篇博文中,作者比较了各种计算句子相似度的方法,并了解它们是如何操作的。词嵌入(word embeddings)已经在自然语言处理领域广泛使用,它可以让我们轻易地计算两个词语之间的语义相似性,或者找出与目标词语最相似的词语。然而,人们关注更多的是两个句子或者短文之间的相似度。如果你对代码感兴趣,文中附有讲解细节的Jupyter Notebook地址。以下是论智的编译。
许多NLP应用需要计算两段短文之间的相似性。例如,搜索引擎需要建模,估计一份文本与提问问题之间的关联度,其中涉及到的并不只是看文字是否有重叠。与之相似的,类似Quora之类的问答网站也有这项需求,他们需要判断某一问题是否之前已出现过。要判断这类的文本相似性,首先要对两个短文本进行embedding,然后计算二者之间的余弦相似度(cosine similarity)。尽管word2vec和GloVe等词嵌入已经成为寻找单词间语义相似度的标准方法,但是对于句子嵌入应如何倍计算仍存在不同的声音。接下来,我们将回顾一下几种最常用的方法,并比较它们之间的性能。
数据
我们将在两个被广泛使用的数据集上测试所有相似度计算方法,同时还与人类的判断作对比。两个数据集分别是:
STS基准 收集了2012年至2017年国际语义评测SemEval中所有的英语数据
SICK数据库 包含了10000对英语句子,其中的标签说明了它们之间的语义关联和逻辑关系
下面的表格是STS数据集中的几个例子。可以看到,两句话之间的语义关系通常非常微小。例如第四个例子:
A man is playing a harp.
通过判断,两句话之间“非常不相似”,尽管它们的句法结构相同,并且其中的词嵌入也类似。
STS数据集中的例子
相似度检测方法
用于计算两句子间语义相似度的方法非常广泛,下面是常见的几种方法。
基准方法
估计两句子间语义相似度最简单的方法就是求句子中所有单词词嵌入的平均值,然后计算两句子词嵌入之间的余弦相似性。很显然,这种简单的基准方法会带来很多变数。我们将研究,如果忽略终止词并用TF-IDF计算平均权重会带来怎样的影响。
词移距离
两文本之间的词移距离指的是文本一种中所有单词与文本二中的单词之间最小累计距离
替代上述基准方法的其中一种有趣方法就是词移距离(Word Mover’s Distance)。词移距离使用两文本间的词嵌入,测量其中一文本中的单词在语义空间中移动到另一文本单词所需要的最短距离。
Smooth Inverse Frequency
从语义上来讲,求一句话中词嵌入的平均值似乎给与不相关的单词太多权重了。而Smooth Inverse Frequency试着用两种方法解决这一问题:
加权:就像上文用的TF-IDF,SIF取句中词嵌入的平均权重。每个词嵌入都由a/(a + p(w))进行加权,其中a的值经常被设置为0.01,而p(w)是词语在语料中预计出现的频率。
常见元素删除:接下来,SIF计算了句子的嵌入中最重要的元素。然后它减去这些句子嵌入中的主要成分。这就可以删除与频率和句法有关的变量,他们和语义的联系不大。
最后,SIF使一些不重要的词语的权重下降,例如but、just等,同时保留对语义贡献较大的信息。
预训练编码器
上述两种方法都有两个重要的特征。首先,作为简单的词袋方法,它们并不考虑单词的顺序。其次,它们使用的词嵌入是在一种无监督方法中学习到的。这两种特点都有潜在的威胁。由于不同的词语顺序会有不同的意思(例如“the dog bites the man”和“the man bites the dog”),我们想让句子的嵌入对这一变化有所反馈。另外,监督训练可以更直接地帮助句子嵌入学习到句意。
于是就出现了预训练编码器。预训练的句子编码器的目的是充当word2vec和GloVe的作用,但是对于句子嵌入来说:它们生成的嵌入可以用在多种应用中,例如文本分类、近似文本检测等等。一般来说,编码器在许多监督和非监督的任务中训练,目的就是能尽量多地获取通用语义信息。目前已经有好几款这样的编码器了,我们以InferSent和谷歌语句编码器为例。
预训练句子编码器以来自然语言推理等任务,来学习句子嵌入,以便用于今后的迁移任务中
InferSent是由Facebook研发的预训练编码器,它是一个拥有最大池化的BiLSTM,在SNLI数据集上训练,该数据集含有57万英语句子对,所有句子都属于三个类别的其中一种:推导关系、矛盾关系、中立关系。
为了与Facebook竞争,谷歌也推出了自己的语句编码器,它有两种形式:
其中一种高级模型,采用的是变换过的模型编码子图生成的语境感知词所表示的元素总和。
另一种是简单一些的深度平均网络(DAN),其中输入的单词和双字符的嵌入相加求平均数,并经过一个前馈深层神经网络。
基于变换的模型的结果更好,但是在书写的时候,只有基于DAN的编码器可用。与InferSent不同,谷歌的橘子编码器是在监督数据和非监督数据上共同训练的。
结果
我们在SICK和STS数据集上测试了上述所有方法,得出句子对之间的相似度,并与人类判断相比较。
基准方法
尽管他们很简洁,在平均词嵌入之间求余弦相似性的基准方法表现得非常好。但是,前提仍要满足一些条件:
简单word2vec嵌入比GloVe嵌入表现的好
在用word2vec时,尚不清楚使用停用词表或TF-IDF加权是否更有帮助。在STS上,有时有用;在SICK上没用。仅计算未加权的所有word2vec嵌入平均值表现得很好。
在使用GloVe时,停用词列表对于达到好的效果非常重要。利用TF-IDF加权没有帮助。
我们简单的基准方法表现得都不错
词移距离
基于我们的结果,好像没有什么使用词移距离的必要了,因为上述方法表现得已经很好了。只有在STS-TEST上,而且只有在有停止词列表的情况下,词移距离才能和简单基准方法一较高下。
词移距离的表现令人失望
Smooth Inverse Frequency
SIF是在测试中表现最稳定的方法。在SICK数据集上,它的表现和简单基准方法差不多,但是在STS数据集上明显超过了它们。注意,在带有word2vec词嵌入的SIF和带有GloVe词嵌入的SIF之间有一些差别,这种差别很显著,它显示了SIF的加权和去除常用元素后减少的非信息噪音。
SIF的表现最稳定
预训练编码器
预训练编码器的情况比较复杂。但是我们的结果显示编码器还不能完全利用训练的成果。谷歌的句子编码器看起来要比InferSent好一些,但是皮尔森相关系数的结果与SIF的差别不大。
预训练编码器表现得不错,但是SIF也没比它们差多少
而斯皮尔曼相关系数的效果更直接。这也许表明,谷歌的句子编码器更能了解到句子的正确顺序,但是无法分辨其中的差别。
斯皮尔曼相关系数表现出与皮尔森不同的效果
结论
语句相似度是一个复杂现象,一句话的含义并不仅仅取决于当中的词语,而且还依赖于它们的组合方式。正如开头我们举的那个例子(harp和keyboard),语义相似度有好几种维度,句子可能在其中一种维度上相似,而在其他维度上有差异。目前的句子嵌入方法也只做到了表面。通常我们在皮尔森相关系数(Pearson correlation)上进行测试,除了有些情况下斯皮尔曼相关系数(Spearman correlation)会有不一样的结果。
所有判断句子相似度的方法比较
所以,如果你想计算句子相似度,你会选择哪种方法呢?我们的建议如下:
word2vec比GloVe的选择更保险
虽然句子中无加权的平均词嵌入是简单的基准做法,但是Smooth Inverse Frequency是更强有力的选择
如果你可以用预训练编码器,选择谷歌的那款吧。但是要记住它的表现可能不会总是那么惊艳。
python 文本相似度计算函数_四种计算文本相似度的方法对比相关推荐
- php 数据分别是怎么传的_四种php页面间传递数据方法
我们定义page01.php和page02.php两个php文件,将page01中的内容想办法传递到page02,然后供我们继续使用. 第一种: 使用客户端浏览器的cookie.cookie很容易理解 ...
- strlen函数_四种好用的PHP自定义加密函数(可逆/不可逆)
项目中有时我们需要使用PHP将特定的信息进行加密,也就是通过加密算法生成一个加密字符串,这些加密后的字符串可以通过解密算法进行解密,便于程序对解密后的信息进行处理. 最常见的应用在用户登录以及一些AP ...
- python代码 学生上课签到表_一种上课签到系统的制作方法
本发明涉及教学签到领域,尤其涉及一种上课签到系统. 技术背景 良好的学习氛围可以有助于学生提高学习成绩,迟到的同学会影响其他同学的注意力.打断老师的讲课思路,破坏课堂秩序.然而在大学生中,迟到旷课的情 ...
- python下载文件到本地-Python下载网络文本数据到本地内存的四种实现方法示例
本文实例讲述了Python下载网络文本数据到本地内存的四种实现方法.分享给大家供大家参考,具体如下: import urllib.request import requests from io imp ...
- JavaScript高级第2天:定义函数的三种方式、函数的原型链结构、完整原型链、作用域以及作用域链、函数的四种调用模式、闭包、计数器、斐波那契数列优化、三种继承方式
JavaScript高级第二天 01-定义函数的三种方式 1.函数声明 function:可以先调用再声明,因为预解析(把函数声明.变量声明进行提升) function fn() {//函数体conl ...
- 函数的四种调用模式.上下文调用.call.apply
闭包:函数就是一个闭包,一个封闭的作用域; 返回函数,要返回多个函数就用一个对象封装一下, 立即执行函数+return 回调函数 JS动态创建的DOM,不会被搜索引擎抓取,对SEO不友好. /*win ...
- java实现c语言的函数_C语言实现返回字符串函数的四种方法
前言 C语言返回字符串函数共有四种方式,分别如下: 使用堆空间,返回申请的堆地址,注意释放 函数参数传递指针,返回该指针 返回函数内定义的静态变量(共享) 返回全局变量 下面来看看详细的介绍 其实就是 ...
- 函数 函数的基本使用 函数的四种基本形式 可选参数 函数默认参数 函数的剩余参数 构造函数() 函数重(chong)载
函数主要定义行为的 匿名参数 const mingz = function 无名字(参数:数值类型):返回值的类型 接口函数: type(关键字) 别名 = (参数:number)=>返回值 ...
- 【算法】计算组合数的四种常用方法
[算法]计算组合数的四种常用方法 算法一:Cab=Ca−1b−1+Ca−1bC_{a}^{b}=C_{a-1}^{b-1}+C_{a-1}^{b}Cab=Ca−1b−1+Ca−1b 解析: Ca ...
最新文章
- 一看就懂,图解 Spring 循环依赖,写得老好了!
- 写给 Web 开发者的深度学习教程 - 向量化 矩阵
- @valid 校验_SpringBoot数据校验与优雅处理详解
- 实验15 安装新的int 9中断例程
- LeetCode 912. 排序数组(10种排序)
- 1001.A+B Format (20) 解题
- python用装饰器实现缓存函数执行结果
- shell脚本实现一个彩色进度条
- 计算机组成原理r型指令logisim实现_全国计算机二级MS office选择题增分速记宝典!...
- html5新增标签/删除标签
- 快逸报表研究-冻结表头
- 用国产编程语言CBrother做微信公众号后台开发太简单
- 微信小程序实现收藏功能
- 如何在线将WAV转换为MP3格式
- 微信小程序获取微信卡包发票原件及格式化发票信息
- 计算机系一班班会,迎新 · 破冰会|“情暖计算机,友爱一九一”——记计算机类19-1班新生破冰班会...
- mavlink协议从入门到放弃(二)
- 2021年中国棘轮手柄市场趋势报告、技术动态创新及2027年市场预测
- 干货!Flask 动态展示 Pyecharts 图表数据的几种方法!
- 什么是哈希冲突?如何解决?
热门文章
- mysql5.5.44安装_cmake 安装 mysql5.5.44
- sql中当前日期加2个月_一文搞定Mysql日期时间函数
- unity3d 自动变化大小_【Unity游戏开发】AB学习(三)--加载AB和实例化操作对应的内存变化...
- 35岁真的是程序员的坎儿吗?
- 震撼!波士顿动力最新逆天机器人视频,倒立翻筋斗!人类集体沉默...
- VHDL实现简易停车场系统设计
- 基于verilog贪吃蛇游戏设计
- matlab 常用m文件,MATLAB基础课程 第三章 M文件知识(4)
- android自定义图标下载,charts
- ueditor php 网络链接错误,ueditor使用editor.execCommand( 'link', {})插入链接无效的问题...