文字相似度演算法 餘弦定理

2021-06-18 07:23:10 字數 2212 閱讀 8339

最近由於工作專案,需要判斷兩個txt文字是否相似,於是開始在網上找資料研究,因為在程式中會把文字轉換成string再做比較,所以最開始找到了這篇關於 距離編輯演算法 blog寫的非常好,受益匪淺。

於是我決定把它用到專案中,來判斷兩個文字的相似度。但後來實際操作發現有一些問題:直接說就是查詢一本書中的相似章節花了我7、8分鐘;這是我不能接受……

於是停下來仔細分析發現,這種演算法在此專案中不是特別適用,由於要判斷一本書中是否有相同章節,所以每兩個章節之間都要比較,若一本書書有x章的話,這裡需對比x(x-1)/2次;而此演算法採用矩陣的方式,計算兩個字串之間的變化步驟,會遍歷兩個文字中的每乙個字元兩兩比較,可以推斷出時間複雜度至少為document1.length × document2.length,我所比較的章節字數平均在幾千~一萬字;這樣計算實在要了老命。

想到lucene中的評分機制,也是算乙個相似度的問題,不過它採用的是計算向量間的夾角(余弦公式),在google黑板報中的:數學之美(餘弦定理和新聞分類) 也有說明,可以通過餘弦定理來判斷相似度;於是決定自己動手試試。

首相選擇向量的模型:在以字為向量還是以詞為向量的問題上,糾結了一會;後來還是覺得用字,雖然詞更為準確,但分詞卻需要增加額外的複雜度,並且此專案要求速度,準確率可以放低,於是還是選擇字為向量。

然後每個字在章節中出現的次數,便是以此字向量的值。現在我們假設:

章節1中出現的字為:z1c1,z1c2,z1c3,z1c4……z1cn;它們在章節中的個數為:z1n1,z1n2,z1n3……z1nm;

章節2中出現的字為:z2c1,z2c2,z2c3,z2c4……z2cn;它們在章節中的個數為:z2n1,z2n2,z2n3……z2nm;

其中,z1c1和z2c1表示兩個文字中同乙個字,z1n1和z2n1是它們分別對應的個數,

最後我們的相似度可以這麼計算:

程式實現如下:(若有可優化或更好的實現請不吝賜教)

public static double getsimilarity(string doc1, string doc2)

catch (exception)

finally

else}}

}}

for (int i = 0; i < doc2.length; i++)

catch (exception)

finally

else}}

}}

double sqdoc1 = 0;

double sqdoc2 = 0;

double denominator = 0;

foreach (keyvaluepairpar in algorithmmap)

return denominator / math.sqrt(sqdoc1 * sqdoc2);

}else

}public static bool ishanzi(char ch)

/*** 根據輸入的unicode字元,獲取它的gb2312編碼或者ascii編碼,

* * @param ch

* 輸入的gb2312中文字元或者ascii字元(128個)

* @return ch在gb2312中的位置,-1表示該字元不認識

*/public static short getgb2312id(char ch)

int b0 = (int)(buffer[0] & 0x0ff) - 161; // 編碼從a1開始,因此減去0xa1=161

int b1 = (int)(buffer[1] & 0x0ff) - 161; // 第乙個字元和最後乙個字元沒有漢字,因此每個區只收16*6-2=94個漢字

return (short)(b0 * 94 + b1);

}catch (exception e)

return -1;

}

程式中做了兩小的改進,以加快效率:

1. 只將漢字作為向量,其他的如標點,數字等符號不處理;2. 在hashmap中存放漢字和其在文字中對於的個數時,先將單個漢字通過gb2312編碼轉換成數字,再存放。

最後寫了個測試,根據兩種不同的演算法對比下時間,下面是測試結果:

餘弦定理演算法:doc1 與 doc2 相似度為:0.9954971, 耗時:22mm

距離編輯演算法:doc1 與 doc2 相似度為:0.99425095, 耗時:322mm

可見效率有明顯提高,演算法複雜度大致為:document1.length + document2.length。

文字相似度 自己實現文字相似度演算法(餘弦定理)

最近由於工作專案,需要判斷兩個txt文字是否相似,於是開始在網上找資料研究,因為在程式中會把文字轉換成string再做比較,所以最開始找到了這篇關於 距離編輯演算法 blog寫的非常好,受益匪淺。於是我決定把它用到專案中,來判斷兩個文字的相似度。但後來實際操作發現有一些問題 直接說就是查詢一本書中的...

使用餘弦定理計算文字相似度

文字相似度 學過向量代數的人都知道,向量實際上是多維空間中有方向的線段。如果兩個向量的方向一致,即夾角接近零,那麼這兩個向量就相近。而要確定兩個向量方向是否一致,這就要用到餘弦定理計算向量的夾角了。餘弦定理對我們每個人都不陌生,它描述了三角形中任何乙個夾角和三個邊的關係,換句話說,給定三角形的三條邊...

文字相似度計算 餘弦定理和廣義Jaccard係數

在7.9餘弦定理 空間向量 我的數學3 中簡單地說了一下利用餘弦定理來計算文字相似度。下面是利用餘弦定理和廣義jaccard係數來計算文字相似度。簡單介紹一下jaccard係數 廣義jaccard係數可以用於文件資料,並在二元屬性情況下歸約為jaccard係數。廣義jaccard係數又稱tanimo...