声明:本文仅为学习笔记,欢迎各位大佬的意见与建议,侵权删
一、协同过滤算法
协同过滤算法,collaborative filtering(CF),通过挖掘用户历史行为信息,从而发现用户偏好。基于不同 的偏好,对用户或产品进行群组划分,最后为目标用户推荐对应的信息。“协同”即利用多个用户数据对数据进行挖掘,“过滤”即信息筛选的过程。
主要功能及预测和推荐。
协同过滤算法分为:1、基于用户的协同过滤算法;2、基于产品的协同过滤算法
1、基于用户的协同过滤算法
基于用户的协同过滤算法(userCF),通过挖掘用户的历史数据,寻找与目标用户具有相似喜好的用户,将相关的物品推荐给具有相似喜好的用户。本质是寻找客户。举个例子:A和B都喜欢汗蒸和捏脚,同时A还喜欢泰式按摩,那么就可以把泰式按摩也推荐给B。
比如,现在有一份数据,提供了几名客户对不同服务的喜爱程度:

这样格式的数据比较难以反映出谁更喜欢哪项服务,谁与谁有相似的爱好等信息,因此可以通过构建数据透视表,使得数据更为清晰。
所用函数:pivot_table(index,colum,values),例子:
import pandas
data = pandas.read_csv(r"D:\Python Code\dataMining\大保健.csv",encoding="GBK")
preference = data.pivot_table(index="服务",columns="客户",values="喜爱程度")
print(data)
print("----------------------------以下是数据透视表------------------------")
print(preference)
运行结果:

那么如何评价客户间喜好的相似程度呢?
我们需要使用皮尔森相关系数(P)。
至于皮尔森相关系数是啥,百度一下你就知道
注意,计算皮尔森向相关系数时,取双方公共的的数据,比如,要计算老张和老王之间的皮尔森相关系数,老张的数据为[4,3],老王的数据为[5,5]。要计算老张和老李的相关系数,那么,老张的数据为[4],老李为[5]
P=0 两变量非线性相关(注意,这个时候可能是非线性的关系)
P∈(0,0.3] 弱相关
P∈(0.3,0.8] 中等相关
P∈(0.8,1] 强相关,1的时候刚好可以线性表示
计算皮尔森相关系数
Dataframe数据类型提供corr()函数,该函数可以计算皮尔森相关系数(pearson),肯德尔相关系数(Kendall),斯皮尔曼相关系数(spearman)。
例子:
import pandas
import numpy as np
data = pandas.read_csv(r"D:\Python Code\dataMining\大保健.csv",encoding="GBK")
preference = data.pivot_table(index="服务",columns="客户",values="喜爱程度")
#min_periods表示最小数据量,小于min_periods将不被计算。
#如果min_period=3,那么就只计算老张和老王的相关系数了
corr_ = preference.corr(method="pearson",min_periods=1)
print(preference)
print("-------------------------------------------")
print(corr_)
运行结果(你会发现 比如老张对老赵的相关系数是空值,可是明明min_period=1,按理来说他们之间应该存在相关系数。那么是什么原因呢?由于皮尔森相关系数公式定义中,分母是两个方差相乘,而在计算老张老赵的相关系数的时候,数据为[8],[3],只有一个数值,那么方差就为0,导致皮尔森相关系数的分母为0,就出现了空值。当然还有其他时候也会出现空值,看这里):

对目标用户做出推荐的依据
比如,我的目标用户是老张,那么我就要找到和老王皮尔森相关系数最高的那个客户,通过这个客户的喜好来给老王做推荐。
corr_ = preference.corr(method="pearson",min_periods=1)
#获取老张这一列的相关系数,并删除老张对自己的相关系数
zhang = corr_["老张"].drop(index="老张")
#获取相关系数最大的那个索引
mostSimilar = zhang.idxmax()
print(zhang)
print("-------------------")
print(mostSimilar)
运行结果:

获得需要推荐的服务清单
targetService = preference[mostSimilar]
targetService = targetService[targetService.values >= 7]#假定评分大于7的才有值得推荐
targetServiceName = targetService.index
print(targetServiceName)
print("------------------------")
noNeed = preference["老张"].dropna().index#去除空值(没评分),即老张已经体验过的就不再推荐了
print(noNeed)
print("------------------------")
recommend = targetServiceName[~targetServiceName.isin(noNeed)].values
print(recommend)
运行结果(需要给老张推荐SPA):

那么基于用户的系统过滤的完整代码大致如下,可以分为两个步骤1、找到“臭味相投”的客户,2、把“臭味相投”的那位的喜好推荐给目标客户。
import pandas
data = pandas.read_csv(r"D:\Python Code\dataMining\大保健.csv",encoding="GBK")
preference = data.pivot_table(index="服务",columns="客户",values="喜爱程度")
corr_ = preference.corr(method="pearson",min_periods=1)
#获取老张这一列的相关系数,并删除老张对自己的相关系数
zhang = corr_["老张"].drop(index="老张")
#获取相关系数最大的那个索引
mostSimilar = zhang.idxmax()
targetService = preference[mostSimilar]
targetService = targetService[targetService.values >= 7]#假定评分大于7的才有值得推荐
targetServiceName = targetService.index
noNeed = preference["老张"].dropna().index#去除空值(没评分),即老张已经体验过的就不再推荐了
recommend = targetServiceName[~targetServiceName.isin(noNeed)].values
print(recommend)
2、基于物品的协同过滤
基于物品的协同过滤(itemCF),即根据用户的历史偏好将与这些偏好同类的物品推荐给客户,本质上是面向物品的。比如一个客户喜欢搓澡,捏脚,那他基本上也喜欢SPA,所以就会推荐SPA。
由于过程和基于用户的协同过滤类似,所以这里先给出完整代码,在讨论其中一些比较重要的部分。
import pandas
data = pandas.read_csv(r"D:\Python Code\dataMining\大保健.csv",encoding="GBK")
preference = data.pivot_table(index="客户",columns="服务",values="喜爱程度")
#计算不同服务的相似程度(皮尔森相关系数)
corr_ = preference.corr(method="pearson",min_periods=1)
#获取老张评分过的服务
zhang = preference.loc["老张"].dropna()
#获取老张评分过的服务以及相应的评分
service_zhang = zhang.index
serviceRate_zhang = zhang.values
#获取老张评分过的服务和他没评分过的服务的皮尔森相关系数
similarService = corr_[service_zhang].drop(index = service_zhang)
#计算老张对他没评分过的服务的感兴趣程度
product = serviceRate_zhang*similarService
tendToPrefer = product.sum(axis=1)
#递减排序,取最高的那个
tendToPrefer = tendToPrefer.sort_values(ascending = False)
recomList = tendToPrefer.index[0:1].values
print(recomList)
#运行结果:
#['泰式按摩']
前面的部分没什么好讲的,基于用户的协同过滤是计算用户间的相似性,那么基于物品的协同过滤就是计算物品的相似性。所以在生成数据透视表的时候行和列要互换。
然后计算每个服务之间的皮尔森相关系数。
这里我们假定目标用户是老张,即给老张推荐服务。所以我们同样还是获取老张已经享受过的服务以及他的评价,并通过这些评价计算出老张是否喜欢那些他没评价过的服务。
接下来就是关键之处了,我们判断是否将一个服务推荐给客户并不完全通过服务与服务之间的相似性,即皮尔森相关系数。服务A与服务B可能之间的皮尔森相关系数最高,但并不代表目标客户会喜欢。因此我们要判断的是用户对某个服务的喜爱程度。
那么喜爱程度怎么算呢?这里用过公式:。
Puj代表的就是用户u对服务j的喜爱程度。wji表示服务j和服务i之间的皮尔森相关系数,rui表示用户u对服务i的评价。其中服务i是用户已经评价过的服务中的一个。将每个服务i对应的wui与rui相乘,得到的数值相加,得到的就是用户u对服务j的喜爱程度了。翻译成人话就是,服务i和服务j有一定相关性,同时我对服务i有一个评价,那么我对服务j的评价很可能和服务i的评价相关。服务i与服务j的相关性越高,且我对服务i的评价越高,我就越可能喜欢服务j。
所以这段代码就是在计算老张对所有他没评价过的服务的喜爱程度。要注意的是,倒数第二行中,serviceRate_zhang*similarService中,符号*并不是传统意义的矩阵乘法。Dataframe的*的计算方式是:
service_zhang = zhang.index
serviceRate_zhang = zhang.values
#获取老张评分过的服务和他没评分过的服务的皮尔森相关系数
similarService = corr_[service_zhang].drop(index = service_zhang)
#计算老张对他没评分过的服务的感兴趣程度
product = serviceRate_zhang*similarService
tendToPrefer = product.sum(axis=1)
本文详细介绍了协同过滤算法在推荐系统中的两种主要类型:基于用户的协同过滤和基于物品的协同过滤。通过计算用户历史行为的皮尔森相关系数来发现用户或物品的相似性,并以此为基础进行推荐。在用户CF中,找到与目标用户兴趣最相似的用户,将他们的喜好推荐给目标用户;在物品CF中,计算物品之间的相似性,根据用户已有的喜好预测其可能的兴趣。整个过程中,数据处理和相似性计算是关键步骤。
:协同过滤&spm=1001.2101.3001.5002&articleId=125649063&d=1&t=3&u=19748f661913441092aed48982ee35c5)
3354

被折叠的 条评论
为什么被折叠?



