487. H&M Personalized Fashion Recommendations | h-and-m-personalized-fashion-recommendations
距离我上次在 Kaggle 上看到关于推荐的竞赛已经很久了。非常感谢 Kaggle 团队和 H&M 主办了如此有趣的比赛。CV(交叉验证)和 LB(排行榜)之间的高相关性、用于深度数据挖掘的海量训练数据、无测试信息泄露、友好的工作人员和参与者,所有这些都成就了这次成功的比赛。
为了方便快速阅读,这里将说明我解决方案的核心思想。
train = transactions.loc[transactions["t_dat"] < "2020-09-16"]
valid = transactions.loc[transactions["t_dat"] >= "2020-09-16"]
如果你有足够的计算能力,最好使用这篇文章中提到的 k-fold 验证,以避免过拟合最后一周的数据。
但根据我在本次比赛中的经验,仅使用最后一周作为验证集,LB 分数和 CV 分数的相关性非常高。
使用 LightGBM 训练 20 周的数据,包含约 300 个特征。
我没时间训练所有 5 个基于 k-fold 分割的模型,截止日期前只完成了其中的 3 个。所以我最终的提交基于 1 个在全量数据上训练的模型和另外 3 个基于 k-fold 分割训练的模型(总共 4 个模型)。
| 模型 | Public 分数 | Private 分数 |
|---|---|---|
| 单模型 | 0.0338 | 0.0341 |
| 集成 | 0.0343 | 0.0346 |
使用 Rapids 的 cudf 和 Forest Inference Library 进行快速特征生成和快速树推理。
| 硬件 | 配置 |
|---|---|
| CPU | 32核 |
| 内存 | 128G |
| GPU | V100 32G |
我们可以发现验证集中 90% 以上的商品也出现在过去 30 天内。
train_condition = (trans["t_dat"] >= "2020-08-16") & (trans["t_dat"] < "2020-09-16")
items_in_valid = trans.loc[trans["t_dat"] >= "2020-09-16", "article_id"].unique()
items_last_month = trans.loc[train_condition, "article_id"].unique()
print(len(set(items_in_valid) & set(items_last_month)) / len(set(items_in_valid)))
# 0.92
验证集中大约 50% 的客户在过去 30 天内有交易记录。
train_condition = (trans["t_dat"] >= "2020-08-16") & (trans["t_dat"] < "2020-09-16")
users_in_valid = trans.loc[trans["t_dat"] >= "2020-09-16", "customer_id"].unique()
users_last_month = trans.loc[train_condition, "customer_id"].unique()
print(len(set(users_in_valid) & set(users_last_month)) / len(set(users_in_valid)))
# 0.47
考虑到这些结果