使用LSH来计算余弦相似度

使用LSH来减少余弦相似度开销计算
LSH-余弦相似度详解

原理,在余弦空间中构造一条直线(平面)
当两个向量在直线一边时,认为这两个向量较相似。

那么我们有两个向量A,B,和一条直线a。
假设A在直线a上方,标记为1
B在直线a下方,标记为0

因此我们认为A和B不相似。

为了更准确的估计,我们构造了多条直线b,c,d,e
那么A的标记可能为,1,1,1,0,0
B的标记为,0,1,1,0,0

直观上来看A和B就比较相似了

在下文中,我们考虑(所有标记都相同的向量)才会相似,当查找A时,假设A的标记为,1,1,1,0,0,那么我们把所有,1,1,1,0,0标记的向量都取出来,与A实际进行相似度计算(cos)

目的:用近似来简化计算(减少搜索范围,加速搜索)

假如每个向量有128维度,有1000个向量
那么我们想找所有近似,就要两两计算
要1000乘(1000-1)/2 次

现在我们构造10条直线(平面),同样每个直线128维度,
那么1000个向量计算标记,需要计算1000乘10次,每一个向量得到一个10维的标记

一共有1000个向量,平均每个标记有1000/1024 = 1 个向量。

我们只把同标记的进行比较,即只认为同标记的是有可能相似的,这样一个标记平均保存一个向量。

当待查询向量输入后,计算向量的标记,再看看同标记是否保存了其他向量,计算此标记保存向量和查询向量的相似度,因为平均一个标记保存一个向量,那么计算了1000乘1次

为了减少误差,我们将这样的10条直线多构造几对,称为bands,假设构造16组直线,只要有一组直线构成的标记相同,我们就会查询保存的向量。

那么我们计算标记时,需要计算1000乘10乘16次,也就是1000乘160次。(得到1000个向量的16组标记,将向量保存在标记中)

得到标记后,再将向量的标记与相同标记的向量比较,平均16组标记每组标记保存一个向量,计算了1000乘1乘16,也就是1000乘16次

(当然,实际去重操作次数会少一些,先来的向量有标记并且保存,后来的向量计算标记后,发现了此标记的向量中,有相似的,那么后来的向量就作为重复项去掉,不保存在标记中,这样标记保存的向量数量会有所减少)

(如果实际不进行去重,那么就每条向量都保存吧)

现在有结果了,我们吧1000乘999/2 次匹配计算简化成了1000乘176次匹配,看起来减少的不是特别多

但如果我们时10万条向量呢

我们就会把10万乘10万计算简化成10万乘(160+10万/1024乘16)次,极大的简化了计算

(构造16组标记,每组标记为10条直线,每组标记中每个标记保存的向量10万/1024个,乘以16组)

如果我的理解对你的理解有所帮助,请同学帮忙点赞

如果有疑问,我会尽快回复

(个人总结,请勿转载)

你可能感兴趣的:(nlp)