欢迎使用CSDN-markdown编辑器
来源:互联网 发布:网络认证怎么弄 编辑:程序博客网 时间:2024/05/20 09:08
基于用户的协同过滤算法也被称为最近邻协同过滤或KNN (K.Nearest-Neighbor,K最近邻算法)。其核心思想就是,首先根据相似度计算出目标用户的邻居。1.首先,使用用户已有的评分来计算用户之间的相似度;2.然后,选择与目标用户相似度最高的K个用户,通常把这些用户称为邻居;3.最后,通过对邻居用户的评分的加权平均来预测目标用户的评分。为了方便说明,我们把系统中用户的集合记为U。物品的集合记为I,用户u,v∈U,物品i,j∈I, 是用户对物品的评分,而用户u和v之间的相似度记为 ,用一个m×n的矩阵来表示所个用户对玎个物品的评分情况。读入数据集,此时建立users字典,以第一列用户名为key,新建一个字典为value,value字典以书籍id为key,以对书籍的评分为value。以皮尔逊相似度来计算两用户之间的相似度,计算公式如下
# -*- coding: utf-8 -*-"""Created on Thu Nov 23 16:30:43 2017@author: BruceKun"""from math import sqrt fp = open("f:/data.txt","r",encoding='utf8') users = {} for line in open("f:/data.txt",encoding='utf8'): lines = line.strip().split(",") if lines[0] not in users: #用户名没在用户名字典里就将用户名加入 users[lines[0]] = {} #以用户名为key的字典新建一个字典 users[lines[0]][lines[2]]=float(lines[1]) #用户名字典以书id为key,书评分为value#----------------新增代码段END---------------------- class recommender: #data:数据集,这里指users #k:表示得出最相近的k的近邻 #metric:表示使用计算相似度的方法 #n:表示推荐book的个数 def __init__(self, data, k=3, metric='pearson', n=12): self.k = k self.n = n self.username2id = {} self.userid2name = {} self.productid2name = {} self.metric = metric if self.metric == 'pearson': self.fn = self.pearson if type(data).__name__ == 'dict': self.data = data def convertProductID2name(self, id): if id in self.productid2name: return self.productid2name[id] else: return id #定义的计算相似度的公式,用的是皮尔逊相关系数计算方法 def pearson(self, rating1, rating2): sum_xy = 0 #分子相乘 sum_x = 0 #分子前半部分 sum_y = 0 #分子后半部分 sum_x2 = 0 #分母前半部分 sum_y2 = 0 #分母后半部分 n = 0 #rating为用户表,此处key为书id for key in rating1: if key in rating2: n += 1 #n为共同评分数量 x = rating1[key] #x,y为书的评分 y = rating2[key] sum_xy += x * y sum_x += x sum_y += y sum_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 0 else: return (sum_xy - (sum_x * sum_y) / n) / denominator def computeNearestNeighbor(self, username): distances = [] for instance in self.data: #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与所有其他用户的相似度,返回一个list nearest = self.computeNearestNeighbor(user) # print nearest userRatings = self.data[user] # print userRatings totalDistance = 0.0 #得住最近的k个近邻的总距离 for i in range(self.k): totalDistance += nearest[i][1] if totalDistance==0.0: totalDistance=1.0 #将与user最相近的k个人中user没有看过的书推荐给user,并且这里又做了一个分数的计算排名 for i in range(self.k): #第i个人的与user的相似度,转换到[0,1]之间 weight = nearest[i][1] / totalDistance #第i个人的name name = 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 = [(self.convertProductID2name(k), v)for (k, v) in recommendations] #做了一个排序 recommendations.sort(key=lambda artistTuple: artistTuple[1], reverse = True) return recommendations[:self.n],nearest def adjustrecommend(id): bookid_list = [] r = recommender(users) k,nearuser = r.recommend("%s" % id) for i in range(len(k)): bookid_list.append(k[i][0]) return bookid_list,nearuser[:15] #bookid_list推荐书籍的id,nearuser[:15]最近邻的15个用户 bookid_list,near_list = adjustrecommend("欧阳杼") print ("bookid_list:",bookid_list) print ("near_list:",near_list)
数据集格式如下,用户名、评分、书籍id,中间用逗号隔开
因为数据量较小,与用户相似度近似的只有一个而且完全相同,所以不存在为该用户推荐相似用户看过该用户没有看过的书目
推荐结果:
阅读全文
0 0
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- Gradle 与 Android的相互依赖
- Android开发中出现的错误集
- c++内存管理学习纲要
- linux上redis集群的安装以及redis.conf配置(去注释版)
- [Java]“语法糖”系列(二)之Lambda表达式/匿名函数(Lambda Expression)
- 欢迎使用CSDN-markdown编辑器
- 树莓派3b+设置静态ip
- 面向对象程序设计思想简述
- java---三种排序的方法
- Linux系统下安装rz/sz命令及使用说明
- 使用JavaScript开发IE浏览器本地插件实例
- phpStorm快捷键的:
- 第九题 顺序查找某个数的下标
- win7 64位环境下VS2012编译使用boost_1_60_0