• 【搜索引擎(五)】局部敏感哈希


    1.介绍

        哈希是一种常用的数据摘要方法,可以把大段的数据映射成固定长度的字符串。在查找某个文档的时候,我们不希望每一次都比较大段的数据,以此来确定文档的位置,这样太过浪费生命了。只要实现计算好文档的哈希值,就可以只通过比较两个文档的哈希,查出匹配的文档,从而大大减少检索的时间。

        传统的hash方法,比如md5,其设计的目的是为了让整个分布尽可能地均匀,输入内容哪怕只有轻微变化,hash值就会发生很大的变化,这跟它本来是为了跟哈希表配合有关的。但是由于搜索引擎的发展,我们很容易遇到这种情景,即我们为了加快搜索的效率会利用索引,但是索引本身如果直接使用哈希,可无法找到内容相近的,而只能找到完全匹配的,这在现实中是很难满足的。

        现实中很多查找问题都是寻找相似集,而非完美匹配集。

        这种问题最后是在高维空间里查找,例如:1.两篇有相似单词的文章;2. 两个消费了相似物品的顾客;3.两张有相似特征的图片。

    2. LSH的作用

        我们需要采用一些类似索引的技术来加快查找过程,通常这类技术称为最近邻查找(Nearest Neighbor,AN),例如K-d tree;或近似最近邻查找(Approximate Nearest Neighbor, ANN),例如K-d tree with BBF, Randomized Kd-trees, Hierarchical K-means Tree。而LSH是ANN中的一类方法。

        LSH的基本思想是:将原始数据空间中的两个相邻数据点通过相同的映射或投影变换(projection)后,这两个数据点在新的数据空间中仍然相邻的概率很大,而不相邻的数据点被映射到同一个桶的概率很小。

    3. 实现

        实现Locality Sensitive Hashing的重要工具只有三个。

        Jaccard距离、Min-Hashing函数、桶映射

        算法流程是:Documents -> Shingle -> Min-hashing产生签名(摘要)->检索.其中Shingle解释如下:

      Shingling

      shingling是一种文本的预处理方式。对文档分别进行Shingling(将待查询的字符串集进行映射,映射到一个集合里,如字符串"abcdeeee", 映射到集合"(a,b,c,d,e)", 注意集合中元素是无重复的,这一步骤就叫做Shingling, 意即构建文档中的短字符串集合,即shingle集合。类比倒排索引,我们可以得到类似的矩阵:

        3.2 度量和函数

      A. C1和C2的Jaccard 距离:

        B. 重要的哈希函数     Min-Hashing

        输入值是一个矩阵:shingle(文本单元)x文档矩阵,值(i,j)表示词si在文档dj中出现与否。

        这样文档的哈希值长度是我们设定的置换个数。在下面的例子中,文档1,2,3,4的哈希值分别是221,112,241,112

        找到一个哈希函数,如果sim(C1,C2) 很高, 那么很高概率h(C1) = h(C2)

        如果sim(C1,C2)低,那么很高概率h(C1) ≠h(C2)。

        Min-hashing函数:    hπ(C), 表示在经过π置换的C列中为1的方格的第一个下标。   注:π置换(a1,a2,…)会将向量X中的xi置换到位置ai(i=1,2,3…)

     根据这种定义,有如下性质:选择一个随机π,则Pr[hπ(C1) = hπ(C2)] = sim(C1,C2)

        证明: 设y∈X, 因为Pr[π(y) = min(π(X)) ] = 1/|X|,(这个性质下面没有用到)

             若 π(y) = min(π(C1C2)), (即y在置换后是新向量里的最小为1下标),

             则 要么π(y) = min(π(C1) 且 y∈C1, 要么π(y) = min(π(C1) 且y∈ C2

             这两种情况同时成立的概率为

                    Pr[min(π(C1) = min(π(C2)] = |C1 ∩C2| / |C1C2| = sim(C1, C2)

             这个概率反映的是随机置换的结果。

        

        Min-Hash Signature

    用sig(C)表示文档编码C的签名, 则sig(C)[i] = min(πi(C)), 如100个随机置换得到的签名需要100 个byte。

       

    C. LSH算法

          1. 先看产生签名的实现方法:

    for each column C and hash-func ki keep a slot of the min-hash value
    	sig(C)[i] = ∞
    	Scan rows looking for 1
    		Suppose row j has 1 in column C  即: C[j][i] = 1
    		Then for each ki:
    		    if ki(j) < sig(C)[i], then sig(C)[i] <- ki(j)  // 用每个置换的下
    

      上面是签名算法,而LSH 算法是检索的算法,给定一个相似度值s和文档,找出相似文档。

            由于检索的方法是很naïve的,下面我们只需要验证LSH的性质,并且给出实现方法即可。

    问题:

    给定s和n x m矩阵M, 先在矩阵M (shingle * document)中找出候选对

            n = |shingle|, m = |document|

            

            把矩阵分割成b个band(条带),每个带有整数个数 r = M / b

    样例:

    假设有100,000个文档, 每个签名是100个整数(100 bytes)

            签名占了40 Mb。

            b = 20, a = 5, s=0.8.

            相似度s >= 0.8的时候, 验算至少有一个band是相同的概率:

    sim(C1, C2) = 0.8, (0.8)^5 = 0.328,

        1 – (0.328)^20 = 0.00035, 即sim(C1, C2) = 0.8 的时候至少有一个band相同的概率是99.965%。

            同样地, 计算sim(C1,C2) = 0.3的时候可以验算得到其概率很低。

        

    4. 参考:

    J. Leskovec, A. Rajaraman, J. Ullman: Mining of Massive Datasets,http://www.mmds.org/mmds/v2.1/ch03-lsh.pdf

        

  • 相关阅读:
    尾递归
    gcc/g++ 命令
    GCC输出带C源代码的汇编文件
    linux下Ctrl命令组合
    静态链接库(lib)、动态链接库(dll)与动态链接库的导入库(lib)
    VS2010-MFC(菜单:菜单及CMenu类的使用)
    VS2010-MFC(菜单:VS2010菜单资源详解)
    VS2010-MFC(常用控件:标签控件Tab Control 下)
    VS2010-MFC(常用控件:标签控件Tab Control 上)
    VS2010-MFC(常用控件:树形控件Tree Control 下)
  • 原文地址:https://www.cnblogs.com/wangzming/p/7825730.html
Copyright © 2020-2023  润新知