1. 程式人生 > 其它 >自然語言處理之文字相似度的計算

自然語言處理之文字相似度的計算

自然語言處理中,文字相似度的計算至關重要,在計算文字相似度的時候,通常將特徵表示為向量的形式,目前常用的簡單文字相似度計算有以下幾種,文末上程式碼。
  • 餘弦相似度
    對於兩個向量A和B,餘弦相似度關注的是向量之間的角度關係,並不關心他們的絕對大小,其取值範圍是[-1,1]。當一對兒文字長度差距很大,但內容相近時,如果使用詞頻或者詞向量作為特徵,他們在特徵空間中的歐式距離會很大,如果使用餘弦相似度的話,夾角可能很小,相似度較高。
    餘弦相似度公式:cos(A,B) = \(\frac{A\cdot B}{||A||_{2}||B||_{2}}\)
    餘弦距離公式:1-cos(A,B)

  • jaccard相似度
    jaccard相似度的簡單解釋就是兩個句子詞彙的交集size除以兩個句子詞彙的並集size,這個與上述cos相似度的區別在於若某一詞彙在某個向量中重複許多次並不會影響相似度的計算,假設某個業務場景的文字包含了很多重複性的詞彙,而這些詞彙與我們想要做的任務關係不大,那麼可選擇jaccard相似度來計算。
    jaccard相似度公式:\(jaccard\_sim = \frac{|A\cap B|}{|A\cup B|}\)

  • w2v相似度
    在計算文字相似度時,如果需要考慮周圍詞對當前文字向量的影響可能需要更復雜一點的計算或者模型,經典的模型有word2vec或者bert等等,一個最簡單的表示文字向量的方式就是將文字中所有的詞向量相應維度進行相加,從而得到當前文字的向量,在得到文字向量之後可以選擇cos相似度去計算文字相似度。

  • 編輯距離
    編輯距離,又稱Levenshtein距離,是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。許可的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。在nlp中編輯距離一般用於拼寫糾錯,相似度計算,在搜尋領域,通過計算輸入詞與候選詞的編輯距離,可以一定量的幫助使用者進行拼寫糾錯。這部分不細說了,看程式碼。

點選檢視程式碼
from scipy import spatial
#餘弦相似度
def cos_sim(a, b):
    return 1 - spatial.distance.cosine(a, b)

#jaccard相似度
def jaccard_dist(s1, s2):
    l1 = set(s1)
    l2 = set(s2)
    cap = l1 & l2
    cup = l1|l2
    return len(cap)/len(cup)

#編輯距離
def minDistance(word1, word2):
    dp = [[0 for j in range(len(word2)+1)]for i in range(len(word1)+1)]
    for i in range(len(word1)+1):
        for j in range(len(word2)+1):
            if i == 0:
                dp[i][j] = j
            elif j == 0:
                dp[i][j] = i
            elif word1[i-1] == word2[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = 1+min(dp[i][j-1],
                                 dp[i-1][j],
                                 dp[i-1][j-1])
    return dp[len(word1)][len(word2)]

#w2v計算相似度
from gensim.models import word2vec
import jieba
import numpy as np
model_path = "~~~"
model = word2vec.Word2Vec.load(model_path)
def w2v(sentence):
    words = jieba.cut(sentence, cut_all=False)
    dim = model.syn0.shape[1]
    vector = np.zeros(dim)
    for word in words:
        if word in model.vocab:
            vec = model[word]
            vector += vec
    return vector
sim = cos_sim(sentence1,sentence2)