python - Rec 的用户-项目矩阵中共同评分项目的矢量化计算。系统

标签 python numpy vectorization recommendation-engine

我正在研究推荐系统,计算的一部分是将权重作为许多共同评分的项目添加到距离度量中。考虑下面的矩阵:

行代表用户,列代表项目。例如第一行,该用户给产品A打了2分,没有评价产品B。然后产品C得到了3分,产品D得到了2分,依此类推...

ratings = np.array([[2,0,3,2,0,1],
                    [2,5,3,0,0,2],
                    [4,3,0,0,0,5],
                    [3,0,2,4,0,5]])

现在,如果两个用户的共同评分项目少于 3 个,请将共同评分项目的总数除以 3,然后乘以距离度量(不过不包括此步骤)。

下面是我创建这些权重的方法,有效:

#Is False when rating is 0 because I want to exclude those
ratings_aux = ratings > 0

co_rated_aux = np.zeros((ratings.shape[0], ratings.shape[0]))
co_rated = co_rated_aux.copy()

for row in xrange(co_rated.shape[0]):
    for clmn in xrange(co_rated.shape[1]):
        #If both are True, sum them
        co_rated_aux[row,clmn] = np.sum((ratings_aux[row,:] == ratings_aux[clmn,:]) & (ratings_aux[row,:] != False) & (ratings_aux[clmn,:] != False))
        if co_rated_aux[row,clmn] <= 3:
            co_rated[row,clmn] = co_rated_aux[row,clmn]/float(3)
        else:
            co_rated[row,clmn] = 1

在这里您可以看到共同评分的项目数量: (例如,第一个和第二个用户对三个相同的项目进行了评分)

print co_rated_aux

[[ 4.  3.  2.  4.]
 [ 3.  4.  3.  3.]
 [ 2.  3.  3.  2.]
 [ 4.  3.  2.  4.]]

最终权重:(如果两个用户有超过3个共同评分的项目,则相似度度量将保持不变。如果少于,则相似度度量将减小)

print co_rated

[[ 1.          1.          0.66666667  1.        ]
 [ 1.          1.          1.          1.        ]
 [ 0.66666667  1.          1.          0.66666667]
 [ 1.          1.          0.66666667  1.        ]]

但是,这个计算非常难看,并且对于较大的数组来说会非常慢。我试图仅使用向量运算来摆脱 for 循环,但我真的不知道如何。

我很乐意接受任何建议。

最佳答案

一种矢量化方法是 broadcasting (尽管要注意内存使用情况,但作为 booelan 数组对 RAM 的负担相对较小)-

mask = ratings_aux[None,:,:] == ratings_aux[:,None,:]
mask &= (ratings_aux != False)[None,:,:] & (ratings_aux != False)[:,None,:]
co_rated_aux_out = mask.sum(2) # or np.count_nonzero(mask,axis=2)
co_rated_out = np.where(co_rated_aux_out <=3, co_rated_aux_out/3.0,1)

基本上,在前两个步骤中,我们保持最后一个轴对齐,并将输入数组中的第一个轴与其自身“展开”,以进行逐元素比较。这为我们在这两个步骤中的每一步提供了一个 3D 数组。这种“展开”符合我们在每个维度/轴中引入了np.newaxis/Nonesingleton维度/轴之后的广播规则输入数组的这两个版本。

仔细观察就会发现,由于我们已经在第一步检查是否相等,因此我们可以在第二步中跳过第二项,如下所示 -

mask &= (ratings_aux != False)[None,:,:]

同样, ratings_aux 是一个 bool 数组。因此, ratings_aux != False 本质上是真正的元素,即数组本身。因此,进一步改进 -

mask &= ratings_aux[None,:,:]

关于python - Rec 的用户-项目矩阵中共同评分项目的矢量化计算。系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45391804/

相关文章:

python - Tensorflow卷积和numpy卷积的区别

python - 截至 2014 年 6 月,应该考虑使用哪些工具来提高 Python 代码性能?

MATLAB 矢量化以创建矩阵

python - 矢量化 : Limit the increase in value between two subsequent numbers in Series (or list/array/whatever)

python - 如何向量化 pandas 数据框中的比较?

.net - 改变声音输出

python - 为字典伪造 __hash__() 的惯用方法是什么?

python - Matlab 和 Numpy+Python FFT2 之间的差异?

python - 根据关键行查找跨轴的第一个重复项

python - 如何从 Python 中的文件名列表中删除文件名的扩展名?