摘要:本文對兩種文本相似度算法進(jìn)行比較。余弦值相似度算法最小編輯距離法氏編輯距離基于詞條空間編輯距離,又稱距離,是指兩個字串之間,由一個轉(zhuǎn)成另一個所需的最少編輯操作次數(shù)。但是同時也可以看出余弦相似度得到的結(jié)果相對比較高一些。
本文由作者祝娜授權(quán)網(wǎng)易云社區(qū)發(fā)布。
本文對兩種文本相似度算法進(jìn)行比較。余弦值相似度算法 VS 最小編輯距離法
1、L氏編輯距離(基于詞條空間)
編輯距離(Edit Distance),又稱Levenshtein距離,是指兩個字串之間,由一個轉(zhuǎn)成另一個所需的最少編輯操作次數(shù)。許可的編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符。
算法實現(xiàn)步驟:
1 設(shè)置n為字符串s的長度。("我是個小仙女")
設(shè)置m為字符串t的長度。("我不是個小仙女")
如果n等于0,返回m并退出。
如果m等于0,返回n并退出。
構(gòu)造兩個向量v0[m+1] 和v1[m+1],串聯(lián)0..m之間所有的元素。
2 初始化 v0 to 0..m。
3 檢查 s (i from 1 to n) 中的每個字符。
4 檢查 t (j from 1 to m) 中的每個字符
5 如果 s[i] 等于 t[j],則編輯代價cost為 0;
如果 s[i] 不等于 t[j],則編輯代價cost為1。
6 設(shè)置單元v1[j]為下面的最小值之一:
a、緊鄰該單元上方+1:v1[j-1] + 1
b、緊鄰該單元左側(cè)+1:v0[j] + 1
c、該單元對角線上方和左側(cè)+cost:v0[j-1] + cost
7 在完成迭代 (3, 4, 5, 6) 之后,v1[m]便是編輯距離的值。
我們得到最小編輯距離為1那么它們的相似度為 (1-ld/(double)Math.max(str1.length(), str2.length()));
1 - 1/8=7/8.
其算法實現(xiàn)(java):
public static float levenshtein(String str1,String str2) { //計算兩個字符串的長度。 int len1 = str1.length(); int len2 = str2.length(); //建立上面說的數(shù)組,比字符長度大一個空間 int[][] dif = new int[len1 + 1][len2 + 1]; //賦初值,步驟B。 for (int a = 0; a <= len1; a++) { dif[a][0] = a; } for (int a = 0; a <= len2; a++) { dif[0][a] = a; } //計算兩個字符是否一樣,計算左上的值 int temp; for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { if (str1.charAt(i - 1) == str2.charAt(j - 1)) { temp = 0; } else { temp = 1; } //取三個值中最小的 dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1, dif[i - 1][j] + 1); } } float similarity =1 - (float) dif[len1][len2] / Math.max(str1.length(), str2.length()); return similarity; }
2、余弦值(基于權(quán)值空間)
關(guān)于余弦相似度可以參照 百度詞條 余弦相似度
通過測量兩個向量之間的角的余弦值來度量它們之間的相似性。0度角的余弦值是1,而其他任何角度的余弦值都不大于1;并且其最小值是-1。從而兩個向量之間的角度的余弦值確定兩個向量是否大致指向相同的方向。所以,它通常用于文件比較。
算法步驟
預(yù)處理→文本特征項選擇→加權(quán)→生成向量空間模型后計算余弦。
具體步驟見附件: 余弦相似度算法步驟解釋.docx
其算法實現(xiàn)(java):
public static double getSimilarity(String doc1, String doc2) { if (doc1 != null && doc1.trim().length() > 0 && doc2 != null && doc2.trim().length() > 0) {
MapAlgorithmMap = new HashMap(); // 將兩個字符串中的中文字符以及出現(xiàn)的總數(shù)封裝到,AlgorithmMap中 for (int i = 0; i < doc1.length(); i++) { char d1 = doc1.charAt(i); if (isHanZi(d1)) { int charIndex = getGB2312Id(d1); if (charIndex != -1) { int[] fq = AlgorithmMap.get(charIndex); if (fq != null && fq.length == 2) { fq[0]++; } else { fq = new int[2]; fq[0] = 1; fq[1] = 0; AlgorithmMap.put(charIndex, fq); } } } } for (int i = 0; i < doc2.length(); i++) { char d2 = doc2.charAt(i); if (isHanZi(d2)) { int charIndex = getGB2312Id(d2); if (charIndex != -1) { int[] fq = AlgorithmMap.get(charIndex); if (fq != null && fq.length == 2) { fq[1]++; } else { fq = new int[2]; fq[0] = 0; fq[1] = 1; AlgorithmMap.put(charIndex, fq); } } } } Iteratoriterator = AlgorithmMap.keySet().iterator(); double sqdoc1 = 0; double sqdoc2 = 0; double denominator = 0; while (iterator.hasNext()) { int[] c = AlgorithmMap.get(iterator.next()); denominator += c[0] * c[1]; sqdoc1 += c[0] * c[0]; sqdoc2 += c[1] * c[1]; } double origin = denominator / Math.sqrt(sqdoc1 * sqdoc2); if (String.valueOf(origin).equals("NaN")) { return Double.valueOf("0"); } BigDecimal bg = new BigDecimal(origin); double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); return f1; } else { throw new NullPointerException(" the Document is null or have not cahrs!!"); } } public static boolean isHanZi(char ch) { // 判斷是否漢字 return (ch >= 0x4E00 && ch <= 0x9FA5); } /** * 根據(jù)輸入的Unicode字符,獲取它的GB2312編碼或者ascii編碼, * * @param ch * 輸入的GB2312中文字符或者ASCII字符(128個) * @return ch在GB2312中的位置,-1表示該字符不認(rèn)識 */ public static short getGB2312Id(char ch) { try { byte[] buffer = Character.toString(ch).getBytes("GB2312"); if (buffer.length != 2) { // 正常情況下buffer應(yīng)該是兩個字節(jié),否則說明ch不屬于GB2312編碼,故返回"?",此時說明不認(rèn)識該字符 return -1; } int b0 = (buffer[0] & 0x0FF) - 161; // 編碼從A1開始,因此減去0xA1=161 int b1 = (buffer[1] & 0x0FF) - 161; // 第一個字符和最后一個字符沒有漢字,因此每個區(qū)只收16*6-2=94個漢字 return (short) (b0 * 94 + b1); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return -1; }
現(xiàn)在對兩種計算相似度的算法進(jìn)行比較:
編輯距離相似度運(yùn)行結(jié)果:
"第六章 字符編碼" 與 "第一章 設(shè)計模式" 的相似度為:0.07159507274627686
"第六章 字符編碼" 與 "第二章 python學(xué)習(xí)" 的相似度為:0.06676656007766724
"第六章 字符編碼" 與 "第三章 python簡介" 的相似度為:0.08275055885314941
"第六章 字符編碼" 與 "第四章 輸入輸出" 的相似度為:0.1878122091293335
"第六章 字符編碼" 與 "第五章 數(shù)據(jù)類型和變量" 的相似度為:0.20358151197433472
"第六章 字符編碼" 與 "第六章 字符編碼" 的相似度為:1.0
"第六章 字符編碼" 與 "第七章 list" 的相似度為:0.20995670557022095
runtime:989毫秒
L編輯距離的時間 算法采用矩陣的方式,計算兩個字符串之間的變化步驟,會遍歷兩個文本中的每一個字符兩兩比較,可以推斷出時間復(fù)雜度至少為 document1.length × document2.length
cos相似度運(yùn)行結(jié)果:
"第六章 字符編碼" 與 "第一章 設(shè)計模式" 的相似度為:0.5
"第六章 字符編碼" 與 "第二章 python學(xué)習(xí)" 的相似度為:0.59
"第六章 字符編碼" 與 "第三章 python簡介" 的相似度為:0.68
"第六章 字符編碼" 與 "第四章 輸入輸出" 的相似度為:0.62
"第六章 字符編碼" 與 "第五章 數(shù)據(jù)類型和變量" 的相似度為:0.72
"第六章 字符編碼" 與 "第六章 字符編碼" 的相似度為:1.0
"第六章 字符編碼" 與 "第七章 list" 的相似度為:0.59
runtime:400毫秒
使用余弦定理計算文本效率相對比較高:其算法復(fù)雜度大致為:document1.length + document2.length。
但是同時也可以看出 余弦相似度得到的結(jié)果相對比較高一些。使用分詞或者過濾掉一些常用詞會對結(jié)果的準(zhǔn)確性更有利。
使用分詞的方法在本文中沒有展開。但是如果去掉文章里的“的、了、吧,呢、啊”等可以提高結(jié)果的準(zhǔn)確率。當(dāng)然同時也可以提高判斷的閥值。
運(yùn)行結(jié)果:
"第六章 字符編碼" 與 "第一章 設(shè)計模式" 的相似度為:0.37
"第六章 字符編碼" 與 "第二章 python學(xué)習(xí)" 的相似度為:0.48
"第六章 字符編碼" 與 "第三章 python簡介" 的相似度為:0.57
"第六章 字符編碼" 與 "第四章 輸入輸出" 的相似度為:0.56
"第六章 字符編碼" 與 "第五章 數(shù)據(jù)類型和變量" 的相似度為:0.67
"第六章 字符編碼" 與 "第六章 字符編碼" 的相似度為:1.0
"第六章 字符編碼" 與 "第七章 list" 的相似度為:0.48
runtime:519毫秒
看以看出準(zhǔn)確度有了一定的提高。
番外:
L編輯距離動態(tài)計算法,調(diào)用python腳本實現(xiàn),腳本文件
author = "victor"
-- coding:utf-8 --import sys
import Levenshtein
if name == "__main__":
if(len(sys.argv) < 3): print("Usage: python myratiodetect.py str1 str2") exit(-1) str1 = sys.argv[1] str2 = sys.argv[2] r = Levenshtein.ratio(str1, str2) print(r) exit(0)
本地運(yùn)行的前提為:已經(jīng)適應(yīng)pip安裝了:python_Levenshtein,所以其對服務(wù)器的依賴比較大,如果工程環(huán)境遷移了的話,會比較受影響。
程序的運(yùn)行結(jié)果:
"第六章 字符編碼" 與 "第一章 設(shè)計模式" 的相似度為:0.157063851181
"第六章 字符編碼" 與 "第二章 python學(xué)習(xí)" 的相似度為:0.165801038753
"第六章 字符編碼" 與 "第三章 python簡介" 的相似度為:0.194563908481
"第六章 字符編碼" 與 "第四章 輸入輸出" 的相似度為:0.268671351528
"第六章 字符編碼" 與 "第五章 數(shù)據(jù)類型和變量" 的相似度為:0.300997688969
"第六章 字符編碼" 與 "第六章 字符編碼" 的相似度為:1.0
"第六章 字符編碼" 與 "第七章 list" 的相似度為:0.296406739228
runtime:2247毫秒
運(yùn)行速度.....比較慢..2333
參考:
https://www.2cto.com/kf/20140...
http://wdhdmx.iteye.com/blog/...
http://blog.sina.com.cn/s/blo...
http://blog.sina.com.cn/s/blo...
更多網(wǎng)易技術(shù)、產(chǎn)品、運(yùn)營經(jīng)驗分享請訪問網(wǎng)易云社區(qū)。
文章來源: 網(wǎng)易云社區(qū)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/25320.html
摘要:在近鄰?fù)扑]中,最常用的相似度是余弦相似度。這就是由于余弦相似度被向量長度歸一化后的結(jié)果。用余弦相似度計算出來,兩個用戶的相似度達(dá)到。余弦相似度適用于評分?jǐn)?shù)據(jù),杰卡德相似度適合用于隱式反饋數(shù)據(jù)。 今天,我們來聊聊協(xié)同過濾中的相似度計算方法有哪些。相似度的本質(zhì)推薦系統(tǒng)中,推薦算法分為兩個門派,一個是機(jī)器學(xué)習(xí)派,另一個就是相似度門派。機(jī)器學(xué)習(xí)派是后起之秀,而相似度派則是泰山北斗,以致?lián)纹饋硗?..
摘要:文和,創(chuàng)意實驗室創(chuàng)意技術(shù)專家在機(jī)器學(xué)習(xí)和計算機(jī)視覺領(lǐng)域,姿勢預(yù)測或根據(jù)圖像數(shù)據(jù)探測人體及其姿勢的能力,堪稱最令人興奮而又最棘手的一個話題。使用,用戶可以直接在瀏覽器中運(yùn)行機(jī)器學(xué)習(xí)模型,無需服務(wù)器。 文 / ?Jane Friedhoff 和 Irene Alvarado,Google 創(chuàng)意實驗室創(chuàng)意技術(shù)專家在機(jī)器學(xué)習(xí)和計算機(jī)視覺領(lǐng)域,姿勢預(yù)測或根據(jù)圖像數(shù)據(jù)探測人體及其姿勢的能力,堪稱最令人興...
摘要:代碼地址在這篇文章中,我將盡我所能揭秘三種降維技術(shù)和自編碼器。動機(jī)當(dāng)處理真實問題和真實數(shù)據(jù)時,我們往往遇到維度高達(dá)數(shù)百萬的高維數(shù)據(jù)。盡管在其原來的高維結(jié)構(gòu)中,數(shù)據(jù)能夠得到較好的表達(dá),但有時候我們可能需要給數(shù)據(jù)降維。 代碼地址:https://github.com/eliorc/Medium/blob/master/PCA-tSNE-AE.ipynb在這篇文章中,我將盡我所能揭秘三種降維技術(shù):...
摘要:在自然語言處理中,一個很重要的技術(shù)手段就是將文檔轉(zhuǎn)換為一個矢量,這個過程一般是使用這個庫進(jìn)行處理的。自然語言處理中,一般來說,代表詞。自然語言預(yù)處理中,一個很重要的步驟就是將你收集的句子進(jìn)行分詞,將一個句子分解成詞的列表。 前言 本文根據(jù)實際項目撰寫,由于項目保密要求,源代碼將進(jìn)行一定程度的刪減。本文撰寫的目的是進(jìn)行公司培訓(xùn),請勿以任何形式進(jìn)行轉(zhuǎn)載。由于是日語項目,用到的分詞軟件等,在...
摘要:實驗結(jié)果實驗數(shù)據(jù)集數(shù)據(jù)集都是新聞類網(wǎng)頁,從五個中文新聞網(wǎng)站中收集一百個頁面這最多也就五類吧,而且也就五百個,好像有點少了吧結(jié)果與驗證性能指標(biāo)這這這比較文本長度就了那不是只要包含新聞?wù)牟痪秃昧恕? 《Web Content Extraction Using Clustering with Web Structure》引用 Huang X, Gao Y, Huang L, et al. ...
閱讀 3515·2021-11-22 09:34
閱讀 750·2021-11-19 11:29
閱讀 1427·2019-08-30 15:43
閱讀 2312·2019-08-30 14:24
閱讀 1936·2019-08-29 17:31
閱讀 1302·2019-08-29 17:17
閱讀 2698·2019-08-29 15:38
閱讀 2928·2019-08-26 12:10