返回列表

1st Place Solution-2 Targets and Ensemble

642. CIBMTR - Equity in post-HCT Survival Predictions | equity-post-HCT-survival-predictions

开始: 2024-12-04 结束: 2025-03-05 临床决策支持 数据算法赛
第一名解决方案 - 双目标与集成

第一名解决方案 - 双目标与集成 (1st Place Solution-2 Targets and Ensemble)

作者: minerppdy
发布时间: 2025-03-06
竞赛排名: 1

首先,祝贺最终在这场竞赛中“幸存”的队伍,并感谢在论坛中分享经验和提供帮助的参与者。

我也独立训练了分类器和回归器模型,然后将它们与一个魔法函数结合起来,就像第 2 名和第 4 名的解决方案一样。主要思想是,当患者具有高的 efs == 0 概率时,我们应该给他们一个高分。否则,我们应该给他们一个相对较低的分数,并更多地关注 efs_time 的排名。因此,回归器只需要关注 efs == 1 的排名任务。

这里是简化的 代码

1. 特征工程 (Feature Engineering)

  1. 原始特征
  2. 对所有分类特征进行独热编码(但仍保留原始分类特征)
  3. 将连续特征复制为分类特征

2. 交叉验证策略 (CV Strategy)

  1. 不同的分割策略会导致 CV 非常不稳定。为了使结果具有可比性,我对所有分类器和回归器模型训练使用了相同种子的 10 折分割。
y_combine = data['efs'].astype('str')+'|'+data['X']['race_group'].astype('str')
skf = StratifiedKFold(n_splits=10, shuffle=True, random_state=888)
skf.split(X,y_combine)
  1. 不使用早停(early stopping)以减少过拟合风险,尤其是当我使用大量折数时。

3. 分类器 (Classifier)

目标:P(efs=0)

使用的模型

  1. XGBoost, LightGBM, CatBoost
  2. NN, TabM
  3. GNN
  4. NN/TabNet/GNN 带有 pairwise-rank-loss

技巧 (Tricks)

  1. Gnn 方法。我使用 KNN 找到最近的 25 个节点并创建边(使用欧几里得距离),然后使用 graphsage 来拟合目标。
  2. 当使用 rank loss 时,预测会在不同的折之间发生偏移,因为 rank loss 对偏移不敏感,这可能导致在整个集合上计算指标时 CV 较低。所以你需要修复这些偏移,以保持在不同折中训练的模型具有相同的均值/中值预测值。
  3. 即使我使用了 logloss,GNN 也有这个问题,我仍然不知道为什么。

AUC 指标

模型 AUC
lightgbm0.7603
catboost0.7617
xgboost0.7606
nn0.75902
tabm0.7596
gnn0.7591
ranknn0.7598
ranktabm0.7597
rankgnn0.7586

有趣的发现

  1. LGB 和 XGB 的最佳 max depth 是 2(对于 CatBoost 是 6,我仍然不知道为什么)。这在我的经验中几乎是闻所未闻的。这意味着几乎没有有价值的特征交互信息,任务很容易拟合。也许这就是为什么 NN 类模型在这个表格数据上也表现良好的原因。

4. 回归器 (Regressor)

目标

efs 分组并归一化排名

efs_time_norm[efs == 1] = efs_time[efs == 1].rank() / sum(efs == 1)  
efs_time_norm[efs == 0] = efs_time[efs == 0].rank() / sum(efs == 0)

使用的模型

XGBoost, LightGBM, CatBoost (NN 类模型对我来说效果不好,如果有人成功使用了 NN 类模型,请告诉我。)

技巧 (Tricks)

  1. 训练时将 efs 作为特征加入,并关注 efs==1 样本上的性能。在 LB 数据上进行推理时设置 efs=1
  2. efs==1efs==0 应用样本权重,比例为 0.6:0.4
  3. 使用这个技巧的原因。最初,我只在 efs==1 的样本上训练回归器。当使用这个模型对 efs==0 的样本进行推理时,它仍然显示出预测和 ground truth 之间明显的相关性。这很奇怪,因为由于各种可能导致数据删失的原因,efs==0 的 efs_time 是没有意义的。我猜这是因为 SurvalGAN 算法。顺便说一句,事实证明 efs==0efs==1 的样本之间存在相似的模式。因此,通过添加 efs==0 的样本,回归器在 efs==1 上的性能显著提高!

efs==1 上的原始一致性指数 (Concordance Index)

模型 C-index
xgboost0.770229
lightgbm0.767615
catboost0.769340

5. 合并函数 (Merge Function)

def model_merge(Y_HAT_REG,Y_HAT_CLS,a=2.96,b=1.77,c=0.52):
    '''
    Y_HAT_REG 和 Y_HAT_CLS 需要缩放到 0~1
    a,b,c 需要用 optuna 调整
    '''
    y_fun = (Y_HAT_REG>0)*c*(np.abs(Y_HAT_REG))**(b)
    x_fun =(Y_HAT_CLS>0)*(np.abs(Y_HAT_CLS))**(a)
    res = (1-y_fun)*x_fun+y_fun
    res = pd.Series(res).rank()/len(res)
    return res

这是合并函数的样子(没有排名转换),其中 x 是 efs==0 的概率,y 是预测的 efs_time(缩放到 0~1)

Merge Function Visualization

6. 集成方法 (Ensembling Method)

  1. 创建分类器和回归器之间的组合,然后通过 5 折交叉验证找到合并函数的最佳 (a, b, c),然后获得合并后的预测。

    这里是组合的分层一致性指数。忽略合并函数中的排名转换,确信没有泄漏

    分类器 (cls) 回归器 (reg) CV 分层 C-index
    xgboostxgboost0.6938821198444668
    xgboostcatboost0.693390761259049
    xgboostlightgbm0.6920553689042972
    catboostxgboost0.6946771227057665
    catboostcatboost0.6942415329389815
    catboostlightgbm0.6928675187239672
    lightgbmxgboost0.6935306031275579
    lightgbmcatboost0.693123814234674
    lightgbmlightgbm0.6917244174625249
    tabmxgboost0.6943607674628444
    tabmcatboost0.6936616324722884
    tabmlightgbm0.6922428015362854
    nnxgboost0.6939542378441973
    nncatboost0.6932931191267933
    nnlightgbm0.6920700218390199
    gnnxgboost0.6940062476514388
    gnncatboost0.6932012736212297
    gnnlightgbm0.6921340326054011
    ranktabmxgboost0.693141398733159
    ranktabmcatboost0.6927626179572159
    ranktabmlightgbm0.6912730733179469
    ranknnxgboost0.6944776101013886
    ranknncatboost0.6936542865352446
    ranknnlightgbm0.6924528052605144
    rankgnnxgboost0.6934854451860402
    rankgnncatboost0.692783734834767
    rankgnnlightgbm0.6916329456191074
  2. 使用 Optuna 和 5 折交叉验证,通过加权平均对合并后的预测进行集成。
  3. 由于有 9 个分类器 × 3 个回归器 = 27 种组合,存在过拟合的风险。因此,我将 Optuna 搜索权重的范围设置为 0.1 到 1,而不是 0 到 1。我认为这是一种正则化形式。
  4. 最终的 CV 分层 C-index 约为 0.6965
  5. 向某些种族组添加噪声显著提高了交叉验证性能,但在公有或私有 LB 上都没有效果。
同比赛其他方案