浅析simhash算法


计算文章相似度,用到了simhash算法

问题一: 传统的hash只能够判断两篇文章是不是完全一样, (即hash相等) 而不能判断相似度, 

问题二:使用余弦相似度判断文章相似度,即:先进行分词,得到一系列特征向量,然后计算特征向量之间的余弦夹角,

            这种方法在特征向量很多的时候, 会拥有庞大的计算量

simhash就很好的解决的以上两个问题,simhash作为locality sensitive hash(局部敏感哈希)的一种,

其主要思想是降维, 将高维度的特征向量映射成低维的特征向量,

相对于传统的hash, 相似文章的simhash也是相似的, 

可以通过计算两个向量的 Hamming Distance(汉明距离)来确定文章是否重复或者高度近似.

simhash的过程可以分为以下几步:

1.分词 

->获取文章分词 

                ->去除html标签

                ->获得文章关键字

->获得所有内容的词性(第三方技术获取)

->获得分词的词性

->获得词的权重(词频,计算某个词在该文章中出现的次数)

->封装参数
temp = array(
keyword => ... //关键字 
cixing  => ... //词性
cipin   => ... //词频
);

->获取文章词汇数量 (实际上是每个关键字出现次数的总和, 即所有关键字词频的总和)

会在计算TF值时用到

->获取语料库文章总数 (从数据库中查询, 计数即可)

会在计算IDF时用到

->计算TF值 

公式: 某关键字tf = 该关键字词频/文章总词汇数

->计算IDF值与TF-IDF值 

->计算每个关键词出现在文章的次数

->公式: IDF = log(10为底) (文章总数/包含该关键字的文章数+1)
TF-IDF = TF * IDF


2.hash 

通过hash算法把每个关键词变成hash值,获得64位hash值


3.加权

->将得到的哈希值转换为数组(每个元素只含一位)

->需要按照单词的权重形成加权数字串, 

 当hash值为1时, hash和权重正相乘(1*TF-IDF), 

 当hash值为0时, hash和权重负相乘(-1*TF-IDF)


4.合并降维

合并所有的特征向量相加,得到一个最终的向量,然后降维

对于最终的向量的每一位如果大于0则为1,否则为0,这样就能得到最终的simhash的指纹签名

如此便完成了降维的操作, 将原有n个m维的特征向量降为1个m维的特征向量, 

图解:
文章1 hash值 TF-IDF    各位加权
关键字1         10010   5    5  -5  -5   5  -5 \
关键字2         11001   4    4   4  -4  -4   4 |   n个特征向量
关键字3         10100   1    1  -1   1  -1  -1 |
关键字4         10001   3    3  -3  -3  -3   3 /

加权后各位(每列)相加            13 -5 -11  -3  1
simhash值 (>0为1 , <=0 为0)            1   0    0    0  1 
            \-------------/
          m维
所以最终结果: 文章1的 simhash值为10001.


为了方便比较, 此处还采取了分块存储, 即除了存储每篇文章的simhash外, 

还将simhash平均分为4块, 计算每块的值,即每块的二进制转10进制进行存储, 如果某块的值相同,

则说明这块所对应的simhash值也相同,加快了比较的速度.

-------------------------------------------------------------------------------------------------------------
PS: 

汉明距离(Hamming Distance)的计算:

前提: 已知要比较相似度的两篇文章的simhash, 

按位异或判断,即:如果该位上的hash值不同,则距离+1, 如果相同则不加.

例子:

文章1: 10010010010

文章2: 10001010000

结果:  00011000010

汉明距离为:3

(此处结果值为每位值的[异或]结果,汉明距离即为结果中1的个数)

异或: 如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

你可能感兴趣的:(算法)