引言
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 提供了简洁的接口和高效的训练方法,使得构建推荐系统变得更加容易。