一、 前言

最近在工作中需要对海量数据进行相似性查找,即对微博全量用户进行关注相似度计算,计算得到每个用户关注相似度最高的TOP-N个用户,首先想到的是利用简单的协同过滤,先定义相似性度量(cos,Pearson,Jaccard),然后利用通过两两计算相似度,计算top-n进行筛选,这种方法的时间复杂度为O(n^2)(对于每个用户,都和其他任意一个用户进行了比较)但是在实际应用中,对于亿级的用户量,这个时间复杂度是无法忍受的。同时,对于高维稀疏数据,计算相似度同样很耗时,即O(n^2)的系数无法省略。这时,我们便需要一些近似算法,牺牲一些精度来提高计算效率,在这里简要介绍一下MinHashing,LSH。

二、 MinHashing

Jaccard系数是常见的衡量两个向量(或集合)相似度的度量:

为方便表示,我们令A和B的交集的元素数量设为

,A和B的非交集元素数量设为
,则Jaccard相似度即为

所谓的MinHsah,即进行如下的操作:

1. 对A、B的n个维度,做一个随机排列(即对索引

随机打乱)

2. 分别取向量A、B的第一个非0行的索引值(index),即为MinHash值

得到AB的MinHash值后,可以有以下一个重要结论:

以下是证明:

在高维稀疏向量中,考虑AB在每一维的取值分为三类:

1. A、B均在这一维取1(对应上述元素个数为

2. A、B只有一个在这一维取1(对应上述元素个数为

3. A、B均取值为0

其中,第三类占绝大多数情况,而这种情况对MinHash值无影响,第一个非零行属于第一类的情况的概率为

,从而上面等式得证。

另外,按照排列组合的思想,全排列中第一行为第一类的情况为

,全排列为
,即将n维向量全排列之后,对应的minHash值相等的次数即为Jaccard相似度。

但是在实际情况中,我们并不会做

次排列,只做m次(m一般为几百或者更小,通常远小于n),这样,将AB转为两个m维的向量,向量值为每次排列的MinHash值。

这样计算两个Sig向量相等的比例,即可以估计AB的Jaccard相似度(近似保持了AB的相似度,但是不能完全相等,除非全排列,对于这种利用相似变换相似空间的方法,需要设计哈希函数,而一般的哈希函数无法将满足相似向量哈希后的值相似)。

在实际实现中,m次排列通常通过一个针对索引的哈希来达到hash的效果,即MinHashing算法,实现可参考Spark实现细节

http://spark.apache.org/docs/2.2.0/api/java/org/apache/spark/ml/feature/MinHashLSH.html​spark.apache.org

三、 LSH

上面的MinHashing解决了高维稀疏向量的运算,但是计算两两用户的相似度,其时间复杂度仍然是O(n^2),显然这个计算量还没有得到改善,这时我们如果能将用户分到不同的桶,只比较可能相似的用户,即相似用户以较大可能分到同一个桶内,这样不相似的用户基本不会发生比较,降低计算复杂度,LSH即为这样的方法。

LSH方法基于这样的思想:在原空间中很近(相似)的两个点,经过LSH哈希函数的映射后,有很大概率它们的哈希是一样的;而两个离的很远(不相似)的两个点,映射后,它们的哈希值相等的概率很小。

基于这样的思想,LSH选择的哈希函数即需要满足下列性质:

对于高维空间的任意两点,

  • 如果

    ,则
    的概率不小于
  • 如果
    ,则
    的概率不大于

其中,

大于1,

满足这样性质的哈希函数,被称为

本文介绍的LSH方法基于MinHashing函数。

LSH将每一个向量分为几段,称之为band,如下图,图源:

http://www.mmds.org/mmds/v2.1/ch03-lsh.pdf​www.mmds.org

每一个向量在图中被分为了b段(每一列为一个向量),每一段有

行MinHash值。在任意一个band中分到了同一个桶内,就成为候选相似用户(拥有较大可能相似)。

设两个向量的相似度为t,则其任意一个band所有行相同的概率为

,至少有一行不同的概率为

则所有band都不同的概率为

,至少有一个band相同的概率为
。其曲线如下图所示,图源

http://www.mmds.org/mmds/v2.1/ch03-lsh.pdf​www.mmds.org

图中变化最抖的点

近似为
,其中,s作为阈值可以卡具体为多少是我们才将其分到一个桶中,即人工设定
来确定这里的
。如图例,对于
时,其阈值为0.6,其中,绿色为假正例率(相似度很低的两个用户被哈希到同一个桶内),蓝色为假负例率(真正相似的用户在每一个band上都没有被哈希到同一个桶内),可以设置
调整
越大,效率越高,假正例率越低,假负例率越高。

四、后记

接触LSH是一个很偶然的工作中的小需求,感慨其在海量高维稀疏数据中有很好的应用场景(文本,图片,结构数据均可以用),速度快,计算复杂度低,感慨其embedding转换的巧妙,鉴于本人水平和精力着实有限,没有搞懂的地方其实还很多,没有证明MinHashing方法满足LSH方法的性质,也没有搞懂BloomFilter算不算也是一种LSH方法的哈希函数,Simhash也没有精力去研读。知乎用户 @hunter7z 的答案给了我不少的启发 ,感谢。

查了很多资料,作此读书笔记,权且抛砖引玉。

参考文献:

1. Mining of Massive Datasets

2. hunter7z:大规模数据的相似度计算:LSH算法

3. MinHashLSH (Spark 2.2.0 JavaDoc)

4. Locality Sensitive Hashing

5. 图像检索(6):局部敏感哈希索引(LSH) - Brook_icv - 博客园

mysql 查找相似数据_局部敏感哈希LSH(Locality-Sensitive Hashing)——海量数据相似性查找技术...相关推荐

  1. 局部敏感哈希(Locality Sensitive Hashing)二三问[2]

    #写在前面的话 今天的这一章有几个目的,一是回答一下各位网友在各大博客上提出的问题,然后其他博主没有回答的问题.二是纠正一些别人在写局部敏感哈希时候出现的错误.就是这么贴心有没有. #假装自己是正文的 ...

  2. 局部敏感哈希算法(Locality Sensitive Hashing)

    from:https://www.cnblogs.com/maybe2030/p/4953039.html 阅读目录 1. 基本思想 2. 局部敏感哈希LSH 3. 文档相似度计算 局部敏感哈希(Lo ...

  3. 最近邻和K近邻及其优化算法LSH(局部敏感哈希,Locality Sensitive Hashing) Kd-Tree

    引言 在处理大量高维数据时,如何快速地找到最相似的数据是一个比较难的问题.如果是低维的小量数据,线性查找(Linear Search)就可以解决,但面对海量的高维数据集如果采用线性查找将会非常耗时.因 ...

  4. 【算法】局部敏感哈希 LSH 的 Python 实现

    一.哈希算法 普通的哈希算法:把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值. 最理想的是所有不同的输入都可以映射到散列值,但是存在这种可能性的.当不同的输入映射到相同的散列值时, ...

  5. LSH(Locality Sensitive Hashing)局部敏感Hash

    文章目录 LSH 的哈希函数族(Hash Family)定义 LSH 的查找过程 LSH 常见的 Hash Function(降维) min-hash 具体介绍: min-Hash的局部敏感哈希算法( ...

  6. 如何使用局部敏感哈希(LSH)算法进行特征降维?

    这篇博客只关注局部敏感哈希的降维过程,也不涉及理论证明. 1. 局部敏感哈希算法 1.1 算法简介   传统的哈希(Hashing)算法通过映射函数将记录的存储位置与记录的关键字关联起来,实现记录的快 ...

  7. 局部敏感哈希(lsh)包安装成功

    我们需要安装一个lsh包 直接 pip install lsh 报错 error: Microsoft Visual C++ 14.0 is required. Get it with "M ...

  8. 局部敏感哈希-Locality Sensitive Hashing

    局部敏感哈希 转载请注明http://blog.csdn.net/stdcoutzyx/article/details/44456679  在检索技术中,索引一直需要研究的核心技术.当下,索引技术主要 ...

  9. R语言实现︱局部敏感哈希算法(LSH)解决文本机械相似性的问题(一,基本原理)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 私认为,文本的相似性可以分为两类:一类是机械相 ...

最新文章

  1. Metasploit 之 webshell 提权
  2. Python输出黄金分隔数列前n项。 黄金分隔数列由Fibonacci数列相邻两项之比组成:1/1,1/2,2/3,3/5,5/8,...其取值逐渐接近黄金分隔数。
  3. python的模块文档_python查看模块文档
  4. mysql卸载时弹框,win10卸载mysql5安装mysql8
  5. (转)MyBatis框架的学习(六)——MyBatis整合Spring
  6. Python基础篇:Python 程序流程控制,让你的代码有理有据
  7. (自然语言处理)语料、文本数据集清单
  8. 区块链 Fisco bcos 智能合约(18)-FISCO BCOS的速度与激情:性能优化方案最全解密
  9. iOS设备是否越狱的判断代码
  10. 探讨破解3G今日困局之策
  11. win10 FTP搭建全过程
  12. Java测试框架-junit5详解
  13. fild与fmul的问题
  14. 乐鑫esp8266学习rtos3.0笔记第9篇:整理分享那些我在项目中常用的esp8266 rtos3.0版本的常见驱动,Button按键长短按、PWM平滑调光等。(附带demo)
  15. 用html做七巧板的方法,纯HTML5绘制的七巧板
  16. Lua学习第二课_初探lua和lua语法
  17. 国嵌Linux视频驱动开发
  18. 小米电视刷android系统升级,小米电视2系统版本多久更新一次
  19. 图像质量评价常用数据库下载 |LIVE|MICT|CSIQ|TID2013|CID2013|CCID2014|LIVE-Challenge|LIVE-MultiDistortion|IVC_sub
  20. 【我的代码】前端遇上After Effects --- 鼠标悬浮效果(上)

热门文章

  1. Google 推出 Android 11 的 Developer Preview 3 版本
  2. 声网 Agora Share:从天到秒级效率提升,一切都为服务好 15 万+应用
  3. 12 大 AI App 技术创意,教你如何在 2020 年赚到钱
  4. 8 月社群专属福利活动开启!进群免费领取开发视频课程!
  5. Oracle 痛裁程序员,阿里云坐收渔翁利?
  6. 高通誓要“逼杀”苹果!
  7. Visual Studio 与 Eclipse,谁是最强 IDE?
  8. 为什么微信小程序也能做游戏?
  9. Kafka必须掌握的核心技术:简述Java线程池的作用和实现方式
  10. java需要下载哪些,全网最新