2

我是 python 的新学习者,当我尝试重复指南中提供的示例时会出现一些问题。这个例子是关于推荐算法的。此示例试图实现一个项目列表,该列表存储对特定项目进行评分的用户。这是代码(python 2.7)

def UserSimilarity(train):
    #build inverse table for item_users
    item_users=dict()
    for u,items in train.items():
        for i in items.keys():
            if i not in item_users:
                item_users[i]=set()              
            item_users[i].add(u)


    #calculate co-rated items between users
    C=dict()
    N=dict()
    for i, users in item_users.items():
        print i,users
        #print N[u]
        for u in users:
            N[u]=N[u]+1
            print N[u]
            for v in users:
                print C[u][v]
                if u==v:
                    continue
                C[u][v]=C[u][v]+1

    #calculate finial similarity matrix W
    W=dict()
    for u, related_users in C.items():
        for v, cuv in related_users.items():
            W[u][v]=cuv/math.sqrt(N[u]*N[v])
    return W

ps: 'train' 的数据格式是字典之类的{UserId1:{ItemId1:Ratings1,ItemId2,Rating2,...},...}

我遇到的问题是

Traceback (most recent call last):
  File "D:\Users\Administrator\workspace\GroupLens\src\test3.py", line 82, in <module>
    UserSimilarity(train_dic)
  File "D:\Users\Administrator\workspace\GroupLens\src\test3.py", line 66, in UserSimilarity
    N[u]=N[u]+1
KeyError: '3'

我不知道如何改进它,希望有人能帮助我!非常感谢!!

4

2 回答 2

0

主要问题是您正在定义一个新字典 ( N = dict()),然后遍历您的users,尝试根据给定用户创建字典键。那部分很好,但是当你这样做时会出现问题:

N[u]=N[u]+1

为字典分配一个值很好,但请看右侧 - 您正在尝试分配N[u]的值N[u] + 1N[u]但该值尚不存在(因此出现错误)。我不是 100% 确定总体目标是什么(所以这可能会被误导),但如果您的目标是根据用户出现的次数增加一个数字,您可以使用 a defaultdict,它是使用类型创建的一个论点(这里是一个int)。这意味着如果找不到密钥(如上面的错误),默认值基于您声明的类型(此处0):

In [1]: from collections import defaultdict

In [2]: N = defaultdict(int)

In [3]: users = [1, 2, 3, 2, 1, 2]

In [4]: for u in users:
   ...:     N[u] += 1
   ...:     
   ...:     

In [5]: N
Out[5]: defaultdict(<type 'int'>, {1: 2, 2: 3, 3: 1})

或者,您可以使用普通字典,但使用该get方法,如果找到则返回一个值,但如果没有则返回一个默认值(您可以自己指定的默认值):

In [1]: N = dict()

In [2]: users = [1, 2, 3, 2, 1, 2]

In [3]: for u in users:
   ...:     N[u] = N.get(u, 0) + 1
   ...:     
   ...:     

In [4]: N
Out[4]: {1: 2, 2: 3, 3: 1}
于 2012-12-10T08:07:40.703 回答
0

非常感谢!是的,问题是我没有为 N[u] 分配初始值。你的回答很有帮助,我从中学到了很多!再次感谢您的及时帮助!以下是修改成功版~

修改版

def UserSimilarity(train):
    #build inverse table for item_users
    item_users=dict()
    for u,items in train.items():
        for i in items.keys():
            if i not in item_users:
                item_users[i]=set()              
            item_users[i].add(u)
            
    #calculate co-rated items between users
    C=dict()
    N=dict()
    for i, users in item_users.items():
        for u in users:
            if u in N.keys():
                N[u] +=1
            else:
                N[u]=0                

            for v in users:
                if u==v:
                    continue
                elif u in C.keys():
                    if v in C[u].keys():
                        C[u][v] +=1
                    else:
                        C[u][v] =1
                else:
                    C[u]=dict({v:1})

    #calculate final similarity matrix W
    W=dict()
    for u, related_users in C.items():
        W[u]=dict()
        for v, cuv in related_users.items():
            W[u][v] = cuv/math.sqrt(N[u]*N[v])
于 2012-12-10T16:49:49.030 回答