基于用户的协同过滤python代码实现

原文链接:基于用户的协同过滤python代码实现

微信公众号:机器学习养成记


推荐算法概述中介绍了几种推荐算法的概念,但是没有具体代码实现,本篇文章首先来看一下基于用户的协同过滤python代码。

数据准备

本次案例中,我们使用用户对电影的打分数据进行演示。数据包含两个表,一个是movies表,记录了电影编号和电影名称的对应关系👇

另外一张是ratings表,记录了每个用户对电影的打分情况👇

Python代码实现

这里简述几个主要过程:

数据初始化

原始数据分别通过三列记录了用户、电影及打分,无法直接满足计算需要,因此这里我们首先要将原始数据转化为字典形式,记录每个用户与电影之间的关系。

########获得初始化数据

def __init__(self,data):

data_dic = {}

for line in data.itertuples():

if not line[1] in data_dic.keys():

data_dic[line[1]]={line[4]:line[2]}

else:

data_dic[line[1]][line[4]]=line[2]

    self.data = data_dic

计算用户间距离

基于用户的协同过滤第二步就是计算用户两两间的距离,计算距离的方式很多,这里提供欧式距离和皮尔逊系数两种方式,可以通过参数进行方法选择。推荐使用皮尔逊距离,因为可以消除打分膨胀的影响,即有的人打分普遍高,有的人打分普遍低。

########计算两个用户间距离

#pearson系数

def Pearson(self,user1,user2):

sum_xy = 0 

sum_x = 0 

sum_y = 0 

sum_x2 = 0 

sum_y2 = 0 

n = 0 

for key in user1: 

if key in user2: 

n += 1 

x = user1[key] 

y = user2[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 Euclidean(self,user1,user2):

#取出两位用户评论过的电影和评分

distance = 0

#找到两位用户都评论过的电影,并计算欧式距离

for movie1,score1 in user1.items():

if movie1 in user2.items():#计算公共的电影的评分

#注意,distance越大表示两者越相似

distance += pow(float(user1[movie1])-float(user2[movie1]),2)

return 1/(1+sqrt(distance))#这里返回值越小,相似度越大

#选择计算距离方式

def getDistance(self,user1,user2,type):

if type == 'Pearson':

dis = self.Pearson(user1,user2)

if type == 'Euclidean':

dis = self.Euclidean(user1,user2)

return dis

寻找最相似用户并进行推荐

根据距离,找到离目标用户最近的n个用户,将这n个用户看过但是目标用户没看过的电影进行推荐。

########找到与当前用户最近的n个邻居

def nearstUser(self,username,type,n=1):

    distances={};#用户,相似度

    for otherUser,items in self.data.items():#遍历整个数据集

        if otherUser != username:#非当前的用户

            distance=self.getDistance(self.data[username],self.data[otherUser],type)#计算两个用户的相似度

            distances[otherUser]=distance

    sortedDistance=sorted(distances.items(),key=operator.itemgetter(1),reverse=True);#最相似的N个用户

    #print ("排序后的用户为:",sortedDistance)

    return sortedDistance[:n]

#给用户推荐电影

def Recomand(self,username,tp = 'Pearson',n=1):

    recommand={};#待推荐的电影

    for user,score in dict(self.nearstUser(username,tp,n)).items():#最相近的n个用户

        #print ("推荐的用户:",(user,score))

        for movies,scores in self.data[user].items():#推荐的用户的电影列表

            if movies not in self.data[username].keys():#当前username没有看过

                #print ("%s为该用户推荐的电影:%s"%(user,movies))

                if movies not in recommand.keys():#添加到推荐列表中

                    recommand[movies]=scores

    return sorted(recommand.items(),key=operator.itemgetter(1),reverse=True);

最终得到结果如下:

本代码只是对算法逻辑进行了最基本实现,真实应用时还可以加入打分时间、电影分类等维度,提升预测准确率。

关注公众号“机器学习养成记”后台回复“协同过滤用户”获得数据及完整代码


往期推荐:

百度地图API调用:正逆地理编码

疫情下,你还好吗

图片相似度识别:pHash算法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342