Mining Massive Datasets课程笔记(二)

Finding Similar Sets

在数据挖掘中有一个很基础的问题就是寻找相似项。比如“查找具有相似爱好的用户“等应用的本质就是查找相似项。
这一节介绍的就是如何寻找相似项。采用的相似度衡量概念为“Jaccard 相似度”,具体的意思在后文介绍,其主要思想就是两个集合的交集所占的比例越大则认为两者越相似。
对于数据量非常庞大的情况来讲逐一计算相似度肯定是不现实的,联系hash表的(可以快速寻找到特定元素而不用搜寻所有元素)的特性,首先使用Shingling算法,然后提出MinHashing来compress large sets以及
locality-sensitive Hashing 来 find similar documents or similar sets without doing anything that involves searching all pairs.

Applications of Set-Similarity

  • 寻找相似主题或相似内容的网页
  • 推荐系统:对同一用户按口味推荐可能喜欢的电影
  • 寻找有相似受众的电影
  • 实体解析

Similar Documents

以寻找具有相似的text or words的文档为例(不是相似topic),这一例子有很多现实应用:
- 寻找镜像网页,从而避免在搜索结果中重复出现
- 找到抄袭页面,包括只是大量引用且有改动的情况
- 将描写相同事件的网页聚在一起,呈现在结果页面
这些例子中虽然各个页面的内容大部分是一致的,但是各自有各自的改动或特点,比如同一新闻在不同新闻网站上logo、link甚至标题都会有轻微不同,单纯进行逐个单词的比较来计算相似肯定是不对的。

对于处理相似文本,我们需要三种技术:
这里写图片描述
1. Shingling:Jaccard相似度需要计算集合的交集,因此需要将文档转换为集合形式,这一步称为Shingling;
2. Minhashing:将上一步得到的sets转变为一些短的signatures同时保留sets之间的相似度;
3. Locality-sensitive Hashing:我们知道即使文本的数量只是million级的,要计算signatures间的相似度则有trillion级别的pairs要计算,而LSH可以实现只计算部分相似度很高的signature pairs就可以几乎得到所有的相似项。

这是整体的流程图:
这里写图片描述
下面我们分别讲解这三个步骤的实现方式

Shingles

把相邻的k个字符作为一个元素,从而将整篇文档变为一个集合,通常将k值设在5~10之间。对于K值的选择依赖于文档的长度以及文档中词语的评价长度,最好保证任一shingle在文档中所占的比例都很小。
这里写图片描述

Shingles and Similarity
这里写图片描述

shingles:Compress Option
这里写图片描述

Minhashing

Jaccard similarity Measure

这里写图片描述
Example:
这里写图片描述
From Sets to Boolean M atrix
这里写图片描述

通常我们需要处理大型的集合,因此使用矩阵形式是很有用的,首先我们将集合表示为一个单一的布尔型矩阵,即使该集合的存储方式不是布尔型:
我们首先建一个全集,使之包含所有的集合元素,例如,对一个k-shingles表示的文档,它的全集就是由k个character组成的所有序列或者是所有tokens(如果采用了hash处理shingles的话)
特征矩阵表示:
矩阵的行就是所有的这些序列,矩阵的列就是一个集合的向量表示,只有当结合S(假设第j列)中包含k-shingles元素E(假设在第i行)时,矩阵中的元素M(i,j)才等于1,否则记为0。因此列向量中只有值为1的元素才属于集合中的元素,在计算两个列向量的Jaccard相似度时,需要注意只有同时为1才表示集合相交,也只有值为1对应的元素才属于集合中。
Example:
这里写图片描述
因此,一般我们可以通过计算两列中同为1的元素个数/两列中至少有一列有的元素个数来得到Jaccard相似度

注意:上文提到的矩阵在实际应用中是非常稀疏的,并不像例子中举得规模那么小且不稀疏。因为一篇文档中存在的shingles再所有k个元素组成的可能序列中所占的比例非常小,如k=10时由26个字母组成的shingles可以有2610=1.4e14 个,而文档中实际并不会有那么多shingles.
再比如如果矩阵的行表示亚马逊上的不同图书,列表示不同用户的购买记录,单个用户所购买的书再多,和亚马逊上所有的图书数目相比仍然很小。

不要忘了我们的目标是描述如何 通过由minhashing得到的signatures 来推断sets或矩阵的列之间的相似度的。

首先我们来看两个列的相同行可能存在的四种情况:
这里写图片描述
因此Jaccard相似度就可以通过a、b、c来表示。

接下来我们定义Minhashing:
这里写图片描述

假设特征矩阵的行被随机排列,任何一列的minhash值是根据rows新的排列次序下,该列中数字第一行是1的行号。 通常使用如100个独立的hash 函数来为每一列构建签名(signatures),从而形成有边的signature matrix,行表示Minhash的值,列表示集合。
Example:
这里写图片描述

那么为什么要定义Minhashing以及它和我们要求的Jaccard相似度间的有啥关系呢?
在等概率随机全排列的行中,两个集合(列)的minhash值相等的概率和两个集合的Jaccard相似度相等。 都是a/(a+b+c)
证明:如果我们限制于集合s1和s2,那么行可以分成三类:
1.类型X 两列值都是1
2.类型Y 一列是1,另一列是0
3.类型Z 两列都是0
由于矩阵是稀疏的,所以大多数的行是类型Z。类型X和类型Y的函数既决定了SIM(S1,S2) 又决定了h(s1)=h(s2).我们假设有x行是类型X的,y行是类型y的。那么SIM(S1,S2) = x/(x+y).因为x是S1 ∩ S2的大小,而x + y是S1 ∪ S2大小.
现在我们考虑h(s1) = h(s2)的概率。如果我们假设我们随机排列行,那么我们从上到下, 在遇到类型Y之前遇到类型X的概率是x/(x+y)。如果我们从上往下遇到的除了Z类型的第一行 是X类型的行,那么h(s1) = h(s2).
另一方面,如果除了类型Z,我们第一次遇到的类型是类型Y,那么是1的集合,其对应行数,就是minhash值。是0的集合仍然需要向下才能找到为1的行,因此如果我们第一次遇到的是类型Y那么h(s1) <> h(s2)。所以h(s1) = h(s2)的概率是 x / (x + y),这也是s1和s2的Jaccard相似度。

在全排列的情况下两者值是相等的,但是前面说过特征矩阵非常稀疏,为了代表这些集合,我们从M行的排列中选择n个 ,可能是100或者几百个排列。有这些排列组成了minhash函数h1,h2,…,hn。 从由列表示的集合S,构建其minhash签名。矩阵M的第i个列被第i列的minhash签名所代替。
这个签名矩阵具有和原来矩阵一样的列M,但是只有n行,因此由Minhashing生成的signature matrix的行数往往远小于原来的矩阵,从而实现特征矩阵的压缩,因此signture matrix 计算的得到的相似度与Jaccard相似度会有些偏差。

Similarity for Signatures

可以用上面得到的矩阵签名的相似度来近似得到Jaccard相似度,集合的signatures越长即行数越大,误差就越小。全排列时等于Jaccard相似度。

Implementation of Minhashing

我们知道前面的Minhashing是建立在行的全排列上的,但是对于大规模的数据形成的特征矩阵而言,如十亿行,如果要挑选是一行的一个random permutation是很耗费时间和空间的。
解决方式:
通过一个随机hash函数将行号和具有和行数相同的桶进行映射,从而模拟随机排列。
一个hash函数将0…k-1的数字映射到0…k-1的桶中,典型的可能出现不同的数字会映射到相同的桶中,然后其他的一些桶没有被映射。然而只要k足够大,并且没有太多的冲突,这个不同是不重要得,我们可以维护一个hash函数h,将行r映射到h(r)的位置上。 将这个映射看成是随机排列的模拟。
具体过程:
这里写图片描述

  1. 计算h1(r), h2(r), …hn(r), 设置初始sig(i,c)=
  2. 对于所有的列c:
    (a). 如果(r, c) = 0 不作任何操作
    (b). 如果(r, c) = 1, 那么对于i = 1,2,…n, sig(i, c) = min( sig(i,c), hi(r) )

Example:
这里写图片描述

Locality-Sensitive Hashing

小结下前面的知识,为了计算文档相似度,首先我们将文档按k-shingles划分形成将documents转换为sets,然后利用Minhashing将shingle特征矩阵转换为signature matrix,这一步能有效地压缩数据,然后我们可以通过比较signature得到近似的Jaccard相似度。

虽然signature有效压缩了数据,但是要计算相似度还是需要对列向量两两对比计算,当文档很多时仍然很低效,假设有一个相关度阈值T,我们其实只需要计算那些相似度可能大于T的pairs就好,而不需要计算所有pairs。这一点可以通过locality-sensitive Hashing或者near-neighbor search实现。
locality-sensitive Hashing就是在这一系列signature中选择候选的pairs,而不需要计算所有的Elements就能得到相似文档。

When constructing candidate pairs,you look only at individual elements,not at the pairs themselves.

下面我们看下对于signature matrix,是如何挑选候选pairs的:
这里写图片描述

LSH for Minhashing Signatures

一个最简单直接的方法就是对signature matrix M的各列进行多次哈希,相似的列更可能会被hash到相同的bucket,因此Candidate pairs就是那些至少又一次被hash到同一个bucket的列。
这里写图片描述
如图,将一个signature matrix M的rows划分为b个bands,每个band有r行,则b*r = len(rows of M) = the number of minhashing functions that used to create signature matrix
然后,对于每个band,将列元素中对应这一band的部分哈希到k个buckets中,这个k值应该尽可能大(减少哈希过程中的冲突数,保证分到同一个bucket的原因是因为对应band中的元素很相似)
Example:
这里写图片描述
我们认为至少被分到同一个buckets中一次的列是candidate pairs。通过调整b和r的大小来获取尽可能多的相似对,尽量少的nonsimilar pairs。从直观的角度看,我们不难理解,b越大r越小时,分到同一个buckets的概率越大,适用于similarity阈值小时;反之b越小r越大,越难有同一个buckets的pairs,适用于similarity阈值大时。

Analysis of LSH——What We What

Ref
https://class.coursera.org/mmds-003/lecture
http://blog.csdn.net/sherrylml

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章