前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >句子相似度计算

句子相似度计算

作者头像
DC童生
修改2019-08-07 10:58:59
2.4K0
修改2019-08-07 10:58:59
举报
文章被收录于专栏:机器学习原理

思路一:先求句向量,然后求余弦相似度

1.求得两个句子的句向量

  • 生成文本词频向量 用词频来代替,句子,当然这样做忽略近义词信息、语义信息、大量文本下运算等诸多问题。如果两段很长的文本进行比较(比如上万字的文章),岂不是维度要扩增很多倍?而且矩阵会非常稀疏,就是很多取值都是0,计算开销大且效率低
  • tfidf提取句向量 对刚才的问题进行特征降维,可依旧解决不了文本语义问题
  • 深度学习方法包含语义信息,参考前面的文章: bert生成句向量
  • 传统的方法生成句向量

用每个词的词向量相加,然后求平均

代码语言:javascript
复制
def sent2vec(s):
    words = s
    M = []
    for w in words:
        try:
            M.append(w2v.wv[w])
        except:
            continue
    M = np.array(M)
    v = M.sum(axis=0)
    return v / np.sqrt((v ** 2).sum())

2.求两个向量之间的余弦夹角

代码语言:javascript
复制
####计算余弦夹角
def cos_sim(vector_a, vector_b):
    """
    计算两个向量之间的余弦相似度
    :param vector_a: 向量 a
    :param vector_b: 向量 b
    :return: sim
    """
    vector_a = np.mat(vector_a)
    vector_b = np.mat(vector_b)
    num = float(vector_a * vector_b.T)
    denom = np.linalg.norm(vector_a) * np.linalg.norm(vector_b)
    cos = num / denom
    sim = 0.5 + 0.5 * cos
    return sim

思路二:求得词向量,计算词移距离WMD

词移距离

Word2Vec将词映射为一个词向量,在这个向量空间中,语义相似的词之间距离会比较小,而词移距离(WMD)正是基于word2vec的这一特性开发出来的。

两个文档中的任意两个词所对应的词向量求欧氏距离然后再加权求和

image.png

image.png

这个加权矩阵T有些类似于HMM中的状态转移矩阵,只不过其中的概率转换为权重了而已。

如图,我们假设’Obama’这个词在文档1中的的权重为0.5(可以简单地用词频或者TFIDF进行计算),那么由于’Obama’和’president’的相似度很高,那么我们可以给由’Obama’移动到’president’很高的权重,这里假设为0.4,文档2中其他的词由于和’Obama’的距离比较远,所以会分到更小的权重。这里的约束是,由文档1中的某个词i移动到文档2中的各个词的权重之和应该与文档1中的这个词i的权重相等,即’Obama’要把自己的权重(0.5)分给文档2中的各个词。同样,文档2中的某个词j所接受到由文档1中的各个词所流入的权重之和应该等于词j在文档2中的权重。

参考资料:

Supervised Word Mover’s Distance (可监督的词移距离) – NIPS 2016论文精选#2

https://blog.csdn.net/qrlhl/article/details/78512598

https://blog.csdn.net/weixin_40547993/article/details/89475630

  • 计算wmd词移距离代码如下:
代码语言:javascript
复制
from gensim.models import KeyedVectors
import jieba
import time
import os

start = time.time()
model = KeyedVectors.load_word2vec_format('vectors.bin', binary=True, unicode_errors='ignore')
end = time.time()
print('Cell took %.2f seconds to run.' % (end - start))
s01= "今天是个好日子"
s02= "今天是晴天"
s03= "天气多云转阴"
sentence_01 = list(jieba.cut(s01))
sentence_02= list(jieba.cut(s02))
sentence_03= list(jieba.cut(s03))

结果:

代码语言:javascript
复制
Cell took 16.98 seconds to run.
Loading model cost 0.701 seconds.
distance = 24.3276
Prefix dict has been built succesfully.
distance = 55.7726
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.07.10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 思路一:先求句向量,然后求余弦相似度
    • 1.求得两个句子的句向量
      • 2.求两个向量之间的余弦夹角
      • 思路二:求得词向量,计算词移距离WMD
        • 词移距离
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档