思路一:先求句向量,然后求余弦相似度
1.求得兩個(gè)句子的句向量
生成文本詞頻向量
用詞頻來代替呀忧,句子辞友,當(dāng)然這樣做忽略近義詞信息栅哀、語(yǔ)義信息、大量文本下運(yùn)算等諸多問題称龙。如果兩段很長(zhǎng)的文本進(jìn)行比較(比如上萬字的文章)留拾,豈不是維度要擴(kuò)增很多倍?而且矩陣會(huì)非常稀疏鲫尊,就是很多取值都是0痴柔,計(jì)算開銷大且效率低tfidf提取句向量
對(duì)剛才的問題進(jìn)行特征降維,可依舊解決不了文本語(yǔ)義問題深度學(xué)習(xí)方法包含語(yǔ)義信息疫向,參考前面的文章:
bert生成句向量-
傳統(tǒng)的方法生成句向量
用每個(gè)詞的詞向量相加咳蔚,然后求平均
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.求兩個(gè)向量之間的余弦夾角
####計(jì)算余弦夾角
def cos_sim(vector_a, vector_b):
"""
計(jì)算兩個(gè)向量之間的余弦相似度
: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
思路二:求得詞向量,計(jì)算詞移距離WMD
詞移距離
Word2Vec將詞映射為一個(gè)詞向量搔驼,在這個(gè)向量空間中谈火,語(yǔ)義相似的詞之間距離會(huì)比較小,而詞移距離(WMD)正是基于word2vec的這一特性開發(fā)出來的舌涨。
兩個(gè)文檔中的任意兩個(gè)詞所對(duì)應(yīng)的詞向量求歐氏距離然后再加權(quán)求和
image.png
image.png
這個(gè)加權(quán)矩陣T有些類似于HMM中的狀態(tài)轉(zhuǎn)移矩陣糯耍,只不過其中的概率轉(zhuǎn)換為權(quán)重了而已。
如圖囊嘉,我們假設(shè)’Obama’這個(gè)詞在文檔1中的的權(quán)重為0.5(可以簡(jiǎn)單地用詞頻或者TFIDF進(jìn)行計(jì)算)温技,那么由于’Obama’和’president’的相似度很高,那么我們可以給由’Obama’移動(dòng)到’president’很高的權(quán)重扭粱,這里假設(shè)為0.4舵鳞,文檔2中其他的詞由于和’Obama’的距離比較遠(yuǎn),所以會(huì)分到更小的權(quán)重琢蛤。這里的約束是蜓堕,由文檔1中的某個(gè)詞i移動(dòng)到文檔2中的各個(gè)詞的權(quán)重之和應(yīng)該與文檔1中的這個(gè)詞i的權(quán)重相等抛虏,即’Obama’要把自己的權(quán)重(0.5)分給文檔2中的各個(gè)詞。同樣俩滥,文檔2中的某個(gè)詞j所接受到由文檔1中的各個(gè)詞所流入的權(quán)重之和應(yīng)該等于詞j在文檔2中的權(quán)重嘉蕾。
參考資料:
Supervised Word Mover’s Distance (可監(jiān)督的詞移距離) – NIPS 2016論文精選#2
https://blog.csdn.net/qrlhl/article/details/78512598
https://blog.csdn.net/weixin_40547993/article/details/89475630
- 計(jì)算wmd詞移距離代碼如下:
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= "今天是個(gè)好日子"
s02= "今天是晴天"
s03= "天氣多云轉(zhuǎn)陰"
sentence_01 = list(jieba.cut(s01))
sentence_02= list(jieba.cut(s02))
sentence_03= list(jieba.cut(s03))
結(jié)果:
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