系列文章目录
Part1 推荐系统基础
Part2 Movienles介
Part3 协同过滤基础
Part4 协同过滤进阶
Part5 矩阵分解SVD
Part6 Slope-One算法
前言
根据之前几篇文章的介绍,我们应该对协同过滤和矩阵分解算法有了比较深入的了解。由于协同过滤存在计算量过大,不擅长处理稀疏矩阵的问题,因此,在协同过滤的基础上衍生出了矩阵分解算法。本文要介绍的slope one算法也是为了应对稀疏矩阵。
Slope One是一种基于评分的协同过滤算法。基于评分的Slope One算法具有简单、易懂、易于维护和执行、及时更新性等特点。与其他的个性化推荐算法相比,该算法不计算项目之间的相似度, 而是用一种简单的线性回归模型进行预测(可以扩展)。算法易于实现,计算速度快,可扩展性好。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Slope-one算法流程
1.算法原理
我们先举一个简单的例子:多个吃货在某美团的某家饭馆点餐,如下两道菜:可乐鸡翅和红烧肉;顾客吃过后,会有相关的星级评分。假设评分如下:
评分 | 可乐鸡翅 | 红烧肉 |
---|---|---|
小陆 | 4 | 5 |
小红 | 4 | 3 |
小伟 | 2 | 3 |
小芳 | 3 | ? |
问题:请猜测一下小芳可能会给“红烧肉”打多少分?
思路:把两道菜的平均差值求出来,可乐鸡翅减去红烧肉的平均偏差:[(4-5)+(4-3)+(2-3)]/3=-0.333。一个新客户比如小芳,只吃了可乐鸡翅评分为3分,那么可以猜测她对红烧肉的评分为:3-(-0.333)=3.333
这就是slope one 算法的基本思路,非常非常的简单。
(1)
第一步
:筛选用户集合。在User-Item评分矩阵中并非所有用户都参与目标项目评分,而是只有对目标项目评过分的用户才构成用户集合;
(2)
第二步
:筛选项目集合。根据目标用户的已评分项目来筛选集合中其他用户是否对该项目进行过评分,如果有,就把该项目筛选到参与算法运算的项目集合中。如果没有,该项目即不参与运算;
(3)
第三步
:预测项目评分。将User-Item评分矩阵通过筛选用户和筛选项目后得到参与Slope One算法运算的评分数据。其中,Slope One算法的运算过程如下所示:
2.实例分析
假设有100个人对物品A和物品B打分了,R(AB)表示这100个人对A和B打分的平均偏差;有1000个人对物品B和物品C打分了, R(CB)表示这1000个人对C和B打分的平均偏差;
二、Python实战
代码如下:
def loadData():
items={'A':{1:5,2:3},
'B':{1:3,2:4,3:2},
'C':{1:2,3:5}}
users={1:{'A':5,'B':3,'C':2},
2:{'A':3,'B':4},
3:{'B':2,'C':5}}
return items,users
#***计算物品之间的评分差
#items:从物品角度,考虑评分
#users:从用户角度,考虑评分
def buildAverageDiffs(items,users,averages):
#遍历每条物品-用户评分数据
for itemId in items:
for otherItemId in items:
average=0.0 #物品间的评分偏差均值
userRatingPairCount=0 #两件物品均评过分的用户数
if itemId!=otherItemId: #若无不同的物品项
for userId in users: #遍历用户-物品评分数
userRatings=users[userId] #每条数据为用户对物品的评分
#当前物品项在用户的评分数据中,且用户也对其他物品由评分
if itemId in userRatings and otherItemId in userRatings:
#两件物品均评过分的用户数加1
userRatingPairCount+=1
#评分偏差为每项当前物品评分-其他物品评分求和
average+=(userRatings[otherItemId]-userRatings[itemId])
averages[(itemId,otherItemId)]=average/userRatingPairCount
#***预测评分
#users:用户对物品的评分数据
#items:物品由哪些用户评分的数据
#averages:计算的评分偏差
#targetUserId:被推荐的用户
#targetItemId:被推荐的物品
def suggestedRating(users,items,averages,targetUserId,targetItemId):
runningRatingCount=0 #预测评分的分母
weightedRatingTotal=0.0 #分子
for i in users[targetUserId]:
#物品i和物品targetItemId共同评分的用户数
ratingCount=userWhoRatedBoth(users,i,targetItemId)
#分子
weightedRatingTotal+=(users[targetUserId][i]-averages[(targetItemId,i)])\
*ratingCount
#分母
runningRatingCount+=ratingCount
#返回预测评分
return weightedRatingTotal/runningRatingCount
# 物品itemId1与itemId2共同有多少用户评分
def userWhoRatedBoth(users,itemId1,itemId2):
count=0
#用户-物品评分数据
for userId in users:
#用户对物品itemId1与itemId2都评过分则计数加1
if itemId1 in users[userId] and itemId2 in users[userId]:
count+=1
return count
if __name__=='__main__':
items,users=loadData()
averages={}
#计算物品之间的评分差
buildAverageDiffs(items,users,averages)
#预测评分:用户2对物品C的评分
predictRating=suggestedRating(users,items,averages,2,'C')
print 'Guess the user will rate the score :',predictRating
————————————————
原文链接:https://blog.csdn.net/xidianliutingting/article/details/51916578
运行结果
Guess the user will rate the score : 3.3333333333333335
参考
稀饭居然不在家:【算法总结】Slope One协同过滤
心雨心辰:推荐算法之 slope one 算法
总结
本文主要介绍了slope-one算法,它是在协同过滤的基础上改进而来的。该算法适用于物品更新不频繁,数量相对较稳定并且物品数目明显小于用户数的场景。依赖用户的用户行为日志和物品偏好的相关内容。
优点:
1.算法简单,易于实现,执行效率高;
2.可以发现用户潜在的兴趣爱好;
缺点:
依赖用户行为,存在冷启动问题和稀疏性问题;该算法只是简单的采用线性回归分析项目间的相似性,未考虑其它因素对算法推荐精度的影响。