浅谈文本的相似度问题
今天要研究的問(wèn)題是如何計(jì)算兩個(gè)文本的相似度。正如上篇文章描述,計(jì)算文本的相似度在工程中有著重要的應(yīng)用,
比如文本去重,搜索引擎網(wǎng)頁(yè)判重,論文的反抄襲,ACM競(jìng)賽中反作弊等等。
?
上篇文章介紹的SimHash算法是比較優(yōu)秀的文檔判重算法,它能處理海量文本的判重,Google搜索引擎也正是用這
個(gè)算法來(lái)處理網(wǎng)頁(yè)的重復(fù)問(wèn)題。實(shí)際上,僅拿文本的相似度計(jì)算來(lái)說(shuō),有很多算法都能解決這個(gè)問(wèn)題,并且都達(dá)到比
較滿意的效果。最常見(jiàn)的幾種方法如下
?
?? (1)基于最長(zhǎng)公共子串
?? (2)基于最長(zhǎng)公共子序列
?? (3)基于最少編輯距離
?? (4)基于海明距離
?? (5)基于余弦值
?? (6)基于Jaccard相似度
?
由于前2種方法很經(jīng)典,在實(shí)際中也用得不多,就不用多講了。接下來(lái)主要介紹后面4種方法。
?
首先來(lái)研究基于最少編輯距離的方法。最少編輯距離是這樣定義的:指兩個(gè)字符串之間,由一個(gè)轉(zhuǎn)化為另一個(gè)所需
要的最少編輯操作次數(shù),允許的操作包括3種:將一個(gè)字符替換為另一個(gè)字符;插入一個(gè)字符;刪除一個(gè)字符。
?
比如將kitten轉(zhuǎn)換為sitting,則進(jìn)行如下3步操作
?
??? sitten? (k -> s)
??? sittin? (e -> i)
??? sitting (? + g?)
?
所以kitten與sitting的最少編輯距離就是3。編輯距離又稱Levenshtein距離,也叫做Edit Distance,是俄
羅斯科學(xué)家Vladimir Levenshtein在1965年提出的。編程之美上的字符串相似度問(wèn)題實(shí)際上就是求最少編輯距
離問(wèn)題。
?
那么,如何求兩個(gè)字符串的最少編輯距離?很明顯這是一個(gè)DP問(wèn)題,設(shè)表示字符串和字符串
的最少編輯距離,那么狀態(tài)轉(zhuǎn)移方程如下
?
???????
?
初始化為
?
代碼:
#include <iostream> #include <string.h> #include <stdio.h>using namespace std; const int N = 1005;int dp[N][N]; char S[N],T[N];int Lenv(char S[],char T[]) {int n = strlen(S);int m = strlen(T);for(int i=0; i<=n; i++)dp[i][0] = i;for(int i=0; i<=m; i++)dp[0][i] = i;for(int i=1; i<=n; i++){for(int j=1; j<=m; j++){dp[i][j] = min(dp[i-1][j],dp[i][j-1]) + 1;if(S[i-1] == T[j-1])dp[i][j] = min(dp[i][j],dp[i-1][j-1]);elsedp[i][j] = min(dp[i][j],dp[i-1][j-1] + 1);}}return dp[n][m]; }int main() {while(scanf("%s%s",S,T)!=EOF)printf("%d\n",Lenv(S,T));return 0; }
計(jì)算出兩個(gè)文本的最少編輯距離之后,如果這個(gè)數(shù)字越小,那么說(shuō)明這兩篇文章越相似,但是很明顯,通過(guò)這種方法
計(jì)算的時(shí)間復(fù)雜度為,而且需要兩兩進(jìn)行計(jì)算,所以只適合處理小數(shù)據(jù)的文本。
?
對(duì)于基于海明距離的文本處理方法,有比較優(yōu)秀的SimHash算法,上篇文章已經(jīng)介紹過(guò),不再贅述。
?
接下來(lái)研究基于余弦值的方法,其實(shí)基于余弦值的方法是依賴于向量空間模型的,它是先把文本進(jìn)行分詞,提取特征
向量,得到一個(gè)N維的文本向量,然后統(tǒng)計(jì)每個(gè)詞在文中出現(xiàn)次數(shù),把這個(gè)次數(shù)作為這個(gè)詞的權(quán)值,某個(gè)詞出現(xiàn)次數(shù)
越多,表示它越重要,得到的權(quán)值向量用表示。
?
如果要計(jì)算兩個(gè)文本的相似度,那么應(yīng)該先得到它們的權(quán)值向量和,進(jìn)而相似度為
?
????????
?
所以基于余弦值的相似度計(jì)算步驟大致如下
?
???
?
基于Jaccard相似度的度量也是先得到文本向量,這個(gè)向量可以看成是詞的集合,那么兩個(gè)集合之間的Jaccard相
似度等于交集大小與并集大小的比例。公式如下
?
???????
?
當(dāng)然在實(shí)際處理中計(jì)算交集與并集可以用紅黑樹(shù)等數(shù)據(jù)結(jié)構(gòu),在C++中直接可以考慮用set集合容器處理。
?
總結(jié)
以上是生活随笔為你收集整理的浅谈文本的相似度问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 组合数取模终极版
- 下一篇: SVD原理及其应用导论