計算兩組標籤/關鍵詞 相似度算法

原文連接 http://www.zhaochao.net/index.php/2016/02/05/14/

寫作背景

標籤在互聯網行業有大量的應用,給博客打標籤,給商品打標籤,給新聞打標籤。通常每篇文章會打上多個標籤,好的標籤系統給後期的數據分析可以帶來巨大的利處。最近想做一個基於內容的新聞簡單推薦系統,其中的一個推薦權重就是兩篇新聞標籤的相似度,由於沒什麼數據挖掘和機器學習經驗,自己一直在摸索,感覺自己還沒有入門,先記錄下來,慢慢學習。

應用案例

比較現在有兩篇文章
文章1:廣州車展實拍東風悅達起亞K2兩廂 標籤:起亞, 實拍, 汽車, 新聞, 廣州車展, 東風, 資訊
文章2:廣州國際車展:北京現代首望概念車首發現場 標籤廣州, 現場, 汽車, 國際車展, 新聞, 首發, 資訊, 現代, 概念, 北京

現在要通過標籤計算這兩篇文章的相似度

levenshtein distance 編輯距離算法

編輯距離(Edit Distance),又稱Levenshtein距離,是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。許可的編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符。一般來說,編輯距離越小,兩個串的相似度越大。
例如將kitten一字轉成sitting:
sitten (k→s)
sittin (e→i)
sitting (→g)
俄羅斯科學家Vladimir Levenshtein在1965年提出這個概念。

算法JAVA實現

算法具體怎麼實現在時間再分析一下,能過下面代碼我們可以可到兩組標籤的相似度爲0.19999998807907104

public static void main(String[] args) {
        String[] tag1 = { "起亞", "實拍", "汽車", "新聞", "廣州車展", "東風", "資訊"};
        String[] tag2 = {"廣州", "現場", "汽車", "國際車展", "新聞", "首發", "資訊", "現代", "概念", "北京"};
        double similar = levenshtein(tag1, tag2);
        System.out.println(similar);

    }

    public static float levenshtein(String[] str1, String[] str2) {
        // 計算兩個字符串的長度。
        int len1 = str1.length;
        int len2 = str2.length;
        // 建立上面說的數組,比字符長度大一個空間
        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[i - 1] == str2[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);

            }
        }
        // 取數組右下角的值,同樣不同位置代表不同字符串的比較
        // System.out.println("差異步驟:" + dif[len1][len2]);
        // 計算相似度
        float similarity = 1 - (float) dif[len1][len2] / Math.max(str1.length, str2.length);

        return similarity;
    }

    private static int min(int a, int b, int c) {
        int min = a < b ? a : b;
        return min < c ? min : c;
    }

向量空間模型(VSM)的餘弦定理公式(cos)

編輯距離算法雖然可以計算兩組標籤的相似度,但是會有一個很大的問題,就是標籤中的每個關鍵詞權重是不一樣的,它不能帶權重計算兩組標籤的相似度,可以通過向量空間模型計算兩組標籤的空間夾角的餘弦值。具體實現方法如下:
建立標籤庫
如下所示爲我所建的標籤庫,其中id爲標籤的唯一ID,name爲標籤的名稱,sore爲標籤的權重

id  name  sore
1   新聞  1
2   諸暨  0.730766
3   中國  0.684373
4   浙江  0.634607
5   杭州  0.605594
6   廣播  0.526306
7   我市  0.487695
8   視頻  0.444434
9   工作  0.42062
10  男子  0.287171

建立標籤向量
假如有兩篇文章標籤分別爲
文章1:中國,杭州,男子 ,工作
文章2: 我市,杭州,工作

通過標籤庫建立向量
文章1: (0,0,684373,0,605594,0,0,0,42062,28717)
文章2:(0,0,0,0,605594,0,487695,0,420062,0)

向量的建立方法建立一個多維向量,維數等於向量庫的記錄數,向量的值爲文章的標籤的權重,如果沒有標籤則爲0,上面以10個標籤記錄爲例,不過一般標籤庫至少幾十萬,所以要建立幾十萬維的向量

計算向量的cos值

這裏寫圖片描述

v1*v2=0*0+0*0+ ….+28717*0=3.8441274068E11
||v1||=sqrt(0^2+0^2+…+28717^2)=915261.9154635464
||v2||=sqrt(0^2+0^2+…+420062^2+0^2)=883766.1397140083

相似度: v1*v2/(||v1||*||v2||)=0.47524222827391666

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章