E2LSH的原理与实现

来源:互联网 发布:程序员壁纸高清 编辑:程序博客网 时间:2024/05/01 21:44

E2LSH

E2LSH一个是用来解决高维空间近邻搜索问题的工具包。E2LSH实现了R-NN问题的随机化解决方案,即(R, 1 −δ )-near neighbor:每个满足||q-p||2 ≤ R的点p被报告的概率至少为1 −δ。E2LSH的实现基于基本的LSH模式。

Hash函数族

E2LSH使用基于p-stable分布的哈希函数族:ha,b=[a⃗ v⃗ +bw]其中a是一个d维向量,a的每一项是从p-stable分布中随机独立选取的;b是从[0, w]中均匀选取的一个实数。有了一组确定的a和b,也就产生了一个相应的ha,b(v)RdZ,将一个d维的点向量v映射到一个整数。

LSH基本过程

定义g函数:gi(v)=(h1(v),h2(v),...,hk(v))1iL,对应L个哈希表,每个g函数随机独立产生。每个g函数由在哈希函数族ha,b中随机独立选取的k个h函数组成。g函数的值对应具体的哈希桶。

使用LSH进行R-NN或k-NN搜索的过程主要分为建立索引和查询两步。建立索引时,对数据集中的每个点v∈P,计算其L个g函数值,并将其存入L个表中对应的哈希桶内。查询时,同样计算查询点q的L个g函数值,则找到q所在的L个哈希桶,计算这些哈希桶中的点与q的距离,找到规定距离R之内的点(R-NN),或k个距离最近的点(k-NN)。

参数的确定

L的确定

参数L的确定需要根据前面提到的(R, 1 −δ )-near neighbor的定义来解决,即一个近邻点被报告的概率至少为1 −δ。给定一个查询点q,近邻点v ∈ B(q,R),设p1= p(R),两点在某个桶中发生碰撞,即在一个g函数中两点的值相等,应满足:PrgG[g(q)=g(v)]pk1那么q和v在L个g函数中的值都不相等概率至多为(1pk1)L则q在至少一个g函数中与v的值相等的概率满足:1(1pk1)L1δ则L满足:Llogδlog(1pk1)。因为建立哈希表的时间与L的值正相关,因此为了减少建立索引的时间,L取下界。

k的确定

为了确定参数k的取值,首先需要知道使用E2LSH进行R-NN查询的查询时间分为两部分: - Tg=O(dkL):为查询点q计算L个gi1iL,函数并在各表中检索gi(p)桶的时间 - Tc=O(d#collisions):计算发生碰撞的桶中的点与查询点q之间的距离的时间其中#collisions是碰撞的桶的数目,\#collisions的期望为:E(#collisions)=L×vPpk(||qv||2)

根据Tg与Tc的计算方式可知,Tg随k的增大而增大,Tc随k的增大而减小,因此存在一个k的最优值使Tg+Tc最小。对不同的查询点q来说Tc是不同的,因此需要计算Tc的平均值,根据其平均值来估计k的最优值。E2LSH的实现是从查询集中随机选取一组样本点组成集合S,构造一个样本数据结构,并在这个数据结构上执行多次查询,测得一组真实的Tg与Tc的值,计算出Tc的平均值TcTc=qSTc(q)|S| ,则k取 Tg+Tc最小时对应的值。

gi的快速计算

在基本的LSH方法中,g函数的确定过程是在哈希函数族中均匀随机独立选取L个函数gi = (h(i)1 , … , h(i)k ),则需要O(d)时间计算hj(i)(q),O(dkL)时间计算g1(q), … , gL(q)。为了减少计算函数gi函数的时间,需重用一部分hj(i)函数,过程如下:
    - 设k为偶数,m是一个常数,定义函数ui=(h(i)1,...,h(i)k/2)
    - 重新定义gi=(ua,ub)1a<bm,即先产生k/2个h函数,再产生k/2个h函数(不再相互独立地选取,而是可重用,且已计算过的不需要重复计算),然后进行组合产生g函数
    - 总共的哈希表个数为L=C1m+C2m1+...+C11=m(m1)2
因为每个g函数需要两个u函数,因此需要在至少两个u函数内q和v的值相等时,才会产生一个相应的g函数使q和v的相应值相等,即在对应桶中发生碰撞。根据u函数的定义,有:

m个u函数中q和v的值都不相等的概率为 :(1pk/21)m

只有一个u函数中q和v的值相等的概率为:m×pk/21×(1pk/21)m1

根据前面内容,则新的gi下q在至少一个g函数中的值与v相等的概率满足:1(1pk/21)mm×pk/21×(1pk/21)m11δ

该式计算出来的L会比gi相互独立时计算的L值略大一点,但依然是O(log1/δpk1)的,新的时间复杂度降低为O(dkm)=O(dk√L)

实现细节

桶哈希

对数据集中的点使用哈希函数哈希之后得到g(v)=(h1(v),…,hk(v)),但将(h1(v),…,hk(v))直接存入哈希表,即占用内存,又不便于查找,为解决此问题,E2LSH使用了另外两个哈希函数:

    - h1Zk{0,...,tableSize1}
    - h2:Zk{0,...,C},C是一个大素数
h1的值作为哈希表的索引;h2作为链表中桶的索引。h1、h2的具体形式如下:

    - h1(a1,a2,...,ak)=((ki=1r'i×ai)mod prime)mod tableSize
    - h2(a1,a2,...,ak)=((ki=1r'i×ai)mod prime)
其中r’和r”是两个随机整数,C取值为232-5

由于每一个哈希桶(Hash Buckets)gi被映射成Zk,函数h1是普通哈希策略的哈希函数,函数h2用来确定链表中的哈希桶。(1)要在一个链表中存储一个哈希桶gi(v)=(x1,…,xk)时,使用指纹h2(x1,…,xk)构造的指纹代替向量(x1,…,xk),因此一个哈希桶gi(v)=(x1,…,xk)在链表中的存储的相关信息仅包括标识(identifier)指纹h2(x1,…,xk)和相应的原始数据点。(2)存储指纹值h2,而不是存储gi(v)=(x1,…,xk)的值有两个原因:首先,用h2(x1,…,xk)构造的指纹将单个哈希桶的存储空间从O(k)降到了O(1);其次,使用指纹值可以更快的检索哈希表中哈希桶。通过选取一个足够大的h2的值域来保证任意两个不同的哈希桶在链表中有不同的h2指纹值。具体过程如下图所示

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 2个月婴儿拉稀水怎么办 两个月的宝宝拉肚子怎么办 两天了不拉大便怎么办 25天的宝宝便秘怎么办 2个月宝宝便秘怎么办 猫拉绿色稀水怎么办 50天的宝宝便秘怎么办 人工喂养大便次数少怎么办 4个月宝宝肠炎怎么办? 三个月的宝宝拉肚子有奶瓣怎么办 吃米粉后不拉屎怎么办 宝宝拉绿色稀水怎么办 3个月宝宝肠胃炎怎么办 两个月婴儿拉水怎么办 3个月宝宝拉绿水怎么办 宝宝拉绿色的水怎么办 宝宝大便绿又水怎么办 8个月婴儿便秘怎么办 2个月婴儿便秘怎么办 四个月宝宝拉稀带有泡沫怎么办 六个月宝宝拉肚子怎么办拉水 婴儿拉的是沫怎么办 婴儿拉泡沫屎是怎么办 宝宝吃奶粉上火大便干燥怎么办 没满月的宝宝拉肚子怎么办 婴儿吃奶粉上火不大便怎么办 四个月宝宝拉沫怎么办 4个月小孩拉肚子怎么办 3个月的宝宝拉稀怎么办 宝宝没喝过奶粉怎么办 宝宝喝冰酸奶咳嗽了怎么办 7个月不爱喝奶怎么办 宝宝不认妈妈该怎么办 九个月宝宝不喝牛奶怎么办 吃羊肉和西瓜后怎么办 娃儿感冒了很咳怎么办 5岁娃儿经常感冒发烧怎么办 娃儿冷得发抖感冒怎么办 吃羊肉和茶后怎么办 宝宝胆汁酸高22怎么办 5个月发烧38度怎么办