大数据下的相似度计算--minHash

简述

本文讨论一种在数据量较大的情况下计算两个集合(比如文本)相似度的算法,以及在互联网行业的应用。

原始问题

当数据量较小时,计算两个文本的相似度可以直接将两个文本表示为向量,然后计算他们的cosine相似度或jaccard相似度。本文所阐述的方法基于后者。jaccard相似度可以看成两个集合A,B的交集占并集的比例:

Jaccard Sim = (A∩B) / (A∪B)

其实就是计算A与B产生重叠的程度。如果数据量不大,A,B的交集与并集中的元素个数可以遍历A,B数出,复杂度为O(n^2)。

衍生问题

文本中的单词往往是可以计数的,但在一个衍生问题中,计算量会很庞大。在互联中,我们往往需要检查两个url的相似性(比如过滤相似度很高的网页,为某一url查找与之类似的白名单,或产生作弊的黑名单等等)。如果把每个url看成文本,那么访客记录则为它的单词。我们需要计算的是两个url的访客重合度。然而,每个url的访客数目是非常庞大的,而且如果需要计算的url pair很多的话,那么计算量是非常庞大的。

基于上述背景,下面讨论如何在大数据下计算Jaccard相似度。解决方案是使用minHash算法,将原先高纬度的独热编码(对每个url,每个用户都可以看成是一个维度)降为可计算的维度(比如100维)。这一算法的假设是两个集合中的元素经过哈希后的最小值相等的概率即为它们的Jaccard相似度:p(hmin(A)=hmin(B))=jaccard(A,B)。具体做法为对每个互联用户(编号或字符串)做哈希,然后查找url A中的访客的最小哈希值,url B同理。这样处理一次的结果在很大程度上hmin(A)不等于hmin(B)的,因此会得到A与B相似性为0的结论。为使结论更为准确,正确的做法是选取K个不同的哈希函数,对每个用户哈希K次,每个函数作为一个输出维度。此外,也可以对一个哈希函数选取topK个最小的值,每个K作为一个输出维度。得出每个url的哈希签名后,我们用如下公式来计算jaccard相似度:

Jaccard Sim = (minh(A)K∩minh(B)K) / (minh(A)K∪minh(B)K)

即查看A,B最小值集合的重叠程度。

以第一种做法为例,假设url A的访客们通过第一个哈希函数得到的最小值为3, 通过第二个哈希函数得到的最小值为7,那么url A的表示为(3,7)。如果url B的值为(5,3),那么A和B的相似度为1/3。在数据量极大的情况下,这种做法得出的最小值的随机性仍然较大,计算出的相似度仍然有很大概率为0。一种解决方式为计算降维后的url A,B的cosine相似度。比如cosine((3,7),(5,3))。


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