79·实战项目高级

实战:推荐系统构建

projectrecommender

第 79 课 - 实战:推荐系统构建

1. 学习目标

完成本课程的学习后,你将能够:

  • 理解推荐系统的基本原理,特别是协同过滤(Collaborative Filtering)的核心思想。
  • 掌握使用Python库(Surprise)构建一个基础推荐系统的完整流程。
  • 动手实践从数据准备、模型训练、评估到最终预测的完整项目。
  • 了解评估推荐系统模型性能的常用指标(如RMSE)。

2. 核心概念

想象一下,当你逛书店时,店员会根据你过去购买的书籍类型,向你推荐你可能喜欢的新书。推荐系统(Recommender System) 就是数字世界里的“智能店员”,它通过分析用户的历史行为(如评分、购买、点击),来预测用户对未接触过物品的喜好程度。

构建推荐系统主要有两大类方法:

  1. 基于内容的推荐:根据物品本身的属性(如电影的类型、演员、导演)进行推荐。“因为你喜欢《盗梦空间》这部科幻悬疑片,所以我推荐《黑客帝国》”。
  2. 协同过滤:这是目前最经典和广泛使用的方法之一。它的核心思想是:“物以类聚,人以群分”。
    • 用户-用户协同过滤:找到与你兴趣相似的用户,把他们喜欢而你还没看过的物品推荐给你。
    • 物品-物品协同过滤:找到与你喜欢的物品相似的其他物品进行推荐。例如,“喜欢《哈利·波特》的用户,也大多喜欢《纳尼亚传奇》”。

本节课,我们将重点实战基于模型的协同过滤,具体使用奇异值分解技术。你可以将其理解为一种强大的“压缩”技术,它能从庞大的“用户-物品”评分矩阵中,挖掘出潜在的、代表用户兴趣和物品特性的“隐藏因子”(比如“科幻程度”、“爱情成分”等),然后利用这些因子进行精准预测。

模型评估:预测的准确度如何衡量?最常用的指标是均方根误差。它计算的是模型预测分数与真实分数之间差距的平均大小。RMSE值越小,说明模型的预测越接近用户的真实想法。

3. 代码示例

我们将使用Surprise库,这是一个专门用于构建和评估推荐系统的Python库,用起来非常方便。

# 导入必要的库
import pandas as pd
from surprise import Dataset, Reader, SVD
from surprise.model_selection import train_test_split
from surprise import accuracy

# 1. 数据准备
# 我们使用Surprise内置的MovieLens 100k数据集,它包含用户对电影的评分。
# 你也可以加载自己的数据,格式要求是‘user, item, rating’的CSV。
data = Dataset.load_builtin('ml-100k')

# 为了展示,我们手动创建一个小的示例数据集
ratings_dict = {
    'item_id': [1, 2, 3, 1, 2, 3, 1, 2, 3, 4],
    'user_id': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'A'],
    'rating': [5, 4, 1, 4, 5, 2, 2, 3, 5, 4]
}
df = pd.DataFrame(ratings_dict)
print("示例数据集预览:")
print(df)

# 从Pandas DataFrame加载数据到Surprise
reader = Reader(rating_scale=(1, 5))
data = Dataset.load_from_df(df[['user_id', 'item_id', 'rating']], reader)

# 2. 划分训练集和测试集
# 随机将数据集按80%训练,20%测试进行划分
trainset, testset = train_test_split(data, test_size=0.2, random_state=42)

# 3. 选择并训练模型
# 我们使用SVD(奇异值分解)算法,它是协同过滤的经典方法
algo = SVD()

# 在训练集上训练模型
print("\n开始训练模型...")
algo.fit(trainset)
print("模型训练完成!")

# 4. 在测试集上进行预测和评估
print("\n在测试集上进行预测...")
predictions = algo.test(testset)

# 计算RMSE(均方根误差)来评估模型
print("\n模型评估结果 (RMSE):")
accuracy.rmse(predictions)

# 5. 进行个性化推荐预测
# 预测用户 ‘A’ 对物品 ‘3’ 的评分
user_id = 'A'
item_id = 3
prediction = algo.predict(user_id, item_id)
print(f"\n预测用户 '{user_id}' 对物品 '{item_id}' 的评分: {prediction.est:.2f}")

# 预测用户 ‘B’ 对物品 ‘4’ (一个新物品) 的评分
user_id = 'B'
item_id = 4
prediction = algo.predict(user_id, item_id)
print(f"预测用户 '{user_id}' 对新物品 '{item_id}' 的评分: {prediction.est:.2f}")

# 6. 生成Top-N推荐列表(示例逻辑)
# 实际应用中,我们会预测用户对所有未评分物品的分数,并按分数排序
def get_top_n_recommendations(algo, user_id, n=3):
    """为给定用户生成前N个未评分物品的推荐"""
    # 获取所有物品ID
    all_item_ids = df['item_id'].unique()
    # 获取该用户已评分的物品ID
    rated_item_ids = df[df['user_id'] == user_id]['item_id'].values
    # 找出该用户未评分的物品ID
    unrated_item_ids = [item for item in all_item_ids if item not in rated_item_ids]

    # 预测用户对这些未评分物品的分数
    predictions = [algo.predict(user_id, item_id) for item_id in unrated_item_ids]
    # 按预测分数从高到低排序
    predictions.sort(key=lambda x: x.est, reverse=True)
    # 返回前N个
    return [(pred.iid, pred.est) for pred in predictions[:n]]

# 为用户 ‘A’ 生成Top-2推荐
user_id = 'A'
top_n = get_top_n_recommendations(algo, user_id, n=2)
print(f"\n为用户 '{user_id}' 生成的Top-2推荐(物品ID, 预测评分):")
for item_id, score in top_n:
    print(f"  物品 {item_id}: {score:.2f}")

代码输出解释: 你会看到模型训练完成后的RMSE值,这个值大约在0.9-1.1之间(对于这个小数据集),表示平均预测误差不到1分(满分5分)。接着会看到具体的预测示例和最终为用户A生成的推荐列表。

4. 实践练习

练习 1:算法比较 (基础)

修改代码,尝试使用Surprise库中的其他算法,如KNNBasic(基于邻域的协同过滤)或BaselineOnly。比较它们在同一个测试集上的RMSE值。哪个算法在这个小数据集上表现更好?

预期输出:打印出不同算法的RMSE值,并附上简短比较结论。

练习 2:超参数调优 (进阶)

SVD算法有一个重要的超参数n_factors(隐藏因子的个数)。尝试将其设置为不同的值(如10, 50, 100),观察RMSE如何变化,并思考其中的原因。

预期输出:绘制或列出n_factors与对应RMSE的表格,并进行分析。

练习 3:真实数据集应用 (挑战)

  1. 从网上下载一个真实的推荐系统数据集(如Kaggle上的MovieLens数据集)。
  2. 将其加载为pandas DataFrame。
  3. 使用本节课学到的SVD模型构建流程,为某个特定用户(例如,评分最多的用户)生成Top-5电影推荐。
  4. 尝试将电影的titleitem_id关联,使推荐结果可读(例如,推荐《星球大战》而不是“189号物品”)。

预期输出:为指定用户打印出包含电影名称的推荐列表。

5. 常见错误

  1. 忽略数据预处理:真实数据常包含缺失值、异常评分(如全5分或全1分)。直接使用会导致模型学习到错误模式。务必进行数据清洗。
  2. 过度追求模型复杂度:对于小数据集,复杂的模型(如深度学习)容易过拟合,效果可能不如简单的SVD或KNN。应从简单模型开始。
  3. 评估指标选择单一:RMSE衡量评分预测准确性,但对于Top-N推荐任务,更应关注召回率精确率等排序指标。实战中常需要两者结合评估。
  4. 冷启动问题:本节课的协同过滤算法无法为“新用户”(无历史记录)或“新物品”(无被评分记录)进行推荐。这是协同过滤的固有局限,通常需要结合基于内容的推荐或人工规则来解决。

6. 小结

本节课,我们完成了一个基础但完整的推荐系统实战项目:

  • 理解了推荐系统(特别是协同过滤)是解决信息过载、实现个性化服务的关键技术。
  • 学习了使用Surprise库快速搭建推荐系统的标准流程:数据加载 -> 数据集划分 -> 模型选择与训练 -> 预测与评估 -> 生成推荐。
  • 动手实践了使用SVD算法,通过挖掘用户和物品的潜在特征来进行评分预测,并学会了计算RMSE来评估模型。
  • 探讨了模型优化的方向(超参数调优)以及现实应用中面临的挑战(冷启动问题)。

推荐系统是数据科学中应用最广泛、商业价值最高的领域之一。掌握今天的内容,你已经拿到了构建个性化推荐引擎的钥匙。在接下来的课程中,我们将学习处理另一种强大的数据类型——时间序列。

练习编辑器

rust
Loading...

继续学习

完成本课后,建议继续学习下一课「实战:时间序列预测」 以巩固所学知识。