推荐电影。
读取数据
文件格式: 用户 电影 评分…
|
|
算法实现
利用皮尔逊相关系数计算公式
计算用户间的相似距离
- 计算出user与其他所有用户的相似度
- 将与uesr最相近的k个人中user没有看过的书推荐给user,分数排名
- 第i个人的与user的相似度,转换到[0,1]之间
- 第i个用户看过的书和相应的打分
- 排序
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485class recommender:#data:数据集,这里指users#k:表示得出最相近的k的近邻#metric:表示使用计算相似度的方法#n:表示推荐book的个数def __init__(self, data, k=3, metric='pearson', n=5):self.k = kself.n = nself.metric = metricif self.metric == "pearson":self.fn = self.pearsonif type(data).__name__ == 'dict':self.data = data# 定义的计算相似度的公式,用的是皮尔逊相关系数计算方法def pearson(self, rating1, rating2):sum_xy = 0sum_x = 0sum_y = 0sum_x2 = 0sum_y2 = 0n = 0for key in rating1:if key in rating2:n += 1x = rating1[key] #每个电影的打分y = rating2[key]sum_xy += x * ysum_x += xsum_y += ysum_x2 += pow(x,2)sum_y2 += pow(y,2)if n == 0:return 0# 皮尔逊相关系数计算公式denominator = sqrt(sum_x2 - pow(sum_x,2)/n) * sqrt(sum_y2 - pow(sum_y,2)/n)if denominator == 0:return 0else:return (sum_xy - (sum_x * sum_y)/n)/denominatordef computeNearestNeighbor(self,username):distances = []for instance in self.data:if instance != username:distance = self.fn(self.data[username],self.data[instance])distances.append((instance,distance))distances.sort(key=lambda artistTuple:artistTuple[1],reverse=True)return distances# 推荐算法的主体函数def recommend(self,user):# 定义一个字典,用来存储推荐的书单和分数recommendations = {}# 计算出user与其他所有用户的相似度,返回一个listnearest = self.computeNearestNeighbor(user)userRatings = self.data[user]totalDistance = 0.0# 得出最近的k个近邻的总距离for i in range(self.k):totalDistance += nearest[i][1]if totalDistance == 0.0:totalDistance = 1.0# 将与uesr最相近的k个人中user没有看过的书推荐给user,# 并且这里又做了一个分数的计算排名for i in range(self.k):# 第i个人的与user的相似度,转换到[0,1]之间weight = nearest[i][1]/totalDistance# 第i个人的namename = nearest[i][0]# 第i个用户看过的书和相应的打分neighborRatings = self.data[name]for artist in neighborRatings:if not artist in userRatings:if artist not in recommendations:recommendations[artist] = (neighborRatings[artist]*weight)else:recommendations[artist] = (recommendations[artist]+neighborRatings[artist]*weight)recommendations = list(recommendations.items())# 做了一个排序recommendations.sort(key=lambda artistTuple:artistTuple[1],reverse=True)return recommendations[:self.n],nearest
主函数
|
|
运行结果
bookid_list:给用户 luhangdedouban
推荐5部电影。
near_list:与用户 luhangdedouban
相似的其他用户及其相似度
|
|