返回列表

A few notes on #16 solution

498. Foursquare - Location Matching | foursquare-location-matching

开始: 2022-04-14 结束: 2022-07-07 商品理解 数据算法赛
关于第16名方案的几点说明

关于第16名方案的几点说明

作者:Silogram (Grandmaster) | 发布时间:2022-07-08

首先,感谢 Kaggle 和 Foursquare 提供了一个非常有趣的挑战。不过,数据泄露确实令人沮丧。这本该是一个很容易避免的泄露。我无法想象这是怎么漏掉的。寻找泄露是 Kaggle 比赛的常态,但当说明中明确指出不存在特定泄露时,它就不应该存在。

祝贺获胜者,特别是 @psi 后来居上并获得了获胜方案(如果我们不计算明确使用泄露的情况)。这是一场艰难的比赛,需要很多独创性才能取得好成绩。

我从这次比赛中最大的收获是:

  1. RAPIDS 是一个非常成熟且有用的库。这是我第一次使用 RAPIDS,我对几乎无需更改代码即可在 GPU 上运行如此多的 sklearn 和 pandas 功能印象深刻。加速效果非常显著,尤其是在非 GPU 版本仅使用 1 个 CPU 的情况下。还要感谢 @steubk 展示了如何使用 ForestInference 进行推理 (链接)。
  2. 老派 NLP 技术(如文本规范化、TF-IDF、关键词提取等)在特定情况下仍然适用。在本次比赛中,大部分文本是多种语言的名字,这降低了预训练文本模型的实用性。
  3. ML 工具集的成熟:随着机器学习工具集的成熟,ML 正越来越成为软件工程的一个专业领域。特别是在本次比赛中,正确设置问题以使用最少的资源分块处理数据,与所采用的具体 ML 算法同样重要。

关于本次比赛的一个大问题

为什么大多数顶尖团队来自日本?是数据的某些特点给了日本团队优势吗?

以下是我的方案简要概述(未明确使用泄露)。

训练流程

  1. 预处理训练数据:
    • a) 规范化文本字段(小写、去除标点、规范化常见拼写变体、转换为 ASCII)。
    • b) 选择频繁出现的名称关键词并编码为特征。
    • c) 分离多个类别并将其编码为单个类别。
  2. 划分数据:按 point_of_interest 分组,将训练集随机分为两个相等的部分,生成两个集合——train0 和 train1。
  3. 分别处理这两个训练集:
    • a. 获取文本字段的词频向量。
    • b. 对于每个 id,按经纬度找出 200 个最近的邻居。
    • c. 以 10 个邻居为一组生成特征(例如,第 1-10 个最近的邻居,然后是 11-20、21-30 等)。每个 id 与组内的 10 个邻居配对生成成对特征。总共生成了大约 50 个特征,其中最重要的包括:
      1. 文本字段之间的余弦相似度(特别是规范化后的名称、name_nonkey 和地址)。
      2. 距离排名(例如,第 2 近的邻居 vs 第 150 近的)。
      3. 前一个和后一个距离(例如,如果我们正在处理第 5 近的邻居,那么第 4 和第 6 个邻居的距离是多少)。
      4. 名称之间的 Jaccard 相似度。
      5. 原始经纬度。
      6. 编码后的类别。
      7. 配对中匹配名称词的数量。
      8. 最长名称的字符长度。
      9. 名称中字符的最小和最大序数值(字符集/语言的代理指标)。
      10. 类别匹配的数量。
      11. 编码后的国家。
  4. 训练浅层模型:同样以 10 个邻居为一组进行处理,训练浅层 LGB 模型来预测配对匹配。
  5. 筛选候选集:使用第 4 步的匹配预测来选择最可能的匹配。这里的目标是减少候选范围,并获得更平衡的训练集,同时不丢弃太多正样本。对于每 10 个最近邻居组,我们训练 2 个浅层 LightGBM 模型——一个用于 train0,一个用于 train1。我们使用一个集合的模型来预测另一个集合的匹配,从而获得两个集合的 OOF(袋外)预测。我们保存 40 个模型(20 组邻居,每组 2 个)用于推理。
  6. 设置阈值过滤:利用第 5 步的预测,我们设定阈值来过滤掉几乎没有机会匹配的候选者。我发现将阈值设定在约 30:1(正负样本比)效果很好。它捕获了约 95% 的正样本(在 200 个最近邻居对中的那些),同时消除了约 90% 的负样本。阈值
同比赛其他方案