显而易见的,如果签名矩阵的两列越相同,那么在多个行条中的向量相等的可能性也越大。这里给出一张图:
横轴是文档的Jaccard相似度,纵轴是成为候选对的概率。LSH可能出现伪反例,考虑这样一种情况,两列,只有b个分量不同,但这b行就恰巧均匀分布在b个行条之中,那它就成不了候选项。
我们前面提到过很多距离,比如欧氏距离、Jaccard距离、余弦距离、编辑距离,还有用于描述两个向量中不同分量个数的海明距离,那这里要说一下,什么叫做距离测度:
- 距离非负
- 只有点到自身的距离为0,其他距离都大于0
- 距离具有对称性
- 满足三角不等式,即两边之和大于第三边
接下来介绍几种更高相似度场景下的方法。首先是相等项,相等项其实较好处理,有这么几种方法,比如我们可以直接对整篇文档进行哈希,也可以先对文档头部的少许字符进行哈希处理,然后只对进入同一桶的文档进行比较,或者对所有的文档选择某些固定随机点,并且依据此来进行哈希处理。
然后是另一种更复杂的问题,就是我们怎样在大规模集合中,发现所有具有很高Jaccard相似度的集合对,比如大于0.9
为了简化问题,我们将全集中的所有元素按照某个固定次序排列,然后通过以该顺序列出其元素来表示任一集合。对于这样的串,任一元素的出现次数都不超过一次,而且,如果两个元素出现在两个不同的串中,那么这两个元素在两个串中的先后次序相同。
对于普通的文档,可以先将文档变成shingle集合,然后分配一个固定的shingle排序方法,并最终将每篇文档表示成该次序下的shingle列表。
为了解决上面的问题,我们可以基于长度进行过滤,将所有字符串按照长度排序,然后将每个字符串s与其在列表中后面不远的另一个字符串t进行比较。假定两个字符串Jaccard距离的下界是J,那其实s与t的Jaccard相似度的最多为Ls/Lt,L是对应串的长度。如果满足Jaccard相似度J的要求,那么Ls/Lt就必须大于等于J,或者说,只挑选Ls/Lt大于等于J的两个串进行比较。
除了长度,我们还可以像搜索引擎那样建立索引,我们可以为每个字符串s,选择前p个符号组成的前缀,在该前缀中每一个符号的索引中加入字符串s。
我们还可以额外使用位置信息等,这里就不详细说了。