【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个用户推荐电影。

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

目录
相关文章
|
17天前
|
安全 数据处理 开发者
Python中的多线程编程:从入门到精通
本文将深入探讨Python中的多线程编程,包括其基本原理、应用场景、实现方法以及常见问题和解决方案。通过本文的学习,读者将对Python多线程编程有一个全面的认识,能够在实际项目中灵活运用。
|
3天前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
21 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
1天前
|
Python
深入理解Python装饰器:从入门到实践####
本文旨在通过简明扼要的方式,为读者揭开Python装饰器的神秘面纱,从基本概念、工作原理到实际应用场景进行全面解析。不同于常规的摘要仅概述内容概要,本文将直接以一段精炼代码示例开篇,展示装饰器如何优雅地增强函数功能,激发读者探索兴趣,随后深入探讨其背后的机制与高级用法。 ####
19 8
|
2天前
|
机器学习/深度学习 数据采集 搜索推荐
利用Python和机器学习构建电影推荐系统
利用Python和机器学习构建电影推荐系统
11 1
|
4天前
|
Python
探索Python装饰器:从入门到实践
【10月更文挑战第32天】在编程世界中,装饰器是一种特殊的函数,它允许我们在不改变原有函数代码的情况下,增加额外的功能。本文将通过简单易懂的语言和实际案例,带你了解Python中装饰器的基础知识、应用以及如何自定义装饰器,让你的代码更加灵活和强大。
11 2
|
5天前
|
监控 Python
探索Python中的装饰器:从入门到实践
【10月更文挑战第31天】在Python的世界里,装饰器是那些隐藏在幕后的魔法师,它们拥有着改变函数行为的能力。本文将带你走进装饰器的世界,从基础概念到实际应用,一步步揭开它的神秘面纱。你将学会如何用几行代码增强你的函数功能,以及如何避免常见的陷阱。让我们一起来发现装饰器的魔力吧!
|
12天前
|
数据采集 机器学习/深度学习 人工智能
Python编程入门:从基础到实战
【10月更文挑战第24天】本文将带你进入Python的世界,从最基础的语法开始,逐步深入到实际的项目应用。我们将一起探索Python的强大功能和灵活性,无论你是编程新手还是有经验的开发者,都能在这篇文章中找到有价值的内容。让我们一起开启Python的奇妙之旅吧!
|
14天前
|
数据采集 存储 数据库
Python中实现简单爬虫的入门指南
【10月更文挑战第22天】本文将带你进入Python爬虫的世界,从基础概念到实战操作,一步步指导你如何使用Python编写一个简单的网络爬虫。我们将不展示代码示例,而是通过详细的步骤描述和逻辑讲解,帮助你理解爬虫的工作原理和开发过程。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你打开一扇通往数据收集新世界的大门。
|
12天前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
【10月更文挑战第24天】 在Python的世界里,装饰器是一个既神秘又强大的工具。它们就像是程序的“隐形斗篷”,能在不改变原有代码结构的情况下,增加新的功能。本篇文章将带你走进装饰器的世界,从基础概念出发,通过实际例子,逐步深入到装饰器的高级应用,让你的代码更加优雅和高效。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往高效编程的大门。
|
14天前
|
存储 人工智能 数据挖掘
Python编程入门:构建你的第一个程序
【10月更文挑战第22天】编程,这个听起来高深莫测的词汇,实际上就像搭积木一样简单有趣。本文将带你走进Python的世界,用最浅显的语言和实例,让你轻松掌握编写第一个Python程序的方法。无论你是编程新手还是希望了解Python的爱好者,这篇文章都将是你的理想起点。让我们一起开始这段奇妙的编程之旅吧!
18 3
下一篇
无影云桌面