一、背景
推薦系統中,有一個剛需就是去重,去重主要涉及兩塊:
1)內容源去重,即有些抓取的文章基本是講的一件事。
2)給用戶推薦的內容去重,即不能重復推薦。
對於第一種去重,可以采用Google公布的去重算法Simhash,該算法適合海量數據去重。對於常規的文本相似度計算,需要分詞,組合成一個向量,不適合海里文本。
第二種去重可以采用BloomFilter算法,該算法與Bitmap位圖算法有相似之處。
二、Simhash去重算法
simhash的核心思想是為每一篇文本生成一個整數表示的指紋,然后用這個指紋去進行去重或者相似度檢測。對於一些主要內容不變,有一些不太重要的詞句不同的文本,simhash仍然能夠得到相似或者相同的指紋。

1、首先,對原始內容分詞,得到每個詞的權重
2、對每個詞hash成一個整數,並且把這個整數對應的二進制中的0變成-1,1還是1。
3、每個詞hash后的二進制向量乘以權重,形成新的加權向量。
4、把每個詞的加權向量相加,得到最終的加權向量,這個向量中元素有正有負。
5、把最終的這個向量正值設置為1,負值設置為0,形成了一個二進制序列,也就最終變成了一個整數,就是該內容的指紋。
該算法的奇妙之處在於,最后加的一個無關緊要的詞“了”,可以看出這個詞很難改變最終生成的整數,因為其權重比較小,所以其在向量的每一位上,很難改變原有的正負值。所以不太重要的詞,就不太影響內容之間的重復檢測。
得到每個內容的simhash指紋值之后,可以兩兩計算之間的海明距離(一個二進制序列變成另外一個二進制序列需要翻轉的次數),其實就是兩個指紋的異或運算,異或運算結果包含3以下的1,則認為兩條內容重復。
三、BloomFilter算法
對於用戶量不大的場景,可以把用戶推薦過的資訊ID,以K-V的形式存儲起來;但是如果用戶量巨大,這種做法的消耗不容小視。
該算法如下:

假如是3個hash函數,必須3個hash函數后對應的3個位置都為1,才表示在集合內,有一個是0,就說明元素不在集合內。
需要說明的是,BloomFilter不保證百分之百准確,有很小的概率會把原本不屬於集合中的元素判斷存在於集合中,當然概率會比較小,hash函數的個數k越多,這種概率就越低。
