【Python入门系列】第十九篇:Python基于协同过滤推荐系统的实现

文章目录

  • 前言
  • 一、协同过滤算法简介
  • 二、计算相似度
  • 三、Python实现简单的协同过滤推荐系统
  • 总结


前言

推荐系统是现代互联网平台中的重要组成部分,它可以根据用户的兴趣和行为,向其推荐个性化的内容。协同过滤是推荐系统中常用的一种方法,它基于用户的行为数据,通过计算用户之间的相似度,找到相似用户的喜好,从而给用户推荐相似的内容。

一、协同过滤算法简介

协同过滤是一种基于用户和物品之间关系的推荐算法。它主要分为两类:基于用户的协同过滤(User-Based Collaborative Filtering,简称UBCF)和基于物品的协同过滤(Item-Based Collaborative Filtering,简称IBCF)。

  • 基于用户的协同过滤:通过计算用户之间的相似度,找到与目标用户相似的用户,再推荐这些相似用户喜欢的物品给目标用户。
  • 基于物品的协同过滤:通过计算物品之间的相似度,找到与目标物品相似的物品,再推荐这些相似物品给喜欢目标物品的用户。

二、计算相似度

在协同过滤算法中,需要计算用户或物品之间的相似度。常用的相似度计算方法有:

  • 皮尔逊相关系数(Pearson Correlation Coefficient)
  • 余弦相似度(Cosine Similarity)
  • Jaccard相似度(Jaccard Similarity)
    在本文的示例中,我们将使用余弦相似度作为相似度计算方法。

三、Python实现简单的协同过滤推荐系统

def loadExData():
    return[[1,1,1,0,0],
            [2,2,2,0,0],
            [1,1,1,0,0],
            [5,5,5,0,0],
            [1,1,0,2,2],
            [0,0,0,3,3],
            [0,0,0,1,1]]

def loadExData2():
    return[[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],
           [0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],
           [0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],
           [3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],
           [5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],
           [0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],
           [4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],
           [0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],
           [0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],
           [0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],
           [1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]
    
from numpy import * 
from numpy import linalg as la 

#欧氏距离
def euclidSim(inA,inB):
    return 1.0/(1.0+la.norm(inA-inB))

#皮尔逊相关系数  
def pearsSim(inA,inB):

    if len(inA)<3:return 1.0

    return 0.5+0.5*corrcoef(inA,inB,rowvar=0)[0][1]

#余弦相似度
def cosSim(inA,inB):

    num=float(inA.T*inB)
    denom=la.norm(inA)*la.norm(inB)

    return 0.5+0.5*(num/denom)
    
    
#基于物品相似度的推荐引擎(标准相似度计算方法下的用户估计值  )
def standEst(dataMat,user,simMeas,item):

    #商品数目
    n=shape(dataMat)[1]

    #两个用于计算估计评分值的变量
    simTotal=0.0;
    ratSimTotal=0.0

    #遍历所有商品,并将它与所有的物品进行比较
    for j in range(n):

        #用户对某个物品的评分
        userRating=dataMat[user,j]

        if userRating==0:
            continue

        # logical_and:矩阵逐个元素运行逻辑与,返回值为每个元素的True,False  
        # dataMat[:,item].A>0: 第item列中大于0的元素  
        # dataMat[:,j].A: 第j列中大于0的元素  
        # overLap: dataMat[:,item],dataMat[:,j]中同时都大于0的那个元素的行下标(一个向量) 

        overLap=nonzero(logical_and(dataMat[:,item].A>0,\
                                    dataMat[:,j].A>0))[0]

        print(j)
        print("------overLap------")
        print(overLap)

        if len(overLap)==0:
            similarity=0

        # 计算overLap矩阵的相似度
        else: similarity=simMeas(dataMat[overLap,item],\
                        dataMat[overLap,j])

        print("dataMat[overLap,item:")
        print(dataMat[overLap,item])
        print("dataMat[overLap,j:")
        print(dataMat[overLap,j])
        print ('the %d and %d similarity is:%f' % (item,j,similarity))

        # 累计总相似度(不太理解)
#        假设A评分未知,A,B相似度0.9,B评分5,;A C相似度0.8,C评分4.
#        那么按照公式A评分=(0.9*5+0.8*4)/(0.9+0.8)
#       相当于加权平均(如果除以2),但是因为2个评分的权重是不一样的,所以应除以相似度之和

        simTotal+=similarity

        # ratSimTotal = 相似度*元素值 
        ratSimTotal+=similarity*userRating

        print("ratSimTotal+=similarity*userRating:")
        print(ratSimTotal)

    if simTotal==0:
        return 0
    else:
        return ratSimTotal/simTotal

#对某个用户产生最高的N个推荐结果
#user 表示要推荐的用户编号
def recommend(dataMat,user,N=3,simMeas=cosSim,estMethod=standEst):

    #对给定用户建立一个未评分的物品矩阵
    unratedItems=nonzero(dataMat[user,:].A==0)[1] #第user行中等于0的元素 

#    print(dataMat[user,:].A==0)----[[ True  True  True ...,  True False  True]]
#    对于二维数组b2,nonzero(b2)所得到的是一个长度为2的元组。它的第0个元素是数组a中值不为0的元素的第0轴的下标,第1个元素则是第1轴的下标,因此从下面的结果可知b2[0,0]、b[0,2]和b2[1,0]的值不为0:
#
#>>> b2 = np.array([[True, False, True], [True, False, False]])  
#>>> np.nonzero(b2)  
#(array([0, 0, 1], dtype=int64), array([0, 2, 0], dtype=int64))  
   
    if len(unratedItems)==0:
        return 'you rated everything'

    #给未评分物品存放预测得分的列表
    itemScores=[]

    for item in unratedItems:
        #对每个未评分物品通过standEst()方法来预测得分
        print("item------------")
        print(item)

        estimatedScore=estMethod(dataMat,user,simMeas,item)

        #将物品编号和估计得分存放在列表中
        itemScores.append((item,estimatedScore))

    #sorted排序函数,key 是按照关键字排序,lambda是隐函数,固定写法,
    #jj表示待排序元祖,jj[1]按照jj的第二列排序,reverse=True,降序;[:N]前N个
    return sorted(itemScores,key=lambda jj:jj[1],reverse=True)[:N]
    
#利用SVD提高推荐效果
#基于SVD的评分估计
def svdEst(dataMat,user,simMeas,item):

    #商品数目    
    n=shape(dataMat)[1]
    simTotal=0.0;ratSimTotal=0.0

    #SVD分解为:U*S*V
    U,Sigma,VT=la.svd(dataMat)

    #分解后只利用90%能量的奇异值,存放在numpy数组里面
    Sig4=mat(eye(4)*Sigma[:4])

    #利用U矩阵将物品转换到低维空间中
    xformeditems=dataMat.T*U[:,:4]*Sig4.I

    for j in range(n):
        userRating=dataMat[user,j]

        if userRating==0 or j==item:continue
        similarity=simMeas(xformeditems[item,:].T,\
                            xformeditems[j,:].T)
        print ('the %d and %d similarity is :%f' % (item,j,similarity))
        simTotal+=similarity
        ratSimTotal+=similarity*userRating

    if simTotal==0:return 0
    else: return ratSimTotal/simTotal 
    
if __name__ == '__main__':
   myMat=mat(loadExData2())
   print(recommend(myMat,2))

在这里插入图片描述

总结

这段代码主要是通过协同过滤的方式实现一个电影推荐系统。具体流程如下:

  1. 首先,定义了两个函数loadExData()和loadExData2(),它们返回的是用户对电影的评分数据,这些数据被用来作为推荐系统的输入。

  2. 然后,定义了三个函数euclidSim(),pearsSim()和cosSim(),它们分别用于计算欧氏距离、皮尔逊相关系数和余弦相似度。这些相似度计算方法用于计算用户或者物品之间的相似性。

  3. 接下来,定义了两个函数standEst()和svdEst(),它们分别用于基于标准相似度和SVD(奇异值分解)的评分估计。这些评分估计方法用于预测用户对未评分物品的评分。

  4. 然后,定义了一个函数recommend(),它用于对某个用户产生最高的N个推荐结果。这个函数首先找出用户未评分的物品,然后对每个未评分物品通过评分估计方法来预测得分,最后将预测得分最高的N个物品推荐给用户。

  5. 最后,在主函数中,加载了用户对电影的评分数据,然后调用recommend()函数为第2个用户推荐电影。

总的来说,这段代码实现了一个基于协同过滤的电影推荐系统,通过计算用户或者物品之间的相似性,预测用户对未评分物品的评分,然后将预测得分最高的物品推荐给用户。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/48739.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flutter:flutter_local_notifications——消息推送的学习

前言 注&#xff1a; 刚开始学习&#xff0c;如果某些案例使用时遇到问题&#xff0c;可以自行百度、查看官方案例、官方github。 简介 Flutter Local Notifications是一个用于在Flutter应用程序中显示本地通知的插件。它提供了一个简单而强大的方法来在设备上发送通知&#…

PostgreSQL 查询json/jsonb是否存在某个片段

文章目录 前言实现实现思路坑1坑2坑3 恍然大悟 前言 在PostgreSQL中&#xff0c;jsonb有额外的操作符&#xff0c;如 >、<、?、?|、?& 可以用来查询是否包含路径/值&#xff0c;以及顶层键值是否存在。 详细文章&#xff1a;PostgreSQL 操作json/jsonb 那么&am…

青大数据结构【2021】

一、单选&#xff08;17&#xff01;&#xff09; 根据中序遍历得到降序序列可以知道&#xff0c;每个结点的左子树的结点的值比该结点的值小&#xff0c;因为没有重复的关键字&#xff0c;所以拥有最大值的结点没有左子树。 二、简答 三、分析计算 四、算法分析 3.迪杰斯特拉…

LLaMA2可商用|GPT-4变笨|【2023-0723】【第七期】

一、大咖观点&#xff1a; 傅盛&#xff1a;ChatGPT时代如何创业 - BOTAI - 博客园Google 已经被OpenAI 超越了吗&#xff1f;| AlphaGo 之父深度访谈《人民日报》&#xff1a;大模型的竞争&#xff0c;是国家科技战略的竞争WAIC 2023 | 张俊林&#xff1a;大语言模型带来的交…

贝塞尔曲线与B样条曲线

B-spline and Bezier Curve 介绍一下robotics运动规划方向的B样条曲线与贝塞尔曲线相关知识。 0728&#xff1a;TODO&#xff0c;节点向量如何得到&#xff1f; 贝塞尔曲线&#xff0c;B-样条&#xff0c;非均匀有理B样条梳理曲线篇: 贝塞尔曲线Animated Bzier CurvesBzier …

gin框架内容(三)--中间件

gin框架内容&#xff08;三&#xff09;--中间件 Gin框架允许开发者在处理请求的过程中&#xff0c;加入用户自己的函数。这个函数就叫中间件&#xff0c;中间件适合处理一些公共的业务逻辑&#xff0c;比如登录认证、权限校验、数据分页、记录日志、耗时统计等 即比如&#x…

【牛客面试必刷TOP101】Day1.反转链表和合并两个排序的链表

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;牛客面试必刷TOP101 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&…

【Ansible】Ansible自动化运维工具的应用与常用命令

ansible自动化运维工具 一、ansible 的概述1. ansible 的概念2. ansible 的特性 二、ansible 的部署与命令1. ansible 的部署1.1 服务器ip地址设置1.2 ansible 服务器部署 2. ansible 命令行模块2.1 command 模块2.2 shell 模块2.3 cron 模块2.4 user 模块2.5 group 模块2.6 co…

财报解读:新鲜感褪去后,微软直面AI的骨感现实?

微软交出了一份远观尚可&#xff0c;但近看承压的“答卷”。 北京时间2023年7月26日&#xff0c;微软披露了2023财年第四财季及全年财报。受生产力和业务流程部门和智能云部门等业务带动&#xff0c;微软第四财季营收561.89亿美元&#xff0c;同比增长8%&#xff1b;净利润200…

【iOS】—— 持久化

文章目录 数据持久化的目的iOS中数据持久化方案数据持久化方式分类内存缓存磁盘缓存 沙盒机制获取应用程序的沙盒路径沙盒目录的获取方式 持久化数据存储方式XML属性列表Preferences偏好设置&#xff08;UserDefaults&#xff09;数据库存储什么是序列化和反序列化&#xff0c;…

TypeError: Failed to fetch dynamically imported module

浏览器报了如下错误&#xff1a; vue文件如下&#xff1a; 错误出现的原因是因为导入的是路径&#xff0c;vue会在该路径下的文件夹搜索所有文件&#xff0c;但是没有找到对应的组件&#xff0c;但是浏览器并不会直接禁止访问&#xff0c;而是在控制台报错&#xff0c;解决办法…

【雕爷学编程】Arduino动手做(174)---Sensor Shield V5.0传感器扩展板

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

k8s证书过期

k8s证书过期 [rootk8s-master102 ~]# kubectl get pod -A Unable to connect to the server: x509: certificate has expired or is not yet valid: current time 2023-07-25T15:14:0008:00 is after 2023-07-24T16:25:58Z解决方案 备份 kubernetes配置 cp -r /etc/kubernet…

【Python 实战】---- 批量识别图片中的文字,存入excel中【使用百度的通用文字识别】

分析 1. 获取信息图片示例 2. 运行实例 3. 运行结果 4. 各个文件的位置 实现 1. 需求分析 识别图片中的文字【采用百度的通用文字识别】;文字筛选,按照分类获取对应的文本;采用 openpyxl 实现将数据存入 excel 中。2. 获取 access_token 获取本地缓存的

谈谈你对Synchronized关键字的理解及使用

synchronized关键字最主要的三种使用方式的总结 修饰实例方法&#xff0c;作用于当前对象实例加锁&#xff0c;进入同步代码前要获得当前对象实例的锁修饰静态方法&#xff0c;作用于当前类对象加锁&#xff0c;进入同步代码前要获得当前类对象的锁 。也就是给当前类加锁&…

DFS之剪枝与优化--小猫爬山

思路&#xff1a;对小猫的数量和车箱数进行bfs&#xff0c;一旦小猫的数量达到n&#xff0c;就统计ans的数量&#xff0c;如果当前车的剩余重量无法再承受任意一个猫的重量&#xff0c;那么我们将车辆数1来保证小猫能够下山。 #include<bits/stdc.h> using namespace std…

芯片制造详解.净洁室的秘密.学习笔记(三)

这是芯片制造系列的第三期跟学up主三圈&#xff0c;这里对其视频内容做了一下整理和归纳&#xff0c;喜欢的可以看原视频。 芯片制造详解03&#xff1a; 洁净室的秘密&#xff5c;为何芯片厂缺人&#xff1f; 芯片制造详解.净洁室的秘密.学习笔记 三 简介一、干净的级别二、芯片…

Mybatis 新增/批量新增, 拿到返回的自增主键ID

单个新增 &#xff1a; /** * 插入菜单 * param menuInfo * return */ int insertMenuInfo(MenuInfo menuInfo); xml&#xff1a; <insert id"insertMenuInfo" parameterType"com.XXXX..MenuInfo" keyProperty"id&quo…

devops(后端)

1.前言 该devpos架构为gitlabjenkinsharbork8s&#xff0c;项目是java项目&#xff0c;流程为从gitlab拉取项目代码到jenkins&#xff0c;jenkins通过maven将项目代码打成jar包&#xff0c;通过dockerfile构建jdk环境的镜像并把jar包放到镜像中启动&#xff0c;构建好的镜像通…

系统集成项目管理工程师挣值分析笔记大全

系统集成项目管理工程师挣值分析笔记大全 挣值分析是一种项目管理技术&#xff0c;用于量化和监控项目绩效。它通过比较计划值&#xff08;PV&#xff09;、实际成本&#xff08;AC&#xff09;和挣值&#xff08;EV&#xff09;三个参数来评估项目的进展情况和成本绩效。 挣值…
最新文章