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

2021-09-20 04:29:04 字數 2427 閱讀 5340

最近由於工作專案,需要判斷兩個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是它們分別對應的個數,

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

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

1

public

class

cosinesimilaralgorithm else23}

24}25}

2627

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

42}43}

4445 iteratoriterator =algorithmmap.keyset().iterator();

46double sqdoc1 = 0;

47double sqdoc2 = 0;

48double denominator = 0;

49while

(iterator.hasnext())

5556

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

57 } else61}

6263

public

static

boolean ishanzi(char

ch)

6869

/**70

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

71*

72*

@param

ch73

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

74*

@return

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

75*/

76public

static

short getgb2312id(char

ch)

83int b0 = (int) (buffer[0] & 0x0ff) - 161; //

編碼從a1開始,因此減去0xa1=161

84int b1 = (int) (buffer[1] & 0x0ff) - 161; //

第乙個字元和最後乙個字元沒有漢字,因此每個區只收16*6-2=94個漢字

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

86 } catch

(unsupportedencodingexception e)

89return -1;90}

91 }

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

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

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

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

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

文字相似度

這種相似度計算方式相對簡單,原理也易於理解,就是計算單詞集合之間的交集和並集大小的比例,該值越大,表示兩個文字越相似。在涉及到大規模平行計算時,該方法效率上有一定的優勢。jaccard 相似度公式 舉例 句子a 我喜歡看電視,不喜歡看電影。句子b 我不喜歡看電視,也不喜歡看電影。分詞去噪後 a 我,...

計算文字相似度 文字相似度演算法之 simhash

文字相似度演算法種類繁多,今天先介紹一種常見的網頁去重演算法simhash。1 什麼是simhash 2 simhash步驟 人工智慧,1 大資料,2 科技,3 網際網路,4 機器學習,5 人工智慧 00101 大資料 11001 科技 00110 網際網路 10101 機器學習 01011 has...

計算文字相似度

計算文字相似度 推薦2收藏 簡單講解 文字相似度計算在資訊檢索 資料探勘 機器翻譯 文件複製檢測等領域有著廣泛的應用。比如 控制,我們假設你開發了乙個微博 並且已經把世界上罵人的句子都已經收錄進了資料庫,那麼當乙個使用者發微博時會先跟罵人句子的資料庫進行比較,如果符合裡面的句子就不讓使用者發出。通常...