simhash 介绍以及应用场景
簡介
simhash 算法是一種局部敏感的哈希算法,能實(shí)現(xiàn)相似文本內(nèi)容的去重。
與信息摘要算法的區(qū)別
信息摘要算法:如果兩者原始內(nèi)容只相差一個(gè)字節(jié),所產(chǎn)生的簽名也很有可能差別很大。
simhash 算法: 如果原始內(nèi)容只相差一個(gè)字節(jié),所產(chǎn)生的簽名差別非常小。
simhash值的對比: 通過兩者的 simhash 值的二進(jìn)制位的差異來表示原始文本內(nèi)容的差異。差異的個(gè)數(shù)又被稱為海明距離。
注意:
simhash 對長文本 500字+ 比較適用,短文本可能偏差比較大。
在 google 的論文給出的數(shù)據(jù)中,64 位的simhash值,在海明距離為 3 的情況下,可認(rèn)為兩篇文檔是相似的或者說是重復(fù)的。當(dāng)然這個(gè)值只是參考值,針對自己的應(yīng)用可能有不同的測試取值。
Python 中的 simhash 模塊
使用 python 實(shí)現(xiàn) simhash 算法,該模塊得出的 simhash 值的長度是 64 位。
github 地址: https://github.com/leonsim/simhash
接著我們來看一下簡單的示例:
# 測試 simhash 庫的簡單使用 # pip install simhashimport re from simhash import Simhashdef get_features(s):"""對文本全部轉(zhuǎn)小寫 去掉空白字符以及標(biāo)點(diǎn)符號(hào) :param s: :return: """width = 3s = s.lower()s = re.sub(r'[^\w]+', '', s)return [s[i:i + width] for i in range(max(len(s) - width + 1, 1))]# 計(jì)算出這幾個(gè)文本的 simhash 值 print('%x' % Simhash(get_features('How are you? I am fine. Thanks.')).value) print('%x' % Simhash(get_features('How are u? I am fine. Thanks.')).value) print('%x' % Simhash(get_features('How r you?I am fine. Thanks.')).value)其實(shí),由此我們也可以知道,在進(jìn)行simhash之前,進(jìn)行一定的預(yù)處理是非常重要的。
獲取兩個(gè) simhash 值之間的距離:
print(Simhash('furuiyang').distance(Simhash('yaokailun'))) print(Simhash('furuiyang').distance(Simhash('ruanyifeng'))) print(Simhash('ruiyang').distance(Simhash('ruiyang')))一般我們在爬蟲項(xiàng)目中使用 simhash 的模式:
"""以一種更加通用的模式去運(yùn)用海明距離"""import re from simhash import Simhash, SimhashIndexdef get_features(s):"""對文本進(jìn)行預(yù)處理轉(zhuǎn)小寫;去除空白字符以及標(biāo)點(diǎn)符號(hào):param s::return:"""width = 3s = s.lower()s = re.sub(r'[^\w]+', '', s)return [s[i:i + width] for i in range(max(len(s) - width + 1, 1))]# 我們已經(jīng)存在的數(shù)據(jù) data = {1: u'How are you? I Am fine. blar blar blar blar blar Thanks.',2: u'How are you i am fine. blar blar blar blar blar than',3: u'This is simhash test.', } # 由初始數(shù)據(jù)建立的 key 以及 simhash 值的對象集 objs = [(str(k), Simhash(get_features(v))) for k, v in data.items()] # 建立索引 可索引到的相似度海明距離是 3 index = SimhashIndex(objs, k=3) print(index.bucket_size()) # 11 # 計(jì)算一個(gè)新來數(shù)據(jù)的 simhash 值 s1 = Simhash(get_features(u'How are you i am fine. blar blar blar blar blar thank')) # 找到數(shù)據(jù)庫中與此最接近的一個(gè) simhash 值的索引 print(index.get_near_dups(s1)) # 將新數(shù)據(jù)添加到原有的索引中 index.add('4', s1) print(index.get_near_dups(s1))如果我們要在實(shí)際項(xiàng)目上使用 simhash 計(jì)算,很顯然需要保存這個(gè)索引對象 。
因此我們可以考慮使用 序列化工具。
序列化工具: 將一個(gè)對象轉(zhuǎn)換為二進(jìn)制的一個(gè)數(shù)據(jù)。
反序列化工具: 將二進(jìn)制恢復(fù)為一個(gè)對象。
后記
大姨媽來的一天,實(shí)在是有點(diǎn)疼。不過過了艱難的第一天,就又可以活蹦亂跳了。人生也是這樣吧,過了最艱難的時(shí)候,其實(shí)處于通途的時(shí)刻還是會(huì)有的。
可是,總之,也不想自己說消極的話而已。
更新時(shí)間: 2020-02-04
總結(jié)
以上是生活随笔為你收集整理的simhash 介绍以及应用场景的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IDL语言基础
- 下一篇: 爱普生(epson)针式打印机初始位置(