KNN电影评分预测报错:Operands Could not be Broadcast with Shapes (19,)(0,)
KNN电影评分预测报错:ValueError: operands could not be broadcast together with shape (19,)(0,)
咱们先拆解问题根源,再给你修复方案:
问题分析
从报错栈能看到,错误出在spatial.distance.cosine计算时,两个输入数组一个是19维(对应电影的19种类型),另一个是空数组(形状(0,)),导致无法完成广播运算。
为什么会出现空数组?看你构建movieDict的代码:
genres = map(int, genres) movieDict[movieID] = (name, genres, ...)
在Python3里,map()返回的是一次性迭代器,不是列表。当你第一次调用ComputeDistance(movieDict[2], movieDict[4])时,是首次访问这两个电影的genres,迭代器能正常取出值转成数组;但到getNeighbors循环遍历所有电影时,再次访问已经用过的电影的genres时,迭代器已经被耗尽,转成数组就变成了空数组,这就触发了报错。
另外你的getNeighbors函数还有个小笔误:neighbors.append(distance[x][0])里的distance应该是distances(少了个s),这个也会导致后续运行报错。
修复方案
1. 修复genres存储问题
把构建movieDict时的genres迭代器转成列表,这样就能反复访问:
# 原代码 genres = map(int, genres) # 修改为 genres = list(map(int, genres))
2. 修正getNeighbors里的变量名错误
# 原代码 neighbors.append(distance[x][0]) # 修改为 neighbors.append(distances[x][0])
完整修复后的关键代码片段
movieDict = {} with open('C:/Users/dell/Downloads/DataScience/DataScience-Python3/ml-100k/u.item') as f: temp = '' for line in f: fields = line.rstrip('\n').split('|') movieID = int(fields[0]) name = fields[1] genres = fields[5:25] # 把map结果转成列表存储,避免迭代器耗尽 genres = list(map(int, genres)) movieDict[movieID] = (name, genres, movieNormalizedNumRatings.loc[movieID].get('size'), movieProperties.loc[movieID].rating.get('mean')) # 修正后的getNeighbors函数 def getNeighbors(movieID, K): distances = [] for movie in movieDict: if (movie != movieID): dist = ComputeDistance(movieDict[movieID], movieDict[movie]) distances.append((movie, dist)) distances.sort(key=operator.itemgetter(1)) neighbors = [] for x in range(K): # 修正变量名拼写错误 neighbors.append(distances[x][0]) return neighbors
验证修复
修改后再运行代码,getNeighbors(1, 10)就能正常计算邻居了,后续你可以继续完成评分预测的逻辑(比如计算邻居的平均评分)。
内容的提问来源于stack exchange,提问作者Mr Prof
相关产品推荐
相关产品推荐

