趋近智
在计算任何性能指标之前,必须先准备好数据。典型的监督机器学习 (machine learning)通常使用类似 scikit-learn 的 train_test_split 函数来随机打乱并划分数据集。然而,对于推荐系统来说,这种随机方法不仅效果不佳,还可能产生极具误导性的结果。
推荐往往是一项具有时效性的任务。我们希望根据用户过去的行为来预测他们未来会喜欢什么。随机拆分违背了这一基本的时序逻辑。
假设一个用户在一周内评价了三部电影:周一评价了电影 A,周三评价了电影 B,周五评价了电影 C。随机拆分可能会将电影 A 和电影 C 的评分放入训练集,而将电影 B 的评分放入测试集。这样,模型就会在预测目标事件发生之前和之后的数据上同时进行训练。这种来自未来的“数据泄露”给模型带来了在实际环境中并不存在的优势,导致性能指标虚高,产生一种错误的信心。
为线下评估创建训练集和测试集最可靠的方法是模拟时间的流动。这种过程通常被称为时序拆分或基于时间的拆分,它确保你始终基于过去的事件来预测未来的事件。
标准做法是执行按用户拆分:对于每个用户,将其最近的交互留作测试集,而将其较早的交互用于训练。这种“留一法”(leave-one-out)将最后一次交互用于测试,是一种常用且有效的方法。
对于每个用户,交互按时间排序。最近的一次交互被放入测试集(红色),而之前的所有交互构成训练集(蓝色)。
让我们看看如何使用 pandas 来实现这一点。我们假设你的数据在一个 DataFrame 中,包含 user_id、item_id 和一个表示交互发生时间的 timestamp 列。
import pandas as pd
# 假设 'ratings_df' 是一个包含 user_id, item_id, rating 和 timestamp 的 DataFrame
# 示例 DataFrame:
data = {'user_id': [1, 1, 1, 2, 2, 3, 3, 3, 3, 4],
'item_id': [101, 102, 103, 101, 104, 102, 103, 105, 106, 107],
'rating': [5, 4, 3, 4, 5, 2, 5, 4, 3, 5],
'timestamp': [978300760, 978300761, 978300762, 978300763, 978300764,
978300765, 978300766, 978300767, 978300768, 978300769]}
ratings_df = pd.DataFrame(data)
# 确保 DataFrame 已正确排序
ratings_df = ratings_df.sort_values(by=['user_id', 'timestamp'])
# 创建空列表来保存数据
train_data = []
test_data = []
# 按用户分组并拆分数据
for user_id, group in ratings_df.groupby('user_id'):
# 用户必须有超过一个评分才能进入测试集
if len(group) > 1:
# 最后一次交互进入测试集
test_data.append(group.iloc[-1:])
# 其他所有交互进入训练集
train_data.append(group.iloc[:-1])
# 将 DataFrame 列表合并回单个 DataFrame
train_df = pd.concat(train_data)
test_df = pd.concat(test_data)
print("训练集大小:", len(train_df))
print("测试集大小:", len(test_df))
在这段代码中,我们首先按用户然后再按时间对所有交互进行排序。groupby('user_id') 操作允许我们独立处理每个用户的时间线。对于交互次数超过一次的用户,我们使用 iloc[-1:] 选取他们的最后一次交互放入测试集,并使用 iloc[:-1] 选取之前的所有交互放入训练集。
这种时序拆分方法很可靠,但还有一些细节需要处理。
只有一次交互的用户: 上述代码正确处理了仅与一个项目发生过交互的用户。由于 len(group) 不会大于 1,在此实现中,他们的单次交互不会被添加到任何一个集合中。这通常是符合预期的,因为你无法对只有一个数据点的用户进行训练后再测试。他们存在于历史数据中,但被排除在评估集之外。
确保测试集的有效性: 你的目标是衡量模型向现有用户推荐项目的效果。这意味着 test_df 中的每个用户和每个项目最好也出现在 train_df 中。如果一个用户的唯一交互就是其最新的一次(按照我们的逻辑这不可能发生),或者如果一个项目第一次出现在测试集中,你的模型可能无法做出预测。这就是在评估中表现出来的冷启动问题。对于协同过滤等算法的标准评估,你可能需要增加一个步骤来过滤测试集,确保其中的用户和项目在训练期间都已出现过。
现在,你的数据已经正确划分为尊重过去的训练集和代表未来的测试集,可以开始训练模型并使用接下来的指标来观察其表现了。
这部分内容有帮助吗?
© 2026 ApX Machine LearningAI伦理与透明度•