局部敏感哈希(Locality-Sensitive Hashing, LSH)

局部敏感哈希是工程实际中主流的快速 Embedding 向量最近邻搜索方法,它属于近似最近邻查找(Approximate Nearest Neighbor, ANN)的一种。

1 局部敏感哈希的基本原理

局部敏感哈希的基本思想是:让相邻的点落入同一个“桶”中,在进行最近邻搜索时,只需要在一个桶,或者相邻的几个桶内进行搜索。

LSH 算法基本原理是:用一个Hash 方法将数据从原空间映射到一个新的空间中,使得在原空间相似(距离近)的数据,在新的空间中也相似的概率很大,而在原空间不相似(距离远)的数据,在新的空间中相似的概率很小。

例如我们基于欧式距离进行最近邻搜索时,原空间为高维的欧式空间,映射的新的空间为一个低维欧式空间,我们容易推得:在原高维空间中相似的点,在低维的空间肯定也相似,但原本不相似的点在低维空间中是有一定的小概率成为相似的点的。

1.1 哈希函数(Hash Functions)应满足的条件

h ( x ) h(x) h(x) 表示样本 x x x 的哈希变换, x x x y y y 为两个任意的样本, d ( x , y ) d(x,y) d(x,y) x x x y y y 之间的距离, d 1 d_1 d1 d 2 d_2 d2 为两个常量值,且 d 1 < d 2 d_1<d_2 d1<d2 p 1 p_1 p1 p 2 p_2 p2 为两个介于 0 与 1 之间的常量值,若 h ( x ) h(x) h(x) 满足以下两个条件,则称哈希函数 h ( x ) h(x) h(x) ( d 1 , d 2 , p 1 , p 2 ) (d_1,d_2,p_1,p_2) (d1,d2,p1,p2)-senstive

  1. 如果 d ( x , y ) ≤ d 1 d(x,y)\leq d_1 d(x,y)d1,则 h ( x ) = h ( y ) h(x)=h(y) h(x)=h(y) 的概率至少为 p 1 p_1 p1
  2. 如果 d ( x , y ) ≥ d 2 d(x,y)\geq d_2 d(x,y)d2,则 h ( x ) = h ( y ) h(x)=h(y) h(x)=h(y) 的概率至多为 p 2 p_2 p2

通过一个或多个 ( d 1 , d 2 , p 1 , p 2 ) (d_1,d_2,p_1,p_2) (d1,d2,p1,p2)-senstive 的哈希函数对原始数据集合进行哈希运算,得到一个或者多个哈希表的过程就称为是 局部敏感哈希

1.2 LSH 的多桶策略

因为哈希映射过程损失了部分的距离信息,如果只使用一个哈希函数进行分桶,则会存在相似点误判的情况,解决的方式是采用多( m m m)个哈希函数同时进行分桶,同时掉进 m m m 个哈希函数同一个桶中的两个点,是相似点的概率则大大增加。

通过分桶找到候选集合后,就可以在有限的候选集合中通过遍历的方法找到最近的 K K K 个近邻。

在用多个哈希函数进行分桶时,应该通过“与”(And/交集)操作还是“或”(Or/并集)操作生成最终的候选集合呢?

  • 如果通过“与”操作生成候选集,则候选集合中近邻点的准确率将提高,候选集合的样本数量也会减少,从而使最后遍历的时间缩短,但有可能会漏掉一些近邻点;
  • 如果通过“或”操作生成候选集,那么候选集合的规模会变大,遍历的计算开销则会增加,但好处是候选集中近邻点的召回率会提高;

在实际应用中, m m m 的取值、使用“与”还是“或”需要在准确率和召回率之间权衡。

1.3 LSH 的特点

LSH 是一种从海量的高维数据集中查找近似 K K K 近邻的方法,需要注意的是,LSH 并不能保证一定能查找到最相邻的数据,

2 局部敏感哈希的基本流程

2.1 离线建立索引

  1. 根据对准确率和召回率的需求,确定哈希函数的个数 m m m,以及每个哈希函数分桶的个数 w w w
  2. 选取 m m m 个满足 ( d 1 , d 2 , p 1 , p 2 ) (d_1,d_2,p_1,p_2) (d1,d2,p1,p2)-senstive 的哈希函数
  3. 将所有数据经过 LSH 哈希函数映射到相应的桶中,构成多个哈希表

2.2 在线查找

  1. 将查询数据经过 m m m 个哈希函数得到各个相应的桶号
  2. 根据“与”或者“或”操作对桶进行合并,获得最终的候选集
  3. 计算查询数据与候选集合中每个数据点之间的相似度或者距离,返回最近的 K K K 个近邻

从上面的流程可以看出,在线查找的时间包括两个部分:

  1. 步骤1中通过 LSH 哈希函数计算桶号的时间
  2. 步骤3中遍历所有候选点,计算与查询数据点距离的时间

3 不同距离度量下的 LSH

3.1 欧式距离

假设 v v v 是高维空间中的 k k k 维向量, r r r 是一个随机向量,则内积操作可以将 v v v 映射到一维空间:

h ( v ) = v ⋅ r h(v)=v\cdot r h(v)=vr

因为一维空间也能部分保留高维空间的近似距离信息,因此就可以利用下面的哈希公式进行分桶:

h r , b ( v ) = ⌊ v ⋅ r + b w ⌋ h^{r,b}(v)=\lfloor \frac{v\cdot r + b}{w} \rfloor hr,b(v)=wvr+b

其中, ⌊ ⌋ \lfloor \rfloor 是向下取整操作, w w w 是分桶宽度, b b b 0 0 0 w w w 之间的一个均匀分布的随机变量,目的是避免分桶边界固化。

3.2 余弦距离

余弦距离衡量的是两个向量夹角的大小,夹角越小,则两个向量越相似。

基于余弦距离的 LSH 哈希函数为:

H ( v ) = s i g n ( v ⋅ r ) H(v)=sign(v\cdot r) H(v)=sign(vr)

其中, r r r 是一个随机向量, v ⋅ r v\cdot r vr 可以看作是将 v v v r r r 上进行投影。

  • 12
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Python实现Locality-sensitive hashingLSH)算法的示例代码: ```python import numpy as np import hashlib # 生成一些随机数据 data = np.random.rand(1000, 10) # 设置LSH参数 num_tables = 10 num_hashes = 5 hash_size = 10 # 初始化LSH表 tables = [{} for _ in range(num_tables)] hash_funcs = [hashlib.sha1, hashlib.md5, hashlib.sha256, hashlib.blake2s, hashlib.sha3_256] # 建立LSH表 for i in range(num_tables): for j in range(1000): hash_values = [] for k in range(num_hashes): hash_value = hash_funcs[k](data[j].tostring()).hexdigest()[:hash_size] hash_values.append(hash_value) hash_key = ''.join(hash_values) if hash_key not in tables[i]: tables[i][hash_key] = [] tables[i][hash_key].append(j) # 查询近似相似的数据点 query = np.random.rand(10) query_hash_values = [] for k in range(num_hashes): hash_value = hash_funcs[k](query.tostring()).hexdigest()[:hash_size] query_hash_values.append(hash_value) query_hash_key = ''.join(query_hash_values) similar_points = set() for i in range(num_tables): if query_hash_key in tables[i]: similar_points.update(tables[i][query_hash_key]) print(similar_points) ``` 这段代码生成一个大小为1000的随机数据集,并使用LSH算法建立10个LSH表。然后,给定一个查询点,代码计算查询点的哈希值,并在每个LSH表中查找具有相同哈希值的数据点。最后,代码返回所有这些数据点的索引,这些数据点与查询点相似。在实际应用中,可以使用更复杂的哈希函数和更多的LSH表来提高准确性和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值