基于用户的协同过滤算法的电影推荐系统的Python实现

一、基于用户的协同过滤算法原理

基于用户的协同过滤的基本思想相当简单,基于用户对物品的偏好找到邻居用户,然后将邻居用户喜欢的物品推荐给当前用户。计算上就是将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到N个邻居后根据邻居的相似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表作为推荐。例如下图,用户A喜欢物品A和物品C,用户C喜欢物品A、物品C和物品D,用户A和用户C具有相似的兴趣爱好,因此把物品D推荐给用户A。
在这里插入图片描述

二、算法设计

2.1 构建用户相关数据表;
在这里插入图片描述

2.2 根据当前用户,计算与当前用户最相似的N个用户;
相似度的计算有欧式距离、皮尔逊相关系数等,本文主要介绍皮尔逊相关系数。Pearson相关系数用来衡量两个数据集合之间的相似性。比如在一个关于电影的资料网站中,很多用户都可能对其中的电影进行打分。Pearson相关系数可以用来帮助更好的找到兴趣相似的用户,从而进行相关的推荐。这种推荐的基本思路是如果A和B兴趣相似,那么A喜欢看的,B就有很大可能会喜欢看,就可以把A的喜欢看的推荐给B。
Pearson相关系数的一个优点是可以避免评分等级膨胀(grade inflation)的问题,也就是说有的用户可能倾向于对所有的电影都给比较高的分数,而有的用户则会比较苛刻,给分都比较低。对于这种情况,Pearson相关系数可以处理。
Pearson相关系数的具体计算公式为:
在这里插入图片描述
等价公式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.3 推荐N个最相似的用户看过的电影,推荐的过程中遇到已经看到,就排除;
2.4 将排除了已看过电影的推荐电影,按照评分从高到低的顺序推荐给用户。

三、算法实现

3.1 构建用户相关数据表

    users = {  'UserA': {'《战狼2》': 4.5, '《红海行动》': 4.5,'《湄公河行动》': 4.0, '《你好 李焕英》': 3.5,'《泰囧》': 3.0, '《港囧》': 2.5},

             'UserB': {'《战狼2》': 4.0, '《红海行动》': 3.5,'《湄公河行动》': 4.5, '《你好 李焕英》': 3.0, '《泰囧》': 3.0,'《港囧》': 3.5},

             'UserC': {'《战狼2》': 4.5, '《红海行动》': 4.0,                 '《你好 李焕英》': 3.5, '《泰囧》': 3.0},

             'UserD': {             '《红海行动》': 4.5, '《湄公河行动》': 4.0,'《你好 李焕英》': 4.0, '《泰囧》': 3.5,'《港囧》': 2.5},

             'UserE': {'《战狼2》': 4.0, '《红海行动》': 4.0,'《湄公河行动》': 4.0, '《你好 李焕英》': 4.5, '《泰囧》': 3.0,'《港囧》': 3.0},

             'UserF': {'《战狼2》': 4.0, '《红海行动》': 4.0,                 '《你好 李焕英》': 3.5, '《泰囧》': 3.0,'《港囧》': 3.5},

             'UserG': {              '《红海行动》': 4.5,                '《你好 李焕英》': 4.0,             '《港囧》': 2.0}
             }

3.2 完整代码:

from math import sqrt,pow
import operator
class UserCf():

    #获得初始化数据
    def __init__(self,data):
        self.data=data;

    #通过用户名获得电影列表,仅调试使用
    def getItems(self,username1,username2):
        return self.data[username1],self.data[username2]

    #计算两个用户的皮尔逊相关系数
    def pearson(self,user1,user2):#数据格式为:电影,评分  {'战狼2': 4.5, '红海行动': 1.0, '泰囧': 4.0}
        sumXY=0.0;
        n=0;
        sumX=0.0;
        sumY=0.0;
        sumX2=0.0;
        sumY2=0.0;
        try:
            for movie1,score1 in user1.items():
                if movie1 in user2.keys():#计算公共的电影的评分
                    n+=1;
                    sumXY+=score1*user2[movie1]
                    sumX+=score1;
                    sumY+=user2[movie1]
                    sumX2+=pow(score1,2)
                    sumY2+=pow(user2[movie1],2)

            molecule=sumXY-(sumX*sumY)/n;
            denominator=sqrt((sumX2-pow(sumX,2)/n)*(sumY2-pow(sumY,2)/n))
            r=molecule/denominator
        except Exception as e:
           print("异常信息:",e.message)
           return None
        return r
    #计算与当前用户的距离,获得最临近的用户
    def nearstUser(self,username,n=1):
        distances={};#用户,相似度
        for otherUser,items in self.data.items():#遍历整个数据集
            if otherUser not in username:#非当前的用户
                distance=self.pearson(self.data[username],self.data[otherUser])#计算两个用户的相似度
                distances[otherUser]=distance
        sortedDistance=sorted(distances.items(),key=operator.itemgetter(1),reverse=True);#最相似的N个用户
        print("排序后的用户为:",sortedDistance)
        return sortedDistance[:n]
    #给用户推荐电影
    def recomand(self,username,n=1):
        recommand={};#待推荐的电影
        for user,score in dict(self.nearstUser(username,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);#对推荐的结果按照电影评分排序

if __name__=='__main__':
    print("***基于用户的协同过滤算法的电影推荐实例实现***")
    users = {  'UserA': {'《战狼2》': 4.5, '《红海行动》': 4.5,'《湄公河行动》': 4.0, '《你好 李焕英》': 3.5,'《泰囧》': 3.0, '《港囧》': 2.5},

             'UserB': {'《战狼2》': 4.0, '《红海行动》': 3.5,'《湄公河行动》': 4.5, '《你好 李焕英》': 3.0, '《泰囧》': 3.0,'《港囧》': 3.5},

             'UserC': {'《战狼2》': 4.5, '《红海行动》': 4.0,                 '《你好 李焕英》': 3.5, '《泰囧》': 3.0},

             'UserD': {             '《红海行动》': 4.5, '《湄公河行动》': 4.0,'《你好 李焕英》': 4.0, '《泰囧》': 3.5,'《港囧》': 2.5},

             'UserE': {'《战狼2》': 4.0, '《红海行动》': 4.0,'《湄公河行动》': 4.0, '《你好 李焕英》': 4.5, '《泰囧》': 3.0,'《港囧》': 3.0},

             'UserF': {'《战狼2》': 4.0, '《红海行动》': 4.0,                 '《你好 李焕英》': 3.5, '《泰囧》': 3.0,'《港囧》': 3.5},

             'UserG': {              '《红海行动》': 4.5,                '《你好 李焕英》': 4.0,             '《港囧》': 2.0}
             }

    userCf=UserCf(data=users)
    recommandList=userCf.recomand('UserG', 2)
    print( "最终推荐:%s"%recommandList)
  • 5
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Z_凌云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值