侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1824 篇文章
  • 累计收到 0 条评论

实现基于用户的协同过滤推荐算法

2025-12-12 / 0 评论 / 2 阅读

题目

实现基于用户的协同过滤推荐算法

信息

  • 类型:问答
  • 难度:⭐

考点

协同过滤原理,相似度计算,最近邻搜索

快速回答

基于用户的协同过滤推荐算法主要包含三个核心步骤:

  1. 计算用户相似度:使用余弦相似度衡量用户间的兴趣相似程度
  2. 选择最近邻:找出与目标用户最相似的K个用户
  3. 生成推荐:根据相似用户的喜好预测目标用户可能喜欢的物品

公式表示:用户相似度 = cos(θ) = (A·B) / (||A|| ||B||)

解析

原理说明

基于用户的协同过滤(User-Based Collaborative Filtering)通过分析用户行为数据,发现相似用户群体,并基于"相似用户喜欢的内容你也可能喜欢"的原理进行推荐。核心流程:

  1. 构建用户-物品交互矩阵(如评分、点击等)
  2. 计算用户间的相似度(常用余弦相似度)
  3. 为每个用户选择Top-K相似用户(最近邻)
  4. 根据相似用户的偏好预测目标用户对未交互物品的兴趣

代码示例(Python)

import numpy as np

# 用户-物品评分矩阵(5个用户,4部电影)
ratings = np.array([
    [5, 3, 0, 1],
    [4, 0, 0, 1],
    [1, 1, 0, 5],
    [1, 0, 0, 4],
    [0, 1, 5, 4]
])

def cosine_similarity(user1, user2):
    """计算余弦相似度"""
    mask = (user1 > 0) & (user2 > 0)  # 仅计算共同评分的维度
    if np.sum(mask) == 0: return 0

    dot_product = np.dot(user1[mask], user2[mask])
    norm1 = np.linalg.norm(user1[mask])
    norm2 = np.linalg.norm(user2[mask])
    return dot_product / (norm1 * norm2)

# 计算用户0与其他用户的相似度
user0 = ratings[0]
similarities = [cosine_similarity(user0, user) for user in ratings]

# 获取最近邻(排除自己)
k_neighbors = np.argsort(similarities)[-3:-1]  # 取Top2

# 预测用户0对物品2的评分(加权平均)
numerator = denominator = 0
for neighbor in k_neighbors:
    if ratings[neighbor, 2] > 0:  # 邻居对物品2有评分
        numerator += similarities[neighbor] * ratings[neighbor, 2]
        denominator += abs(similarities[neighbor])

pred_rating = numerator / denominator if denominator != 0 else 0
print(f"预测评分: {pred_rating:.2f}")

最佳实践

  • 数据预处理:处理缺失值(如用全局平均填充),归一化评分消除用户评分偏差
  • 相似度计算优化:仅计算共同评分项,使用Jaccard相似度解决数据稀疏问题
  • 邻居选择:动态K值(相似度大于阈值的用户)优于固定K值
  • 冷启动缓解:新用户可结合基于内容的推荐

常见错误

  • 未处理数据稀疏:当共同评分项过少时仍计算相似度导致噪声
  • 忽略评分偏差:未考虑用户评分尺度差异(严厉型vs宽容型)
  • 邻居权重滥用:使用负相似度用户进行预测
  • 效率问题:全量计算用户相似度(O(N²)复杂度),应使用局部敏感哈希优化

扩展知识

  • 相似度替代方案:皮尔逊相关系数(解决评分偏差)、调整余弦相似度
  • 变体算法:基于物品的协同过滤(Item-CF)更适合用户数远大于物品数的场景
  • 实时更新:增量更新相似度矩阵避免全量重算
  • 混合推荐:结合矩阵分解(MF)处理高稀疏数据