阅读目录html
局部敏感哈希(Locality Sensitive Hashing,LSH)算法是我在前一段时间找工做时接触到的一种衡量文本类似度的算法。局部敏感哈希是近似最近邻搜索算法中最流行的一种,它有坚实的理论依据而且在高维数据空间中表现优异。它的主要做用就是从海量的数据中挖掘出类似的数据,能够具体应用到文本类似度检测、网页搜索等领域。算法
1. 基本思想
局部敏感哈希的基本思想相似于一种空间域转换思想,LSH算法基于一个假设,若是两个文本在原有的数据空间是类似的,那么分别通过哈希函数转换之后的它们也具备很高的类似度;相反,若是它们自己是不类似的,那么通过转换后它们应仍不具备类似性。函数
哈希函数,你们必定都很熟悉,那么什么样的哈希函数能够具备上述的功能呢,能够保持数据转化先后的类似性?固然,答案就是局部敏感哈希。post
2. 局部敏感哈希LSH
局部敏感哈希的最大特色就在于保持数据的类似性,咱们经过一个反例来具体介绍一下。spa
假设一个哈希函数为Hash(x) = x%8,那么咱们如今有三个数据分别为25五、257和1023,咱们知道255和257自己在数值上具备很小的差距,也就是说它们在三者中比较类似。咱们将上述的三个数据经过Hash函数转换:htm
Hash(255) = 255%8 = 7;blog
Hash(257) = 257%8 = 1;ci
Hash(1023) = 1023%8 = 7;文档
咱们经过上述的转换结果能够看出,自己很类似的255和257在转换之后变得差距很大,而在数值上差不少的255和1023却对应相同的转换结果。从这个例子咱们能够看出,上述的Hash函数从数值类似度角度来看,它不是一个局部敏感哈希,由于通过它转换后的数据的类似性丧失了。字符串
咱们说局部敏感哈希要求可以保持数据的类似性,那么不少人怀疑这样的哈希函数是否真的存在。咱们这样去思考这样一个极端的条件,假设一个局部敏感哈希函数具备10个不一样的输出值,而如今咱们具备11个彻底没有类似度的数据,那么它们通过这个哈希函数必然至少存在两个不类似的数据变为了类似数据。从这个假设中,咱们应该意识到局部敏感哈希是相对的,并且咱们所说的保持数据的类似度不是说保持100%的类似度,而是保持最大可能的类似度。
对于局部敏感哈希“保持最大可能的类似度”的这一点,咱们也能够从数据降维的角度去考虑。数据对应的维度越高,信息量也就越大,相反,若是数据进行了降维,那么毫无疑问数据所反映的信息必然会有损失。哈希函数从本质上来看就是一直在扮演数据降维的角色。
3. 文档类似度计算
咱们经过利用LSH来实现文档的类似度计算这个实例来介绍一下LSH的具体用法。
3.1 Shingling
假设如今有4个网页,咱们将它们分别进行Shingling(将待查询的字符串集进行映射,映射到一个集合里,如字符串“abcdeeee", 映射到集合”(a,b,c,d,e)", 注意集合中元素是无重复的,这一步骤就叫作Shingling, 意即构建文档中的短字符串集合,即shingle集合。),获得以下的特征矩阵:
其中“1”表明对应位置的Shingles在文档中出现过,“0”则表明没有出现过。
在衡量文档的类似度中,咱们有不少的方法去完成,好比利用欧式距离、编辑距离、余弦距离、Jaccard距离等来进行类似度的度量。在这里咱们运用Jaccard类似度。接下来咱们就要去找一种哈希函数,使得在hash后尽可能还能保持这些文档之间的Jaccard类似度,即:
咱们的目标就是找到这样一种哈希函数,若是原来文档的Jaccard类似度高,那么它们的hash值相同的几率高,若是原来文档的Jaccard类似度低,那么它们的hash值不相同的几率高,咱们称之为Min-hashing(最小哈希)。
3.2 Min-hashing
Min-hashing定义为:特征矩阵按行进行一个随机的排列后,第一个列值为1的行的行号。举例说明以下,假设以前的特征矩阵按行进行的一个随机排列以下:
元素 |
S1 |
S2 |
S3 |
S4 |
他 |
0 |
0 |
1 |
0 |
成功 |
0 |
0 |
1 |
1 |
我 |
1 |
0 |
0 |
0 |
减肥 |
1 |
0 |
1 |
1 |
要 |
0 |
1 |
0 |
1 |
最小哈希值:h(S1)=3,h(S2)=5,h(S3)=1,h(S4)=2.
为何定义最小hash?事实上,两列的最小hash值就是这两列的Jaccard类似度的一个估计,换句话说,两列最小hash值同等的几率与其类似度相等,即P(h(Si)=h(Sj)) = sim(Si,Sj)。为何会相等?咱们考虑Si和Sj这两列,它们所在的行的全部可能结果能够分红以下三类:
(1)A类:两列的值都为1;
(2)B类:其中一列的值为0,另外一列的值为1;
(3)C类:两列的值都为0.
特征矩阵至关稀疏,致使大部分的行都属于C类,但只有A、B类行的决定sim(Si,Sj),假定A类行有a个,B类行有b个,那么sim(si,sj)=a/(a+b)。如今咱们只须要证实对矩阵行进行随机排列,两个的最小hash值相等的几率P(h(Si)=h(Sj))=a/(a+b),若是咱们把C类行都删掉,那么第一行不是A类行就是B类行,若是第一行是A类行那么h(Si)=h(Sj),所以P(h(Si)=h(Sj))=P(删掉C类行后,第一行为A类)=A类行的数目/全部行的数目=a/(a+b),这就是最小hash的神奇之处。
Min-hashing的具体作法能够根据以下进行表述:
返回到咱们的实例,咱们首先生成一堆随机置换,把特征矩阵的每一行进行置换,而后hash function就定义为把一个列C hash成一个这样的值:就是在置换后的列C上,第一个值为1的行的行号。以下图所示:

