背景
徹底搞懂simhash原理,及如何進行文本相似度的比較。
simhash原理
概括的說即是:將文本向量化后,進行向量間的距離計算,卡某個閾值來判定兩個文本是否相似。
涉及關鍵點
- 文本向量化操作
- 切詞,並賦權重值
- bin(hash(切詞)).zfill(64); 轉成定長01向量
- 向量乘權重;遇到1的乘正權重,遇到0乘負權重
- 全部向量對應維度上進行加和
- 降維:大於0的變成1,小於0的變成0,產出文本的向量
- 海明距離計算
- 異或時,只有在兩個比較的位不同時其結果是1 ,否則結果為0
- 兩個向量“異或”后得到1的個數即為海明距離的大小
舉個例子
需要安裝的包
- jieba分詞包:https://pypi.org/project/jieba/
- 選擇半自動安裝:下載最新tar包,本地解壓后,python setup.py install
- numpy包:pip install numpy
詳細代碼如下:
# -*- coding: utf-8 -*- import jieba.analyse import jieba import json import numpy as np class SimHash(object): # 文本使用simhash方法,轉成64維向量 def content_vector(self, contents): # 獲取關鍵詞及其tf-idf權重值 # 分詞 hash 加權 keywords = jieba.analyse.extract_tags(contents, withWeight=True) ret_list = [] for word, weight in keywords: # hash word_hash = bin(hash(word)).replace('0b', '').replace('-', '').zfill(64) weight = int(weight * 10) tmp_list = [] for feature in word_hash: if feature == '1': # 加權 tmp_list.append(weight) else: tmp_list.append(-1 * weight) ret_list.append(tmp_list) # 降維 sum_list = np.sum(np.array(ret_list), axis=0) res_str = '' for i in sum_list: if i > 0: res_str += '1' else: res_str += '0' return res_str # 計算兩個向量的海明距離 def cal_hamming_distance(self, vector1, vector2): vec1_int = int(('0b'+ vector1), 2) vec2_int = int(('0b' +vector2), 2) # 異或操作 num = vec1_int ^ vec2_int # 獲取num中1的個數,即為海明距離 count = 0 for i in bin(num).replace('0b', ''): if i == '1': count += 1 return count