推荐算法 - 协同过滤算法

协同过滤算法是常见的一种推荐算法,通过分析用户历史行为和对物品的偏好,从而预测用户可能喜欢或购买的物品。协同过滤算法主要分为两部分:基于用户的协同过滤(User-Based Collaborative Filtering)和基于物品的协同过滤(Item-Based Collaborative Filtering)。

基于用户的协同过滤算法

这种算法假设用户的兴趣可以由相似兴趣的其他用户来推测出来。算法的流程主要包括以下几个步骤:

  1. 计算用户之间的相似度。可以使用余弦相似度、皮尔逊相关系数等指标来计算用户之间的相似度。一般来说,相似度越高的用户,则他们之间的行为和偏好也越相似。

  2. 找到与目标用户最相似的 K 个用户。选择其中某个相似用户 U,则将该用户对其未评分过的物品按照相似度加权求和,作为对目标用户对该物品的推荐得分。

  3. 针对所有未被目标用户评分的物品,计算得分并进行排序,将得分最高的多个物品推荐给目标用户。

基于物品的协同过滤算法

与基于用户的协同过滤算法类似,这种算法则假设物品之间的相似度可以用来推测用户的评分和喜好。算法的流程主要包括以下几个步骤:

  1. 计算物品之间的相似度。可以使用余弦相似度、改进的余弦相似度等指标来计算物品之间的相似度。

  2. 针对目标用户评分过的物品,找出与之相似的物品作为备选推荐物品。

  3. 统计所有备选推荐物品的得分和,并将得分最高的多个物品推荐给目标用户。

代码示例

下面是一个基于 Python 的用户协同过滤算法示例,假设我们有如下的用户评分矩阵:

Item 1 Item 2 Item 3 Item 4 Item 5
User 1 5 3 2
User 2 4 2 4
User 3 5 4 2 1
User 4 2 1 5 4
User 5 3 2 5

首先,我们定义一个函数来计算两个用户之间的相似度,这里使用皮尔逊相关系数:

from math import sqrt

# 计算两个用户的皮尔逊相关系数
def pearson_correlation(user1, user2, ratings):
    # 找到共同评价过的物品
    common_items = {
    
    }
    for item in ratings[user1]:
        if item in ratings[user2]:
            common_items[item] = 1

    # 如果没有共同评价过的物品,则返回 0.0
    if len(common_items) == 0:
        return 0.0

    # 计算每个用户对共同评价物品的评分平均值
    avg1 = sum([ratings[user1][item] for item in common_items]) / float(len(common_items))
    avg2 = sum([ratings[user2][item] for item in common_items]) / float(len(common_items))

    # 计算皮尔逊相关系数
    numerator = sum([(ratings[user1][item]-avg1)*(ratings[user2][item]-avg2) for item in common_items])
    denominator = sqrt(sum([(ratings[user1][item]-avg1)**2 for item in common_items])) * sqrt(sum([(ratings[user2][item]-avg2)**2 for item in common_items]))
    if denominator == 0:
        return 0.0
    else:
        return numerator / denominator

然后,我们定义一个函数来计算某个用户与其他所有用户之间的相似度,并返回一个由相似度和用户组成的元组列表:

# 找到与指定用户最相似的 top_n 个用户
def find_similar_users(user, ratings, top_n):
    scores = [(pearson_correlation(user, other, ratings), other)
              for other in ratings if other != user]
    scores.sort(reverse=True)  # 按照相似度从高到低排序
    return scores[0:top_n]     # 返回 top n 个相似用户

接下来,我们可以定义一个函数来预测某个用户对某个物品的评分。这个函数会基于与该用户相似度最高的 top_n 个用户的评分来进行加权平均:

# 对指定用户未评价的所有物品进行评分预测
def predict_ratings(user, ratings, top_n):
    # 给出一个默认值(这里设为 3.0),表示用户没看过这部电影时的评分
    totals = {
    
    }
    sim_sums = {
    
    }
    for other in ratings:
        if other == user:
            continue
        sim = pearson_correlation(user, other, ratings)
        if sim <= 0:  # 忽略相似度为 0 或负数的用户,避免无用计算
            continue
        for item in ratings[other]:
            if item not in ratings[user] or ratings[user][item] == 0:
                # 只对未评价的物品进行预测
                totals.setdefault(item, 0)
                totals[item] += ratings[other][item] * sim
                sim_sums.setdefault(item, 0)
                sim_sums[item] += sim
    rankings = [(total/sim_sums[item], item) for item, total in totals.items()]
    rankings.sort(reverse=True)  # 按照评分从高到低排序
    return rankings

最后,我们可以调用上述函数来为某个用户推荐电影。比如,如果要为 User 1 推荐一部电影,可以这样写:

# 假设ratings是一个由用户评分组成的字典,格式为{用户:{电影1:评分1,电影2:评分2...}}
# 获取与User 1最相似的前5个用户
similar_users = find_similar_users('User 1', ratings, 5) 
# 预测User 1对电影的评分
predicted_rating = predict_ratings('User 1', ratings, similar_users) 
# 推荐评分最高的电影
recommendations = sorted(predicted_rating.items(), key=lambda x: x[1], reverse=True) 
# 输出推荐的电影
print(recommendations[0][0]) 

猜你喜欢

转载自blog.csdn.net/weixin_44008788/article/details/130956491