532. OTTO – Multi-Objective Recommender System | otto-recommender-system
首先感谢大家在这个问题上分享了这么多。我从你们所有人身上学到了很多。
特别感谢(按字母顺序排列):
我在 Private LB 上表现最好的方案几乎是单模型(得分几乎与集成模型相同),所以我将描述这个单模型(Public LB: 0.604,Private LB: 0.603)。
流程架构:候选生成 -> 特征创建 (Numba, Polars) -> 排序模型 -> 推理
我认为拥有一个强大的候选生成方法对我帮助很大,所以我是这样做的。
每个会话的候选数量: 在比赛的大部分时间里,我生成了 80 个候选,然后在最后一周将其增加到 120 个候选,以获得一些分数提升(约 0.001)。对于 80 个候选,我有相当不错的最大召回率 0.648(在验证集上)。我也曾在一个实验中尝试了 200 个候选,但这并没有帮助提高分数。
另外,如果我从候选生成模型中取前 20 个候选,我在 LB 上的得分将是 0.585。
对于候选生成,我使用了类似于共访矩阵的方法,我将一个会话中任意两个 aid 的用户行为分为不同的类别,例如:
为了保持较低的内存使用量,我只选择了前 (k * 100) 个候选。这里的 K 是我想要生成的候选数量。
此外,我通过第一个项目的频率对权重进行了归一化。所以这基本上就像:在购买牛奶的 100 次中,有多少次同时也购买了鸡蛋。
矩阵中的权重通过我们要讨论的两个 aid 之间访问的项目数量进行了归一化。
假设我们有 5 个 aid:aid1, aid2, aid3, aid4, aid5。
那么 (aid1, aid5) 的权重将是 (5-1)/(aid1 的频率)。
另外 (aid5, aid1) 的权重将是 ((aid1, aid5) 的权重)/2(只是为了表达 aid5 的购买是由 aid1 的购买驱动的,而不是反过来)。
在推理时,为了决定应该取哪些前 k 个候选,我使用了 Optuna,将每个共访矩阵的权重、项目的时效性权重、项目的整体归一化频率等作为参数进行优化。
我使用了 LightGBM,采用 5% 的负采样和大约 400 个特征,数据为最后两周的数据。添加倒数第二周的数据使分数提高了约 0.0005。
一些对我有效的方法或技巧: