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

news2024/9/24 9:28:34

文章目录

  • 前言
  • 一、协同过滤算法简介
  • 二、计算相似度
  • 三、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.coloradmin.cn/o/798491.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

POI信息点的diPointX、diPointY转化成经纬度

需求&#xff1a;接口返回某个地点的数据&#xff08;diPointX、diPointY&#xff09;&#xff0c;前端需把该地点转化成经纬度形式在地图上进行Marker标记。 实现&#xff1a;&#xff08;查找百度地图开发文档&#xff09; 代码验证&#xff1a; console.log(new BMap.Merca…

性能测试问题之慢sql分析

我们在做性能测试的时候&#xff0c;慢sql也可以说是很常见问题&#xff0c;我的性能测试生涯几乎经常遇到慢sql&#xff0c;那么我们怎么来判断有没有慢sql呢&#xff0c;有慢sql后怎么来分析优化呢?如图&#xff1a; 通过上图看可以看到当存在慢sql的时候&#xff0c;这里会…

火爆全网,接口自动化测试-DDT数据驱动实战总结,一篇贯通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 DDT&#xff08;D…

信息安全:网络安全体系 与 网络安全模型.

信息安全&#xff1a;网络安全体系 与 网络安全模型. 网络安全保障是一项复杂的系统工程&#xff0c;是安全策略、多种技术、管理方法和人员安全素质的综合。一般而言&#xff0c;网络安全体系是网络安全保障系统的最高层概念抽象&#xff0c;是由各种网络安全单元按照一定的规…

python更换iterm2背景图片

背景 在看知乎的时候&#xff0c;突然看到了这样的一个视频教程&#xff0c;用python代码更换iterm2的背景。于是我细细的研究一下。视频地址 视频中提到的参考文章地址&#xff1a; iterm2官网官方仓库 实现过程 我直接把作者的代码粘贴如下&#xff0c;首先需要安装iter…

pycharm 使用远程服务器 jupyter (本地jupyter同理)

1. 远程服务器miniconda 环境中创建jupyter环境 # 1. 激活环境 conda activate envname#2. 在环境中安装jupyter pip install jupyter # 或者 conda install jupyter#3. 生成jupyter_notebook_config.py文件 jupyter notebook --generate-config#4. 设置密码 jupyter noteboo…

docker—springboot服务通信

文章目录 docker—springboot服务通信一、方式1、host 二、坑点末、参考资料 docker—springboot服务通信 一、方式 1、host 步骤&#xff1a; host文件增加域名解析&#xff1a; 127.0.0.1 rabbitmqapplication.yml&#xff1a; application.yml中&#xff0c;连接方式使用…

【HarmonyOS】API6使用storage实现轻量级数据存储

写在前面 本篇内容基于API6 JS语言进行开发&#xff0c;通过结合轻量级数据存储开发指导的文档&#xff0c;帮助大家完成一个实际的代码案例&#xff0c;通过这个小案例&#xff0c;可以实现简单数据的存储。 参考文档&#xff1a;文档中心 1、页面布局 首先我们编写一个简单…

C++容器——list的模拟实现

目录 一.list的基本结构 二. 接下来就是对list类构造函数的设计了&#xff1a; 三.链表数据的增加&#xff1a; 四.接下来就是迭代器的创建了&#xff1a; 四.简单函数的实现&#xff1a; 五.构造与析构 六.拷贝构造和赋值重载 传统写法: 现代写法&#xff1a; 七.迭…

Docker—— consul的容器服务更新与发现

Docker—— consul的容器服务更新与发现 一、Consul概述1.什么是服务注册与发现2.什么是consul 二、consul 部署1.consul服务器①. 建立 Consul 服务②. 查看集群信息③. 通过 http api 获取集群信息 2.registrator服务器①. 安装 Gliderlabs/Registrator②. 测试服务发现功能是…

别再被割韭菜了,小白几块钱就能打造专属AI知识库

随着AIGC各种项目的越发成熟&#xff0c;打造自己的知识库&#xff0c;对于企业和个人来说就变的门槛越来越低&#xff0c;自己的知识库&#xff0c;有许多的好处&#xff0c;上传自己的知识文档&#xff0c;能让对话变的更加垂直专业。 但是博主看到网站很多商家动辄几千的收…

使用docker-compose搭建lnmpr环境

源码gitee compose 使用的三个步骤&#xff1a; • 使用 Dockerfile 定义应用程序的环境。 • 使用 docker-compose.yml 定义构成应用程序的服务&#xff0c;这样它们可以在隔离环境中一起运行。 • 最后&#xff0c;执行 docker-compose up -d 命令来启动并运行整个应用程序…

Carla教程一:动力学模型到LQR

Carla教程一、动力学模型到LQR 从运动学模型和动力学模型到LQR 模型就是可以描述车辆运动规律的模型。车辆建模都是基于自行车模型的设定,也就是将四个轮子抽象为自行车一样的两个轮子来建模。 1、运动学模型 运动学模型是基于几何关系分析出来的,一般适用于低俗情况下,…

【西安交通大学】:融合传统与创新的学府之旅

【西安交通大学】&#xff1a;融合传统与创新的学府之旅 引言历史与发展学校特色学科优势院系专业校园环境与设施学生生活与社团活动校友荣誉与成就未来发展展望总结&#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&…

【Linux】Http协议的学习

文章目录 前言一、了解HTTP协议是如何规定的总结 前言 HTTP协议&#xff08;超文本传输协议&#xff09;和我们上一篇写的网络版计算器中自己定制的协议一样&#xff0c;只不过Http协议是是一个非常好用的协议&#xff0c;所以我们可以直接用现成的不用自己再搞一套了。 一、了…

LeetCode Top100 Liked 题单(序号1~17)

01Two Sum - LeetCode 我自己写的代码【193ms】 因为不知道怎么加cmp函数&#xff0c;就只能pair的first设为值了&#xff0c;但其实这也是瞎做&#xff0c;应该也是O(n&#xff09;吧 class Solution { public:vector<int> twoSum(vector<int>& nums, int …

【观察】智能运维的“下半场”,看云智慧如何“开新局”

毫无疑问&#xff0c;随着数字化转型的加速&#xff0c;越来越多的企业正在把数字化战略提升到一个全新的高度&#xff0c;转型的进程也正从“浅层次”的数字化走向“深层次”的数字化。 也正因此&#xff0c;过去传统的人工运维方式越来越“捉襟见肘”&#xff0c;谋求运维模…

飞桨paddlespeech语音唤醒推理C定点实现

前面的文章&#xff08;飞桨paddlespeech语音唤醒推理C浮点实现&#xff09;讲了飞桨paddlespeech语音唤醒推理的C浮点实现。但是嵌入式设备通常CPU频率低和memory小&#xff0c;在嵌入式设备上要想流畅的运行语音唤醒功能&#xff0c;通常用的是定点实现。于是我就在浮点实现&…

【redis】通过配置文件简述redis的rdb和aof

redis的持久化方式有2种&#xff0c;rdb&#xff0c;即通过快照的方式将全量数据以二进制记录在磁盘中&#xff0c;aof&#xff0c;仅追加文件&#xff0c;将增量的写命令追加在aof文件中。在恢复的时候&#xff0c;rdb要更快&#xff0c;但是会丢失一部分数据。aof丢失数据极少…

HTML快速学习

目录 一、网页元素属性 1.全局属性 2.标签 2.1其他标签 2.2表单标签 2.3图像标签 2.4列表标签 2.5表格标签 2.6文本标签 二、编码 1.字符的数字表示法 2.字符的实体表示法 三、实践一下 一、网页元素属性 1.全局属性 id属性是元素在网页内的唯一标识符。 class…