海量数据集利用Minhash寻找相似的集合【推荐优化】

时间:2022-08-27 20:29:38

MinHash 首先它是一种基于 Jaccard Index 相似度的算法,也是一种 LSH 的降维的方法,应用于大数据集的相似度检索、推荐系统。下边按我的理解介绍下MinHash

问题背景

给出N个集合,找到相似的集合对,如何实现呢?直观的方法是比较任意两个集合。当N比较小时,比如K级,Jaccard算法可以在接受的时间范围内完成,比B级,甚至P级,那么需要的时间是不能够被接受的,举例:对于Indeeed美国的网站用户来说(五千万的访问量),在Mahout中的用户间相似度是通过在O(n2)复杂度下的用户间两两比较的来实现的,假设一台计算机每秒可以计算1Billion=1,000,000,000对集合是否相同,这个比较的数量将达到50,000,000**2次,约15小时,这是难以接受的!

Jaccard相似度计算虽然比较精确,但是推荐是一个非精确匹配问题(N个集合中只有少数几对集合相似,绝大多数集合都不等呢?那么根据上述算法,绝大多数检测的结果是两个结合不相似,可以说这些检测“浪费了计算时间”)。如果能找到一种算法,将大体上相似的集合聚到一起,缩小比对的范围,这样只用检测较少的集合对,就可以找到绝大多数相似的集合对,大幅度减少时间开销。虽然牺牲了一部分精度,但是如果能够将时间大幅度减少,这种算法还是可以接受的。

启发:贡献者戴夫格里菲思从一篇谷歌新闻学术论文上看到了最小哈希方法。最小哈希(或者最小独立序列)允许近似计算杰卡德相似度。将这一方法应用到两个用户都点击过的职位上,我们发现两个用户有更多共同的职位点击,那么他们的杰卡徳相似度就越高。为所有的用户对计算杰卡徳相似度的复杂度是O(n^2),而有了最小哈希后,我们可以将复杂度降到O(n)。

接下来的内容讲解如何使用Minhash和LSH(Locality-sensitive Hashing)来实现上述目的,在相似的集合较少的情况下,可以在O(n)时间找到大部分相似的集合对。

Jaccard相似度

判断两个集合是否相等,一般使用称之为Jaccard相似度的算法(后面用Jac(S1,S2)来表示集合S1和S2的Jaccard相似度)。举个列子,集合X = {a,b,c},Y = {b,c,d}。那么Jac(X,Y) = 2 / 3 = 0.67。也就是说,结合X和Y有67%的元素相同。下面是形式的表述Jaccard相似度公式:

Jac(X,Y) = |X∩Y| / |X∪Y|

也就是两个结合交集的个数比上两个集合并集的个数。范围在[0,1]之间。

Minhash降维

最近的一个由斯坦福大学教授莱斯科维克、拉贾罗曼和厄尔曼讲解的Coursera课程“挖掘海量数据集”,非常详细的解释了最小哈希。他们书的第三章——“挖掘海量数据集”,解释了最小哈希背后的数学证明原理。

Minhash可以帮助我们解决时间复杂度这个问题。举例:S1 = {a,d,e},S2 = {c, e},设全集U = {a,b,c,d,e}。集合可以如下表示:

行号

元素

S1

S2

类别

1

a

1

0

Y

2

b

0

0

Z

3

c

0

1

Y

4

d

1

0

Y

5

e

1

1

X

表1

表1中,列表示集合,行表示元素,值1表示某个集合具有某个值,0则相反(X,Y,Z的意义后面讨论)。Minhash算法大体思路是:采用一种hash函数,将元素的位置均匀打乱,然后将新顺序下每个集合第一个元素作为该集合的特征值。比如哈希函数h1(i) = (i + 1) % 5,其中i为行号。作用于集合S1和S2,得到如下结果:

行号

元素

S1

S2

类别

1

e

1

1

X

2

a

1

0

Y

3

b

0

0

Z

4

c

0

1

Y

5

d

1

0

Y

Minhash

e

e

表2

这时,Minhash(S1) = e,Minhash(S2) = e。也就是说用元素e表示S1,用元素e表示集合S2。那么这样做是否科学呢?进一步,如果Minhash(S1) 等于Minhash(S2),那么S1是否和S2类似呢?

论证:最小哈希(或者最小独立序列)允许近似计算杰卡德相似度

P(Minhash(S­1) = Minhash(S2)) = Jac(S1,S2)

在哈希函数h1均匀分布的情况下,集合S1的Minhash值和集合S2的Minhash值相等的概率等于集合S1与集合S2的Jaccard相似度,下面简单分析一下这个结论。

S1和S2的每一行元素可以分为三类:

l  X类 均为1。比如表2中的第1行,两个集合都有元素e。

l  Y类 一个为1,另一个为0。比如表2中的第2行,表明S1有元素a,而S2没有。

l  Z类 均为0。比如表2中的第3行,两个集合都没有元素b。

这里忽略所有Z类的行,因为此类行对两个集合是否相似没有任何贡献。由于哈希函数将原始行号均匀分布到新的行号,这样可以认为在新的行号排列下,任意一行出现X类的情况的概率为|X|/(|X|+|Y|)。这里为了方便,将任意位置设为第一个出现X类行的行号。所以P(第一个出现X类) = |X|/(|X|+|Y|) = Jac(S1,S2)。这里很重要的一点就是要保证哈希函数可以将数值均匀分布,尽量减少冲撞。

一般而言,会找出一系列的哈希函数,比如h个(h << |U|),为每一个集合计算h次Minhash值,然后用h个Minhash值组成一个摘要来表示当前集合(注意Minhash的值的位置需要保持一致)。举个列子,还是基于上面的例子,现在又有一个哈希函数h2(i) = (i -1)% 5。那么得到如下集合:

行号

元素

S1

S2

类别

1

b

0

0

Z

2

c

0

1

Y

3

d

1

0

Y

4

e

1

1

X

5

a

1

0

Y

Minhash

d

c

表3

所以,现在用摘要表示的原始集合如下:

哈希函数

S1

S2

h1(i) = (i + 1) % 5

e

e

h2(i) = (i - 1) % 5

d

c

表4

从表四还可以得到一个结论,令X表示Minhash摘要后的集合对应行相等的次数(比如表4,X=1,因为哈希函数h1情况下,两个集合的minhash相等,h2不等):

X ~ B(h,Jac(S1,S2))

X符合次数为h,概率为Jac(S1,S2)的二项分布。那么期望E(X) = h * Jac(S1,S2) = 2 * 2 / 3 = 1.33。也就是每2个hash计算Minhash摘要,可以期望有1.33元素对应相等。

所以,Minhash在压缩原始集合的情况下,保证了集合的相似度没有被破坏。

LSH – 局部敏感哈希

现在有了原始集合的摘要,但是还是没有解决最初的问题,仍然需要遍历所有的集合对,,才能所有相似的集合对,复杂度仍然是O(n2)。所以,接下来描述解决这个问题的核心思想LSH。其基本思路是将相似的集合聚集到一起,减小查找范围,避免比较不相似的集合。仍然是从例子开始,现在有5个集合,计算出对应的Minhash摘要,如下:

S1

S2

S3

S4

S5

区间1

b

b

a

b

a

c

c

a

c

b

d

b

a

d

c

区间2

a

e

b

e

d

b

d

c

f

e

e

a

d

g

a

区间3

d

c

a

h

b

a

a

b

b

a

d

e

a

b

e

区间4

d

a

a

c

b

b

a

c

b

a

d

e

a

b

e

表5

上面的集合摘要采用了12个不同的hash函数计算出来,然后分成了B = 4个区间。前面已经分析过,任意两个集合(S1,S2)对应的Minhash值相等的概率r = Jac(S1,S2)。先分析区间1,在这个区间内,P(集合S1等于集合S2) = r3。所以只要S­1和S2的Jaccard相似度越高,在区间1内越有可能完成全一致,反过来也一样。那么P(集合S1不等于集合S2) = 1 - r3。现在有4个区间,其他区间与第一个相同,所以P(4个区间上,集合S1都不等于集合S2) = (1 – r3)4。P(4个区间上,至少有一个区间,集合S1等于集合S2) = 1 - (1 – r3)4。这里的概率是一个r的函数,形状犹如一个S型,如下:

海量数据集利用Minhash寻找相似的集合【推荐优化】

图1

如果令区间个数为B,每个区间内的行数为C,那么上面的公式可以形式的表示为:

P(B个区间中至少有一个区间中两个结合相等) = 1 - (1 – rC)B

领r = 0.4,C=3,B = 100。上述公式计算的概率为0.9986585。这表明两个Jaccard相似度为0.4的集合在至少一个区间内冲撞的概率达到了99.9%。根据这一事实,我们只需要选取合适的B和C,和一个冲撞率很低的hash函数,就可以将相似的集合至少在一个区间内冲撞,这样也就达成了本节最开始的目的:将相似的集合放到一起。具体的方法是为B个区间,准备B个hash表,和区间编号一一对应,然后用hash函数将每个区间的部分集合映射到对应hash表里。最后遍历所有的hash表,将冲撞的集合作为候选对象进行比较,找出相识的集合对。整个过程是采用O(n)的时间复杂度,因为B和C均是常量。由于聚到一起的集合相比于整体比较少,所以在这小范围内互相比较的时间开销也可以计算为常量,那么总体的计算时间也是O(n)。

经验之谈:

minHash算法只适合较细粒度的聚类,太粗的话不好弄

参考:

[1]       书籍《Mining of Massive Datasets》的第三章Find Similar Item,由Anand Rajaraman,Jure Leskovec和Jeffrey David Ullman

[2]       http://www.cnblogs.com/bourneli/archive/2013/04/04/2999767.html

海量数据集利用Minhash寻找相似的集合【推荐优化】的更多相关文章

  1. 利用Minhash和LSH寻找相似的集合(转)

    问题背景 给出N个集合,找到相似的集合对,如何实现呢?直观的方法是比较任意两个集合.那么可以十分精确的找到每一对相似的集合,但是时间复杂度是O(n2).当N比较小时,比如K级,此算法可以在接受的时间范 ...

  2. 利用Minhash和LSH寻找相似的集合

    from: https://www.cnblogs.com/bourneli/archive/2013/04/04/2999767.html 问题背景 给出N个集合,找到相似的集合对,如何实现呢?直观 ...

  3. 人工智能大数据&comma;公开的海量数据集下载&comma;ImageNet数据集下载&comma;数据挖掘机器学习数据集下载

    人工智能大数据,公开的海量数据集下载,ImageNet数据集下载,数据挖掘机器学习数据集下载 ImageNet挑战赛中超越人类的计算机视觉系统微软亚洲研究院视觉计算组基于深度卷积神经网络(CNN)的计 ...

  4. &lpar;转载&rpar;公开的海量数据集 Public Research-Quality Datasets

    转载自:http://rensanning.iteye.com/blog/1601663 海量数据数据集 海量数据(又称大数据)已经成为各大互联网企业面临的最大问题,如何处理海量数据,提供更好的解决方 ...

  5. 巧妙利用ToArray&lpar;&rpar;函数移除集合中的元素

    当我们对集合foreach遍历时,不能直接移除遍历的集合的元素,解决的方法有很多种,见我之前的随笔: http://www.cnblogs.com/527289276qq/p/4331000.html ...

  6. 利用Trie树对字符串集合进行排序并计算特征值

    该算法用于将一组乱序的字符串反序列化到一个Trie树中,这个过程即可视为对字符串进行了一次排序. 还可以通过调用 GetFeatureString 将该 Trie 树重新序列化. #include & ...

  7. Java数组去重(利用数组,不借助集合)

    今天有个同学问我说老师,Java里边数组怎么去重,在不借助List集合的情况下,最后呢我整理了一下,打算发一篇博文,希望能帮助到有用的人,大佬绕过 public static void arrUniq ...

  8. 利用Merge Into 更新表&comma;集合数据到数据库中

    使用Merge INTO 将表数据更新到数据库中 创建User-Defined Table Types   创建要更新的UserDetails表 创建更新存储过程 程序调用存储过程 查看结果

  9. 试着利用BAPI 寻找F-59创建凭证的函数

    功能块代码 F-59开发类 FIBP事务说明 支付请求 事物:FBP1Screen 0BKPF-BLART = AB________________________________________从程 ...

随机推荐

  1. freebsd上安装nginx&plus;php记录

    参考文章 https://wiki.freebsdchina.org/faq/ports http://www.vpsee.com/2014/04/install-nginx-php-apc-mysq ...

  2. 设计模式之享元模式&lpar;FlyWeight&rpar;

    #include <iostream> #include <string> #include <list> #include <vector> usin ...

  3. openstack私有云布署实践【10&period;2 计算nova - controller节点配置(办公网环境)】

    一.首先登录controller1创建nova数据库,并赋于远程和本地访问的权限.     mysql -u root -p   CREATE DATABASE nova; GRANT ALL PRI ...

  4. Java面试准备之集合框架

    集合框架 Collection:List列表,Set集 Map:Hashtable,HashMap,TreeMap Collection 是单列集合 List 元素是有序的(元素存取是有序).可重复 ...

  5. 背水一战 Windows 10 &lpar;109&rpar; - 通知(Tile)&colon; 按计划显示 tile 通知&comma; 轮询服务端以更新 tile 通知

    [源码下载] 背水一战 Windows 10 (109) - 通知(Tile): 按计划显示 tile 通知, 轮询服务端以更新 tile 通知 作者:webabcd 介绍背水一战 Windows 1 ...

  6. Android开发 打开已存在的项目(以虹软人脸识别sdk的demo为例)

    详细流程参考博客https://blog.csdn.net/z979451341/article/details/79468785 个人遇到的问题与注意点 1.下载Demo后忘记修改appid和sdk ...

  7. nginx开启fileinfo扩展

    //实现网址 https://blog.csdn.net/m_nanle_xiaobudiu/article/details/80838424 (1) (2).make && make ...

  8. 全网最详细的Windows系统里Oracle 11g R2 Client(64bit)的下载与安装(图文详解)

    不多说,直接上干货! 环境: windows10系统(64位) 最好先安装jre或jdk(此软件用来打开oracle自带的可视化操作界面,不装也没关系:可以安装plsql,或者直接用命令行操作) Or ...

  9. 1094&period; The Largest Generation &lpar;25&rpar;-(dfs,树的遍历,统计每层的节点数)

    题目很简单,就是统计一下每层的节点数,输出节点数最多的个数和对应的层数即可. #include <iostream> #include <cstdio> #include &l ...

  10. zabbix 实现 iptables 监控

    安装iptstate # yum install iptstate 配置zabbix key iptables.conf # cat /etc/zabbix/zabbix_agentd.d/iptab ...