基于协同的SlopeOne推荐算法原理介绍和实现

本文深入探讨SlopeOne算法,一种高效、简单的Item-Based协同过滤推荐算法,由Daniel Lemire教授于2005年提出。SlopeOne算法通过计算物品间的评分差均值,预测用户对未评分物品的喜好,特别适用于物品更新不频繁的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

640?wx_fmt=png

640?wx_fmt=png

Slope One 算法是由 Daniel Lemire 教授在 2005 年提出的一个 Item-Based 的协同过滤推荐算法。

——文章概要

640?wx_fmt=png

该篇文章主要介绍Slope One算法。Slope One 算法是由 Daniel Lemire 教授在 2005 年提出的一个 Item-Based 的协同过滤推荐算法。和其它类似算法相比, 它的最大优点在于算法很简单, 易于实现, 执行效率高, 同时推荐的准确性相对较高。

  • 协同过滤算法理解和Python实现

  • 基于标签的推荐算法

  • 基于图的推荐算法

经典的ItemCF的问题

经典的基于物品推荐,相似度矩阵计算无法实时更新,整个过程都是离线计算的,而且还有另一个问题,相似度计算时没有考虑相似度的置信问题。例如,两个物品,他们都被同一个用户喜欢了,且只被这一个用户喜欢了,那么余弦相似度计算的结果是 1,这个 1 在最后汇总计算推荐分数时,对结果的影响却最大。

Slope One 算法针对这些问题有很好的改进。不过 Slope One 算法专门针对评分矩阵,不适用于行为矩阵。

Slope One算法过程

Slope One 算法是基于不同物品之间的评分差的线性算法,预测用户对物品评分的个性化算法。

Slope算法主要分为3步

1. 计算物品之间的评分差的均值,记为物品间的评分偏差 (两物品同时被评分)
640?wx_fmt=png

( r_ui - r_uj ) 表示评分的差,这里需要注意的是j相对i的评分偏差是 r_ui - r_uj ,如果是i相对j的评分偏差则是 r_uj - r _ui,两 者是互为相反数的关系。

其中:

  • r_ui :用户u对物品i的评分

  • r_uj :用户u对物品j的评分

  • N(i) :物品i评过分的用户

  • N(j) :物品j评过分的用户

  • N(i) 交 N(j) :表示同时对物品i 和物品j评过分的用户数。

2. 根据物品间的评分偏差和用户的历史评分,预测用户对未评分的物品的评分。
640?wx_fmt=png
其中:

  • N(u) :用户u评过分的物品

3. 将预测评分进行排序,取Top N对应的物品推荐给用户

实例说明

例如现在有一份评分数据,表示用户对电影的评分:

640?wx_fmt=png

现在我们来预测预测每个用户对未评分电影的评分。

Step1: 计算物品之间的评分偏差,以U1为例:
640?wx_fmt=png
640?wx_fmt=png
640?wx_fmt=png
640?wx_fmt=png

同理可以计算出电影b,c,d,e与其他电影的评分偏差。

Step2: 计算用户对未评分物品的可能评分(为了方便计算,这里以U2为例)

由上表可知,用户U2 对电影a没有评分,这里计算用户U2对电影a的评分。

640?wx_fmt=png

Step3: 评分排序

由于给定样例中,U2只对a没有评过分,所以这里不需要进行排序,正常的话,按分数进行倒排就行。

代码实现

这里采用Python实现,在实现过程中并没有考虑算法的复杂度问题。

加载数据

    def loadData(self):	
        user_rate = {	
            "U1": {"a": 2, "b": 3, "c": 3, "d": 4},	
            "U2": {"b": 4, "c": 2, "d": 3, "e": 3},	
            "U3": {"a": 4, "b": 2, "c": 3, "e": 2},	
            "U4": {"a": 3, "c": 5, "d": 4, "e": 3}	
        }	
        item_rate = {	
            "a": {"U1": 2, "U3": 4, "U4": 3},	
            "b": {"U1": 3, "U2": 4, "U3": 2},	
            "c": {"U1": 3, "U2": 2, "U3": 3, "U4": 5},	
            "d": {"U1": 4, "U2": 3, "U4": 4},	
            "e": {"U2": 3, "U3": 2, "U4": 3}	
        }	
        return user_rate,item_rate

计算物品之间的评分偏差


 def cal_item_avg_diff(self):	
        avgs_dict = {}	
        for item1 in self.item_rate.keys():	
            for item2 in self.item_rate.keys():	
                avg = 0.0	
                user_count = 0	
                if item1 != item2:	
                    for user in self.user_rate.keys():	
                        user_rate = self.user_rate[user]	
                        if item1 in user_rate.keys() and item2 in user_rate.keys():	
                            user_count += 1	
                            avg += user_rate[item1] - user_rate[item2]	
                    avg = avg / user_count	
                avgs_dict.setdefault(item1,{})	
                avgs_dict[item1][item2] = avg	
        return avgs_dict

计算预估评分

    def item_both_rate_user(self, item1, item2):	
        count = 0	
        for user in self.user_rate.keys():	
            if item1 in self.user_rate[user].keys() and item2 in self.user_rate[user].keys():	
                count += 1	
        return count	
    def predict(self, user, item, avgs_dict):	
        total = 0.0 # 分子	
        count = 0   # 分母	
        for item1 in self.user_rate[user].keys():	
            num = self.item_both_rate_user(item, item1)	
            count += num	
            total += num * (self.user_rate[user][item1] - avgs_dict[item][item1])	
        return total/count

主函数调用

if __name__ == "__main__":	
    slope = SlopeOne()	
    avgs_dict = slope.cal_item_avg_diff()	
    result = slope.predict("U2", "a", avgs_dict)	
    print("U2 对 a的预测评分为: %s" % result)

打印结果为:

U2 对 a的预测评分为: 3.111111111111111

和上边我们计算的结果一致。

完整代码在:https://github.com/Thinkgamer/Machine-Learning-With-Python/tree/master/Recommend

应用场景

该算法适用于物品更新不频繁,数量相对较稳定并且物品数目明显小于用户数的场景。比较依赖用户的用户行为日志和物品偏好的相关内容。

其优点:

  • 算法简单,易于实现,执行效率高;

  • 可以发现用户潜在的兴趣爱好;

其缺点:

  • 依赖用户行为,存在冷启动问题和稀疏性问题。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值