大规模稀疏向量余弦相似度计算方法(续)

转载请注明出处(zz_boy):http://www.cnblogs.com/zz-boy/archive/2012/12/15/2819401.html

向量u1和u2的余弦相似度计算公式如下

大规模稀疏向量余弦相似度计算方法(续)

我们将向量表示成矩阵Rm*n,如下所示

d­1

d2

d3

d4

dn

u1

r11

r12

r13

r14

r1n

u2

r21

r22

r23

r24

r2n

u3

r31

r32

r33

r34

r3n

um

rm1

rm2

rm3

rm4

rmn

rij表示向量ui的第j维(dj)的值。

那么ua和ub的余弦相似度可以表示成如下的公式

大规模稀疏向量余弦相似度计算方法(续)

我们假设

大规模稀疏向量余弦相似度计算方法(续)

那么上面的公式可以改写成

大规模稀疏向量余弦相似度计算方法(续)

因此ua和ub的余弦相似度计算可以抽象成n+1部计算。

前n部是对大规模稀疏向量余弦相似度计算方法(续)求和,最后一步是除以分母。

基于上面的理论,我们提出一种使用外排序的方法计算相似度的方法,该方法在应对大规模数据时可以有效地控制内存使用,并且计算效率很高。

算法

建立d-><u,r>的倒排索引(r!=0)

对向量空间的每一维度di

根据上面建立的倒排索引获取关联的{<u,r>};假设为{<ua,rai>,<ub,rbi>,<uc,rci>},其中ua< ub< uc;

穷尽{<u,r>}中所有的两两组合,生成待排序项追加到外存文件中。比如上面的{<ua,rai>,<ub,rbi>,<uc,rci>},我们将生成以下排序项:

< ua , ub , rai * rbi >,< ua , uc , rai * rci >,< ub , uc , rbi * rci>

使用外存归并排序方法对文件排序,上述三元组的第一维是主排序项,第二维度是次排序项,归并过程中,如果发现buffer中最近的三元组主排序项、次排序项和当前要添加到buffer中的三元组都相同,则立即合并他们,合并的方法是将两个三元组的第三维相加,前两维不变生成新的三元组,并替换被合并的两个记录。

比如buffer中最近的是< ua , ub , r1>,外存归并排序败者树得出的记录是< ua , ub , r2>,则用

< ua , ub , r1+r2>替换buffer中的< ua , ub , r1>。

入库时每取出一个三元组,则将此三元组的第三维除以已经计算好的分母(余弦相似度计算公式)。

算法优点分析:

1. 算法只会访问r!=0的位置,这对于大规模稀疏向量而言无疑大大加快了速度。

2. 外存归并排序可以定制归并路数K,对每一路可以限制buffer的大小,因此无论数据量有多大,排序所需的内存都是可以控制的。

3. 使用败者树的外存归并排序方法,排序效率很高,因此其处理速度很快,实验中我使用了6000*6000的矩阵,矩阵中不为0的位置有一千万个,机器配置如图所示

大规模稀疏向量余弦相似度计算方法(续)

外排用时75s.

4. 使用上述方法计算相似度是便于动态更新的。这是因为我们可以轻松的以在外排序文件末尾追加记录(三元组)的方式实现相似度的更新,追加的三元组第三维为负值表示要减少原始的计算结果,正值表示增加原始的计算结果。

相关文章: