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

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

@TOC


前言

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

一、协同过滤算法简介

协同过滤是一种基于用户和物品之间关系的推荐算法。它主要分为两类:基于用户的协同过滤(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个用户推荐电影。

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

目录
相关文章
|
13天前
|
机器学习/深度学习 数据采集 搜索推荐
Python基于深度学习算法实现图书推荐系统项目实战
Python基于深度学习算法实现图书推荐系统项目实战
|
16天前
|
安全 Java 调度
「Python入门」Python多线程
1. **线程与进程区别**:线程共享内存,进程独立;线程启动快,多线程效率高于多进程。 2. **多线程使用**:直接使用Thread类,通过`target`指定函数,`args`传递参数;或继承Thread,重写`run`方法。 3. **守护线程**:设置`setDaemon(True)`,主线程结束时,守护线程一同结束。 4. **join线程同步**:主线程等待子线程完成,如`t.join()`。 5. **线程锁**(Mutex):防止数据竞争,确保同一时间只有一个线程访问共享资源。 6. **RLock(递归锁)**:允许多次锁定,用于需要多次加锁的递归操作。
20 1
「Python入门」Python多线程
|
16天前
|
数据采集 XML JSON
「Python入门」Python代码规范(风格)
**Python编码规范摘要** - 编码:使用UTF-8编码,文件开头可声明`# -- coding: utf-8 --`。 - 分号:避免在行尾使用,不用于分隔命令。 - 行长:不超过80字符,长表达式可使用括号换行。 - 缩进:使用4个空格,禁止混用tab。 - 注释:行注释始于`#`和空格,块注释和文档注释遵循特定格式。 - 空行:函数和类定义间用2空行,方法间1空行,内部适当空行。 - 空格:运算符两侧各空一格,逗号后空格,括号内不空格。 - 命名:模块小写,变量下划线分隔,类驼峰式,布尔变量前缀`is_`。 - 引号:保持一致性,可使用单引号或双引号。
19 1
「Python入门」Python代码规范(风格)
|
6天前
|
存储 分布式计算 索引
Python函数式编程入门窥探
Python本身不是一门函数式编程语言,但是它参考了一些函数式编程语言很好的地方,除了可以写出更可读的代码外。还能用它来实现一些特定功能,本身也提供了强大的注解系统和函数和对象之间的灵活调用。
|
7天前
|
算法 数据挖掘 计算机视觉
Python并查集实战宝典:从入门到精通,让你的数据结构技能无懈可击!
【7月更文挑战第17天】并查集,如同瑞士军刀,是解决元素分组问题的利器,应用于好友关系、像素聚类、碰撞检测和连通性分析等场景。本文从基础到实战,介绍并查集的初始化、查找与路径压缩、按秩合并,以及在Kruskal算法中的应用。通过并查集,实现高效动态集合操作,对比哈希表和平衡树,其在合并与查找上的性能尤为突出。学习并查集,提升算法解决复杂问题的能力。
|
8天前
|
监控 数据可视化 定位技术
这本书凭什么得到ChatGPT认可,评价其为最值得读的Python入门书
在当今这个飞速发展且高度数字化的时代,编程已经成为一项至关重要的技能,其重要性愈发凸显。而 Python 作为一种在众多领域都有着广泛应用且相对来说较为容易学习的编程语言,顺理成章地成为了许多编程初学者的热门选择。 就在昨天,图灵君在浏览豆瓣的时候突然被这样一条评论闪到,一位网友说:“ChatGPT 推荐给我的入门书”。我想这书莫不是口碑爆棚、备受好评的蟒蛇书《Python编程:从入门到实践(第3版)》吧!仔细一看还真是!
|
16天前
|
机器学习/深度学习 数据采集 搜索推荐
Python数据分析与机器学习在电子商务推荐系统中的应用
Python数据分析与机器学习在电子商务推荐系统中的应用
39 5
|
15天前
|
数据采集 搜索推荐 算法
Python基于协同过滤算法进行电子商务网站用户行为分析及服务智能推荐
Python基于协同过滤算法进行电子商务网站用户行为分析及服务智能推荐
|
16天前
|
SQL 关系型数据库 MySQL
「Python入门」python操作MySQL和SqlServer
**摘要:** 了解如何使用Python的pymysql模块与MySQL数据库交互。首先,通过`pip install pymysql`安装模块。pymysql提供与MySQL的连接功能,例如创建数据库连接、执行SQL查询。在设置好MySQL环境后,使用`pymysql.connect()`建立连接,并通过游标执行SQL(如用户登录验证)。注意防止SQL注入,使用参数化查询。增删改操作需调用`conn.commit()`来保存更改。pymssql模块类似,但导入和连接对象创建略有不同。
17 0
「Python入门」python操作MySQL和SqlServer
|
16天前
|
并行计算 Java Python
「Python入门」Python多进程
本文探讨Python中的单进程和多进程。多进程使用`multiprocessing`库,如`Process`类,类似于`threading.Thread`。进程是操作系统分配资源的基本单位,每个程序至少有一个进程。多进程允许多个任务并发执行,提升效率,尤其在多核CPU上优于多线程,因Python的GIL限制了多线程的并行计算。文中通过吃饭睡觉打豆豆的例子,展示了单进程按顺序执行,多进程则可并发执行。还介绍了带参数的多进程、获取进程ID、主进程等待子进程结束及子进程守护等概念。在IO或网络密集型任务中,多线程和多进程各有优势,具体选择应根据任务类型和资源需求。
10 0
「Python入门」Python多进程