返回列表

38th Place Solution (3rd Public)

592. Linking Writing Processes to Writing Quality | linking-writing-processes-to-writing-quality

开始: 2023-10-02 结束: 2024-01-09 智能评测 数据算法赛
第38名解决方案(第三名公开)

第38名解决方案(第三名公开)

作者: Mohamed Eltayeb, Reacher, Ali Ibrahim
发布时间: 2024-01-10
获得票数: 19
比赛排名: 第38名(公开榜第3名)

大家好,
感谢Kaggle和主办方举办这场精彩的比赛!同时也感谢我出色的队友 @ihebch@aliibrahimali。没有他们,这将是不可能完成的任务!

解决方案概览

我们使用了与公开笔记本几乎相同的特征(我认为这导致我们在私有榜中排名下滑,可能是因为我们过于依赖那个"银弹"笔记本,但无论如何,那是一个非常棒的笔记本,感谢 @awqatak),将这些特征输入到3个分类器(TabPFN、MLPClassifier、MultinomialNB)中,然后将它们的概率作为特征。接着我们将所有特征输入到由XGBoost和6个线性模型组成的回归集成中,最后使用线性回归找到最佳的集成权重。

验证策略

我们的交叉验证(CV)与排行榜(LB)之间有很好的相关性。许多在CV上的改进都转化到了LB上。我们在CV上的最佳成绩同时也是公开榜和私有榜的最佳成绩。
我们的最佳CV分数约为0.592,公开LB分数为0.570(第三名),私有LB分数为0.566。

我们的CV方法: 基本上就是使用以下代码:
StratifiedKFold(n_splits=5/10/.., shuffle=True, random_state=42)
不使用任何bagging(我们尝试过不同的n_splits,但最终使用5,因为分数"0.5"的类别在数据集中只有5个样本)。
我们将公开LB视为一个额外的折。因此,我们只保留那些同时改进CV和LB的改动。

特征工程

起初,我们从公开笔记本开始使用特征。我们尝试添加更多的聚合/交互特征,但这并没有帮助。我们发现有用的方法有:

  • 原始计数特征: 我们添加了很多这样的特征,最后进行了特征选择,这很有用(+0.001)
  • 隐狄利克雷分配(LDA): 使用预训练的NLP模型在我们的案例中没有太大帮助,那么为什么不尝试一些聚类呢?LDA在这方面提供了帮助,并给我们的CV/LB带来了不错的提升。我们用不同设置的计数向量器输入给它,这非常有帮助(+0.002)
  • 表示特征: 用不同的困惑度在数据上拟合t-SNE帮助获得了不错的提升(+0.001)
  • 分类器概率和期望: 使用3个模型(TabPFN、MLPClassifier和MultinomialNB)的原始概率和期望作为特征也提供了不错的提升(+0.001)。这些模型的输入是原始数据的100个PCA成分。这样做是为了获得输入的多样性,而不是直接输入原始数据。

特征选择

上述工程特征大约有1400个。我们对所有模型多次使用了LOFO(Leave One Feature Out)方法。最终模型只包含约350个特征。这给了我们额外的提升(+0.001)。

建模方法

XGBoost是我们最佳的单模型。添加线性模型有助于增加多样性。
模型架构图
我们没有使用早停,因为这会导致过拟合,特别是对于这个小型数据集。

未成功的方法

  • 在原始日志上训练: 我们在这方面投入了很多时间。我们尝试在日志数据上拟合各种类型的模型,希望之后能获得一些多样性收益,但都没有效果。顺便说一句,仅仅将目标映射到ID上训练这些日志是没有用的(写作开头的样本得分会与结尾的样本相同,这是不正确的)。因此,我们决定使用一个增长的目标(使用了np.linspace(0,score,n_samples_in_id))。它在自身的CV上提供了一些不错的提升,但与聚合数据训练相比仍然太差(~0.718)。当将其输出作为特征添加到xgboost CV时确实带来了一些提升,但并未转化为LB提升,所以我们放弃了。
  • 更多bagging: 这总是让我们的CV更好,但LB更差。所以我们放弃了(我们只使用同时改进CV和LB的方法)。顺便说一句,结果在私有LB上仍然很差。
  • 神经网络: 它们总是过拟合,所以我们放弃了。唯一的例外是MLPClassifier。它给xgboost带来了一些提升(作为特征)。
  • 在全数据上训练: 看起来多样性在这里更重要。
  • 伪标签和后处理: 伪标签完全不起作用。关于后处理,我们想优化这些a,b,c和d参数:
    preds[preds < a] = b
    preds[preds > c] = d
    因此,我们在CV内部应用了内部StratifiedKFold来找到最佳值(对于外部CV,我们选择n_splits=5以确保"0.5"类别的样本不重复。对于内部CV,我们使用n_splits=4出于同样的原因)。但最终这并没有帮助。我认为边缘样本数量少是这里的挑战。

这里是我们的代码(虽然有点乱):
[代码链接已删除]

我们只是差一点就能获得金牌,从而晋升到Master段位,但让我们下次继续努力。
感谢阅读!

同比赛其他方案