FastAI:快速构建电影推荐系统

引言

FastAI 作为一个易于使用且功能强大的深度学习库,为推荐系统的构建提供了便捷的工具。本篇文章将以 fastai_movielens.ipynb 示例为例,介绍如何利用 FastAI 框架,快速构建一个基于协同过滤的电影推荐系统,并对模型性能进行评估。

数据准备

本示例使用经典的 MovieLens 数据集,该数据集包含用户对电影的评分信息。首先,使用 recommenders.datasets.movielens 模块加载数据集,并确保用户 ID 和电影 ID 以字符串类型加载,避免与嵌入 ID 混淆。

ratings_df = movielens.load_pandas_df(
    size=MOVIELENS_DATA_SIZE,
    header=[USER,ITEM,RATING,TIMESTAMP]
)

# 确保 ID 以字符串类型加载
ratings_df[USER] = ratings_df[USER].astype('str')
ratings_df[ITEM] = ratings_df[ITEM].astype('str')

接下来,使用 python_stratified_split 函数将数据集划分为训练集/验证集和测试集,划分比例为 75:25。

train_valid_df, test_df = python_stratified_split(
    ratings_df, 
    ratio=0.75, 
    min_rating=1, 
    filter_by="item", 
    col_user=USER, 
    col_item=ITEM
)

# 从测试集中移除“冷启动”用户
test_df = test_df[test_df.userID.isin(train_valid_df.userID)]

模型训练

FastAI 提供了 collab_learner 函数,用于快速构建协同过滤模型。默认情况下,collab_learner 使用 EmbeddingDotBias 模型,该模型为用户和电影创建嵌入向量,并将它们映射到指定维度的浮点数空间。

# 设置随机种子以确保结果可复现
np.random.seed(101)
torch.manual_seed(101)
torch.cuda.manual_seed_all(101)

# 创建 CollabDataLoaders
data = CollabDataLoaders.from_df(train_valid_df, 
                                     user_name=USER, 
                                     item_name=ITEM, 
                                     rating_name=RATING, 
                                     valid_pct=0)

# 创建 collab_learner
learn = collab_learner(data, n_factors=N_FACTORS, y_range=[0,5.5], wd=1e-1)

collab_learner 中,n_factors 参数表示隐含特征维度,y_range 参数设置评分范围,wd 参数设置权重衰减以进行正则化。

使用 fit_one_cycle 函数训练模型,并设置学习率和迭代次数。

with Timer() as train_time:
    learn.fit_one_cycle(EPOCHS, lr_max=5e-3)

生成推荐结果

为了生成推荐结果,首先需要获取模型已知的所有用户和电影,以及测试集中的用户。

# 获取所有用户和电影
total_users, total_items = learner.dls.classes.values()
total_items = total_items[1:]
total_users = total_users[1:]

# 获取测试集中的用户
test_users = test_df[USER].unique()
test_users = np.intersect1d(test_users, total_users)

然后,构建测试集用户和所有已知电影的笛卡尔积,并移除训练集中出现过的用户-电影组合。

# 构建笛卡尔积
users_items = cartesian_product(np.array(test_users),np.array(total_items))
users_items = pd.DataFrame(users_items, columns=[USER,ITEM])

# 移除训练集中出现过的组合
training_removed = pd.merge(users_items, train_valid_df.astype(str), on=[USER, ITEM], how='left')
training_removed = training_removed[training_removed[RATING].isna()][[USER, ITEM]]

最后,使用 score 函数对模型进行评分,并获取 Top-K 推荐结果。

with Timer() as test_time:
    top_k_scores = score(learner, 
                         test_df=training_removed,
                         user_col=USER, 
                         item_col=ITEM, 
                         prediction_col=PREDICTION)

模型评估

使用 recommenders.evaluation.python_evaluation 模块中的评估指标对模型进行评估。

# 排序指标评估
eval_map = map(test_df, top_k_scores, col_user=USER, col_item=ITEM, 
               col_rating=RATING, col_prediction=PREDICTION, 
               relevancy_method="top_k", k=TOP_K)

eval_ndcg = ndcg_at_k(test_df, top_k_scores, col_user=USER, col_item=ITEM, 
                      col_rating=RATING, col_prediction=PREDICTION, 
                      relevancy_method="top_k", k=TOP_K)

# ... 其他排序指标评估 ...

# 评分预测指标评估
eval_rmse = rmse(test_df, scores, col_user=USER, col_item=ITEM, col_rating=RATING, col_prediction=PREDICTION)
eval_mae = mae(test_df, scores, col_user=USER, col_item=ITEM, col_rating=RATING, col_prediction=PREDICTION)

# ... 其他评分预测指标评估 ...

# 打印评估指标
print(f"Model:\t\t{learn.__class__.__name__}\n"
      f"Top K:\t\t{TOP_K}\n"
      f"MAP:\t\t{eval_map:.6f}\n"
      f"NDCG:\t\t{eval_ndcg:.6f}\n"
      # ... 打印其他排序指标 ...
      f"RMSE:\t\t\t{eval_rmse:.6f}\n"
      f"MAE:\t\t\t{eval_mae:.6f}\n"
      # ... 打印其他评分预测指标 ...
     )

总结

本篇文章以 fastai_movielens.ipynb 为例,介绍了如何使用 FastAI 快速构建一个基于协同过滤的电影推荐系统。FastAI 提供了简洁的接口和高效的训练方法,使得构建推荐系统变得更加容易。

0 0 投票数
Article Rating
订阅评论
提醒
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x