文字相似度及案例-語義分析演算法學習
阿新 • • 發佈:2019-08-16
在做自然語言處理的過程中,我們經常會遇到需要找出相似語句的場景,或者找出句子的近似表達,這時候就需要把類似的句子歸到一起,這裡面就涉及到句子相似度計算的問題。
基本方法
句子相似度計算一共歸類了以下幾種方法:
- 編輯距離計算
- 傑卡德係數計算
- TF 計算
- TF-IDF 計算
- Word2Vec 計算
下面來一一瞭解一下這幾種演算法的原理和 Python 實現。
編輯距離計算
編輯距離,英文叫做 Edit Distance,又稱 Levenshtein 距離,是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數,如果它們的距離越大,說明它們越是不同。許可的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。
例如我們有兩個字串:string 和 setting,如果我們想要把 string 轉化為 setting,需要這麼兩步:
- 第一步,在 s 和 t 之間加入字元 e。
- 第二步,把 r 替換成 t。
所以它們的編輯距離差就是 2,這就對應著二者要進行轉化所要改變(新增、替換、刪除)的最小步數。
那麼用 Python 怎樣來實現呢,我們可以直接使用 distance 庫:
#編輯距離 import distance def edit_distance(s1, s2): return distance.levenshtein(s1, s2) strings = [ '你在幹什麼', '你在幹啥子', '你在做什麼', '你好啊', '我喜歡吃香蕉' ] target = '你在幹啥' results = list(filter(lambda x: edit_distance(x, target) <= 2, strings)) print(results) ''' ['你在幹什麼', '你在幹啥子'] '''
通過這種方式我們可以大致篩選出類似的句子,但是發現一些句子例如“你在做什麼” 就沒有被識別出來,但他們的意義確實是相差不大的,因此,編輯距離並不是一個好的方式,但是簡單易用。
傑卡德係數計算
傑卡德係數,英文叫做 Jaccard index, 又稱為 Jaccard 相似係數,用於比較有限樣本集之間的相似性與差異性。Jaccard 係數值越大,樣本相似度越高。
實際上它的計算方式非常簡單,就是兩個樣本的交集除以並集得到的數值,當兩個樣本完全一致時,結果為 1,當兩個樣本完全不同時,結果為 0。
演算法非常簡單,就是交集除以並集,下面我們用 Python 程式碼來實現一下:
#傑卡德係數計算
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
def jaccard_similarity(s1, s2):
def add_space(s):
return ' '.join(list(s))
# 將字中間加入空格
s1, s2 = add_space(s1), add_space(s2)
# 轉化為TF矩陣
cv = CountVectorizer(tokenizer=lambda s: s.split())
corpus = [s1, s2]
vectors = cv.fit_transform(corpus).toarray()
# 求交集
numerator = np.sum(np.min(vectors, axis=0))
# 求並集
denominator = np.sum(np.max(vectors, axis=0))
# 計算傑卡德係數
return 1.0 * numerator / denominator
s1 = '你在幹嘛呢'
s2 = '你在幹什麼呢'
print(jaccard_similarity(s1, s2))
'''
0.571428571