對simhash算法的一些思考

  最近研究文檔去重技術,研究了一下去重算法後,最終選擇了simhash算法.這個算法相對而言最簡單,效果又好,難怪被google選用.

  簡單來講,simhash分爲3步:

  1.將文本去掉格式後,分詞.

  2.將每一個分詞hash爲一組固定長度的數列.比如32bit的一個整數.

  3.建立一個長度爲32的整數數組(假設要生成32位的數字指紋,也可以是其它數字),對每一個分詞hash後的數列進行判斷,如果是1000...1,那麼數組的第一位和末尾一位加1,中間的30位減一,也就是說,逢1加1,逢0減1.一直到把所有的分詞hash數列全部判斷完畢.最後對數組進行判斷,大於0的記爲1,小於等於0的記爲0,得到一個32bit的數字指紋.

  在實際編碼中,有如下幾點體會:

1.中文文檔進行分詞後,其中的一些助詞,語氣詞,人稱代詞等常用字會帶來很大的干擾,比如說"的","我","了","這"等,要把這些詞去掉,增加去重精度.

2.分詞後,儘量給每個分詞一個權重數字,代表這個詞的重要程度,這樣能夠極大提高精度.比較簡單的算法是,把每個詞在文章中出現的次數作爲權重.比如,"美國總統克林頓登上了長城,這是登上長城的第x位美國總統.",那麼分詞後,長城權重2,美國權重2,總統權重2,克林頓權重1,其它分詞權重0,可以忽略掉.

3.分詞算法,我參考了中科院的ICTCLAS.可以直接分析出文章的關鍵詞,只讓關鍵詞參與到simhash算法中會提高效率和效果.

4.對大量文章通過simhash提取數字指紋後,指紋間的海明距離代表了文章的相近程度.對於二進制來將,海明距離是兩個數字的異或後1的個數.

我覺得下面這個算法計算1的個數很高效:

int Count(int v)
{
    int num=0;
    while(v)
    {
        v&=(v-1);
        num++;
    }
    return num;
}

5.對於大量數字指紋的保存,需要考慮一種高效的數據結構.我沒有自己設計,而是直接將數字指紋保存到了全文檢索引擎提供的數據庫中,這樣的好處是,去重和全文檢索可以和諧統一到一起.全文檢索引擎我選擇了xapian,實際用後,沒有發現什麼缺點.

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