0

我已经尝试了很长时间来解决这个问题。但是我想不出一个干净的数据结构来执行以下操作。

我有一个csv文件如下:

           user_id --->
item_id     ratings
|
|
|
V

例如:

  1,2,3,4,..
a,4, ,2, ,...   
b, ,2,3, ,..
c, ,1,2,3,
d

依此类推...空白值表示用户尚未对给定项目进行评分。现在,对于给定的用户(比如 1),我有这本字典:

weight_vector = {2:0.3422,3:0.222}

我想做的计算如下:

对于用户 1:缺少的值(项目 b 和 c),我想为它分配一个评级,如下所示:

 rating_for_item_for_user_1 = [rating_given_by_user_2* weight_2] + [rating_given_by_user_3*weight_3]/[weight2 + weight3]

如果用户 2 或 3 未对给定项目评分,则权重 = 0。

我有一种感觉,使用 numpy 这应该是相当简单的。但是一直想不通。

4

2 回答 2

1

让我们假设你有一个rating矩阵和一个权重向量列表'weights',那么你可以简单地做(假设这些“空”字段是零 - 这是你必须考虑的一些边界情况,因为你可以遇到无论哪种方式除以 0,当所有用户“邻居”也没有对某些项目给予任何评价时):

empty=np.where(ratings==0)
for (x,y) in zip(empty[0],empty[1]):
    ratings[x,y] = sum( ratings[n][y] * weights[x][y] for n in weights[x] if ratings[n][y] != 0) / sum( weights[x][w] for w in weights[x] if ratings[w,x] != 0 )

为了防止除以零错误,您可以在分配前检查它

empty=np.where(ratings==0)
for (x,y) in zip(empty[0],empty[1]):
    normalizer = sum( weights[x][w] for w in weights[x] if ratings[w,x] != 0 )
    if normalizer > 0:
        ratings[x,y] = sum( ratings[n,y] * weights[x][y] for n in weights[x] if ratings[n][y] != 0) / normalizer
于 2013-10-13T06:27:06.567 回答
1

另一种可能性是使用集合中的 defaultdict。 http://docs.python.org/2/library/collections.html#collections.defaultdict

from collections import defaultdict
dict = defaultdict(float) 
dict[x]=0

如果您希望它作为矩阵,以便您可以按列和按行访问,您可能希望将 id 加载到两个不同的数据结构或将其加载到一个,计算然后转置它。

于 2013-10-13T07:18:29.140 回答