求修改python代码,问题是valuerror

violet2010 2014-03-17 08:18:51

#coding=utf-8
'''
本文,用皮尔逊相关系数(pearon correlation coefficient)计算用户之间的相似性。
'''
from operator import itemgetter, attrgetter
from math import sqrt
# user_movie, movies都是字典
def load_data():
filename_user_movie = 'ratings_test.txt'
user_movie = {}
for line in open(filename_user_movie):
(userId, itemId, rating) = line.strip().split()
user_movie.setdefault(userId,{})
user_movie[userId][itemId] = float(rating)
return user_movie

#计算用户的平均值
def average_rating(user):
average = 0
for u in user_movie[user].keys():
'''针对user遍历user_movie中item列,对于由[userId][itemId]所组成的rating进行累加。
这样得到针对一个user的所有item的总评分。
再用总评分除以用户user的评分过的电影的总个数,就得到用户的平均评分。
'''
average += user_movie[user][u]
average = average * 1.0 / len(user_movie[user].keys())
return average


def calUserSim(user_movie):
''' build inverse table for movie_user 构建倒排文本,movie_user这个字典中相当于itemId是关键字
movie_user只包含两列的内容。
'''
movie_user = {}
for ukey in user_movie.keys():#遍历第一列
for mkey in user_movie[ukey].keys(): #遍历第二列
if mkey not in movie_user:
movie_user[mkey] = []#将user_movie第二列放到movie_user中
movie_user[mkey].append(ukey)# 将user_movie第一列放到movie_user中。那这个没有将rating放进去。

# calculated co-rated movies between users,在用户之间计算共同评分过的电影。
C = {}
'''
下面的操作是针对movie对用户进行遍历,将用户和电影都放到字典C中 。在用户之间计算共同评分过的电影。
movie_user中将第一个遍历到的用户放到第一列,将与第一个用户不同的用户(如果相同就不进行循环块后面的语句)
放到第二列第一个,字典C中的键是由(第一列,第二列)共同组成的,最后在他们的基础上添加电影。
这样就形成了(用户,用户,电影)的 字典。
'''
for movie, users in movie_user.items():#返回一个包含字典中(键, 值)对元组的列表。
#在所有内容中进行遍历 ,movie, users分别对应一列
for u in users:
C.setdefault(u,{}) #将movie_user中users转到C字典中来,并确定C中u是键。
for n in users:
if u == n:
continue #continue语句被用来告诉Python跳过当前循环块中的剩余语句,然后 继续 进行下一轮循环。
C[u].setdefault(n,[])
C[u][n].append(movie)

# calculate user similarity (perason correlation) 计算基于用户之间的相似性
userSim = {}
for u in C.keys():
for n in C[u].keys():
userSim.setdefault(u,{})
userSim[u].setdefault(n,0)

average_u_rate = average_rating(u)
average_n_rate = average_rating(n)

part1 = 0
part2 = 0
part3 = 0
for m in C[u][n]:

part1 += (user_movie[u][m]-average_u_rate)*(user_movie[n][m]-average_n_rate)*1.0
part2 += pow(user_movie[u][m]-average_u_rate, 2)*1.0
part3 += pow(user_movie[n][m]-average_n_rate, 2)*1.0

part2 = sqrt(part2)
part3 = sqrt(part3)
if part2 == 0:
part2 = 0.001
if part3 == 0:
part3 = 0.001
userSim[u][n] = part1 / (part2 * part3)
return userSim

'''
Items 方法 描述返回一个包含 Dictionary 对象中所有条目的数组。下面是首先对userSim[user].items()遍历和排序,
将用户先前交互过的电影过滤掉,将其他项目都放在项目预测pred字典中 ,并且以项目i为键。
i表示的是项目,nrating表示的是用户n的评分。nuw表示的是用户n和u的用户相似度userSim值。
itemgetter函数用于获取对象的哪些维的数据。key=itemgetter(1)意即按照userSim第二列的数据来排序,降序,N个项目。
可是num的值是由谁传递的呢?
'''
def getRecommendations(user, user_movie, userSim, N):
pred = {}
interacted_items = user_movie[user].keys()
average_u_rate = average_rating(user) #沿袭了average_rating(user)函数一样的参数user
sumUserSim = 0

for n, nuw in sorted(userSim[user].items(),key=itemgetter(1),reverse=True)[0:N]:
average_n_rate = average_rating(n) #用户n的平均评分
for i, nrating in user_movie[n].items():
if i in interacted_items:
continue
pred.setdefault(i,0)
pred[i] += nuw * (nrating - average_n_rate)
sumUserSim += nuw
for i, rating in pred.items():
pred[i] = average_u_rate + (pred[i]*1.0) / sumUserSim
# top-10 pred
pred = sorted(pred.items(), key=itemgetter(1), reverse=True)[0:10]
return pred

if __name__ == "__main__": # load data
user_movie= load_data() # Calculate user similarity
userSim = calUserSim(user_movie) # Recommend
pred = getRecommendations('780', user_movie, userSim, 20) # display recommend result (top-10 results)
for i, rating in pred:
print 'film: %s, rating: %s' % (i, rating)




数据文件格式如下:
780 54974 5
1205 67598 5
738 52466 4
4153 1879 3
15890 12197 4
16797 14330 5
1211 67743 5
1688 75757 4
588 7824 5
1275 69043 4
4059 16136 5
1229 3399 4
18349 16286 5
1998 80620 4
8820 2426 5
579 45878 4
……
...全文
222 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
就是文件中有某行不能split成3个变量
ahumoon7421 2014-03-19
  • 打赏
  • 举报
回复
建议split处加一个try,捕获到异常之后打印出来,一目了然

def load_data():       
  filename_user_movie = 'ratings_test.txt'      
  user_movie = {}        
  for line in open(filename_user_movie):  
    try:
      (userId, itemId, rating) = line.strip().split()           
      user_movie.setdefault(userId,{})           
      user_movie[userId][itemId] = float(rating)    
    except:
      print line   
  return user_movie 
jeky_zhang2013 2014-03-18
  • 打赏
  • 举报
回复
加点错误处理,可用利用调试看看运行情况
李察德-泰森 2014-03-17
  • 打赏
  • 举报
回复
检查你的文件,某一行或某几行用空格分不了三个值出来
angel_su 2014-03-17
  • 打赏
  • 举报
回复
就是某行数据分割出0份无法分配数据,譬如空行,加点代码容错处理即可...
violet2010 2014-03-17
  • 打赏
  • 举报
回复
出现的问题如下 Traceback (most recent call last): File "H:\Program Files\workspace\PythonTest1\src\network\UserBasedCF1.py", line 117, in <module> user_movie= load_data() # Calculate user similarity File "H:\Program Files\workspace\PythonTest1\src\network\UserBasedCF1.py", line 14, in load_data (userId, itemId, rating) = line.strip().split() ValueError: need more than 0 values to unpack

37,720

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧