{
  "id": 566584,
  "title": "12th place solution",
  "content": "<p>Given the similarities between this competition and the Tabular Playground Series competitions, and the fact that both my teammate and I are experienced TPS participants with a history of success, we decided to apply our knowledge of synthetic tabular datasets to this competition.  </p>\n<p><strong>TL;DR: Large ensembles with minimal feature engineering, plus a few additional tricks.</strong>  </p>\n<p>Over the course of three months, we trained a large repository of models and experimented with various ensembling techniques. By the end of the competition, we had accumulated a total of 98 models trained on a variety of different target transformations. Given the large number of base models, we also did feature selection during ensembling to reduce the number of models and improve our CV score.  </p>\n<h2>Final Solution</h2>\n<p>Our final approach consisted of a <strong>multi-layered ensemble</strong>:  </p>\n<ol>\n<li><strong>First Layer:</strong> A diverse set of base models, including gradient boosted tree models, neural networks, and AutoML.</li>\n<li><strong>Second Layer:</strong> Three different ensemble methods—Ridge regression, hill climbing, and AutoGluon. We conducted feature selection separately for each of these ensemble methods.  </li>\n<li><strong>Third Layer:</strong> A weighted ensemble of the OOF predictions from the three second-layer models.  </li>\n<li><strong>Final Step:</strong> We used an LGBM classifier and applied the masking trick to obtain our final predictions.  </li>\n</ol>\n<p>Below, we provide the CV scores for all our base models and ensemble models.  <br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F16179447%2Fa0bbc02c1271070caaa39331958e9406%2F__results___122_0.png?generation=1741239162520085&amp;alt=media\" alt=\"\"></p>\n<h2>Acknowledgments</h2>\n<p>We would like to thank the organizers for an interesting competition, as well as everyone who shared their insights and ideas, especially <a href=\"https://www.kaggle.com/ambrosm\" target=\"_blank\">@ambrosm</a>, <a href=\"https://www.kaggle.com/adaubas\" target=\"_blank\">@adaubas</a>, <a href=\"https://www.kaggle.com/andreasbis\" target=\"_blank\">@andreasbis</a>, and <a href=\"https://www.kaggle.com/mtinti\" target=\"_blank\">@mtinti</a>.</p>\n<p>On a personal note, I want to congratulate, and give a big thank you to my teammate, <a href=\"https://www.kaggle.com/rzatemizel\" target=\"_blank\">@rzatemizel</a>. This was our first competition medal, and I couldn't have asked for a better partner!  </p>",
  "comments": [
    {
      "id": 3142156,
      "author_name": "Mart Preusse",
      "author_url": "",
      "post_date": "2025-03-06T06:24:03.947000",
      "content": "<p>Wow, great that you made gold! Nice to see you two doing so well. And this is an amazing amount of models! How did you ensemble them without running into out of memory errors? I could add autogluon and NNs, but as soon as I added my pickle saves of the trained models I got an out of memory error (only when submitting). So I ended up training my models in the submission notebook.</p>",
      "votes": 3,
      "replies": [
        {
          "id": 3142164,
          "author_name": "Mahdi Ravaghi",
          "author_url": "",
          "post_date": "2025-03-06T06:38:16.670000",
          "content": "<p>Thank you! </p>\n<p>We trained our models in separate notebooks and only ran inference on them during submission. The pickles and OOF files we collected were uploaded to a dataset. We didn't run into any memory or space issues. AutoGluon could have encountered disk space problems, but during inference, we moved the pretrained models to the root directory instead of the working directory, which gave us more space to store the models.</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 3142837,
          "author_name": "Robert Hatch",
          "author_url": "",
          "post_date": "2025-03-06T17:46:11.643000",
          "content": "<p>Ironically my final day submission error might have been the equal and opposite: I was training a crazy number of Autogluon models, and maybe ran out of disk space or(?) on the hidden test set run. So I had to switch to inference but thankfully the \"failed\" run I couldn't debug had all the models right there since my local version passed. </p>",
          "votes": 1,
          "replies": [
            {
              "id": 3142868,
              "author_name": "Mahdi Ravaghi",
              "author_url": "",
              "post_date": "2025-03-06T18:10:20.383000",
              "content": "<p>Glad you made it to 5th place despite the last-minute submission errors. </p>\n<p>How many do you consider a crazy amount? 😄</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3142979,
              "author_name": "Robert Hatch",
              "author_url": "",
              "post_date": "2025-03-06T19:54:09.077000",
              "content": "<p>Well, my code is homebrew with Autogluon (as one option) underneath, so I was building a separate AG model each fold. And separate for 4 different targets. Plus one more with target encoding. So 25 AG models with separate directories probably keeping all info like 25 copies of validation data or something. I recall when trying to debug seeing about 1.5 GB on the working submission output pane with the small test set. Don't know internals enough to know if they would increase size at all if predicting on more test data? Shouldn't unless they save some type of cached predictions for some reason 🤷🏻‍♂️.</p>\n<p>Not aware that there's a limit anywhere near that for kaggle, but I was saving test predictions as I went so that would also increase size on the hidden run at least a little more. </p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3142986,
              "author_name": "Robert Hatch",
              "author_url": "",
              "post_date": "2025-03-06T20:00:21",
              "content": "<p>If I hadn't seen errors, I likely would've added another 2 Target Encoding variations. For those I didn't want to write Target Encoding inference, so I would have had to run at least the TE auto gluon training during submission notebook. </p>\n<p>The final submit did that but only for a single model config with a single AG run. I never tried to ensemble in the additional TE runs and see which if any got pulled into final sub. </p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3143373,
              "author_name": "Mahdi Ravaghi",
              "author_url": "",
              "post_date": "2025-03-07T07:00:32.147000",
              "content": "<p>I guess you could have gotten away with only five models instead of 25 and saved yourself some headache. I used to create one model for each fold as well. The problem is that they take a lot of time to train, and you may end up with a different set of models in each fold.  If I had done this, then I would have ended up with 70 AutoGluon models!</p>\n<p>What I did was create one model for each target transformation, then predefine the folds for AutoGluon like this:  </p>\n<pre><code>kf = KFold(n_splits=CFG.n_folds, random_state=CFG.seed, shuffle=)\nsplit = kf.split(train, train[[, ]])\n\n i, (train_index, val_index)  (split):\n    train.loc[val_index, ] = i\n\n    train.loc[train_index, CFG.target], train.loc[val_index, CFG.target] = TargetTransformer(\n        train.loc[train_index, [, ]], \n        train.loc[val_index, [, ]]\n    ).fit_transform(CFG.target)\n</code></pre>\n<p>Then, I told AutoGluon to use these predefined folds like this:</p>\n<pre><code>predictor = TabularPredictor(\n    ...\n    groups=\n)\n</code></pre>",
              "votes": 1,
              "replies": []
            },
            {
              "id": 3143553,
              "author_name": "Mahdi Ravaghi",
              "author_url": "",
              "post_date": "2025-03-07T10:29:35.080000",
              "content": "<p><a href=\"https://www.kaggle.com/competitions/equity-post-HCT-survival-predictions/discussion/566584#3143511\" target=\"_blank\">It was pointed out to me</a> that there is a bug in my code. I realize now why you had to create a new model for each fold.</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3145473,
              "author_name": "Robert Hatch",
              "author_url": "",
              "post_date": "2025-03-09T21:03:49.053000",
              "content": "<p>In any case, one reason I have done this way is I might well run 100 CPU based models on a large dataset on a single fold in Kaggle, which if train data size is large enough, could take 4+ hours. So that way I start all 5 folds simultaneously on different notebooks without timing out, make sure that it doesn't delete my models (do NOT optimize for deployment) and then after I run my own personal ensembling (patterned after AG's), I manually force the future runs to only include the contributing models.</p>\n<p>But that same use case means that each AG model with optimize for deployment False is probably saving a lot of things I don't care about.</p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3142149,
      "author_name": "Optimistix",
      "author_url": "",
      "post_date": "2025-03-06T06:10:13.873000",
      "content": "<p>A big congrats to you and <a href=\"https://www.kaggle.com/rzatemizel\" target=\"_blank\">@rzatemizel</a> on your gold medal! 98 models sounds a lot like what I might have done over 3 months as well. Great to see TPS veterans at the top 😀</p>",
      "votes": 4,
      "replies": [
        {
          "id": 3142161,
          "author_name": "Mahdi Ravaghi",
          "author_url": "",
          "post_date": "2025-03-06T06:31:53.997000",
          "content": "<p>Thank you, and congratulations to you as well for your first silver medal.</p>",
          "votes": 3,
          "replies": []
        }
      ]
    },
    {
      "id": 3143842,
      "author_name": "esoteric.data1",
      "author_url": "",
      "post_date": "2025-03-07T16:50:40.223000",
      "content": "<p>Wow great analysis !! 😀</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 3143453,
      "author_name": "SCRIPTCHEF",
      "author_url": "",
      "post_date": "2025-03-07T08:53:03.940000",
      "content": "<p>Hi Mahdi, congrats! I have two questions: there was some speculation over whether the target creation method caused overfitting - did you create the combined targets using the full train set or just on the fold? Second, what is the masking trick?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 3143472,
          "author_name": "Mahdi Ravaghi",
          "author_url": "",
          "post_date": "2025-03-07T09:09:21.350000",
          "content": "<p>We started by running target transformation on the full training set and noticed little difference when performing the transformation inside the CV loop. However, just to be on the safe side, we decided to go with the latter approach.</p>\n<p>The masking trick involves creating a binary classifier to predict efs. Then, we add a constant (which we tune) to the data points predicted as efs=1. This gave a slight boost to the CV score. That said, we also have gold-medal solutions that do not use this trick.</p>",
          "votes": 0,
          "replies": [
            {
              "id": 3143486,
              "author_name": "SCRIPTCHEF",
              "author_url": "",
              "post_date": "2025-03-07T09:16:43.010000",
              "content": "<p>Thanks, that makes sense. Is there an easy way to create the targets for autogluon? Afaik it expects a column called 'group' but if you need to recalculate targets for each train fold I can't see an easy way to do it.</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3143494,
              "author_name": "Mahdi Ravaghi",
              "author_url": "",
              "post_date": "2025-03-07T09:24:20.973000",
              "content": "<p>It's very easy! <a href=\"https://www.kaggle.com/competitions/equity-post-HCT-survival-predictions/discussion/566584#3143373\" target=\"_blank\">Here</a> is how we did it.</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3143511,
              "author_name": "SCRIPTCHEF",
              "author_url": "",
              "post_date": "2025-03-07T09:44:02.570000",
              "content": "<p>I might have misinterpreted the code in the notebook, but wouldn't this approach overwrite the target in each iteration of the for loop, so your final target would just be the transformation for the last fold?</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3143549,
              "author_name": "",
              "author_url": "",
              "post_date": "2025-03-07T10:21:08.017000",
              "content": "",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3143550,
              "author_name": "Mahdi Ravaghi",
              "author_url": "",
              "post_date": "2025-03-07T10:24:25.550000",
              "content": "<p>You are right. I did not notice this before now.</p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3142842,
      "author_name": "Robert Hatch",
      "author_url": "",
      "post_date": "2025-03-06T17:49:18.510000",
      "content": "<p>Tons of models for the win! Considering at least top 7 all used a strangely powerful trick of separate model types predicting efs vs efs_time rank, your 12th without that is all the more impressive!</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 3142833,
      "author_name": "aldparis",
      "author_url": "",
      "post_date": "2025-03-06T17:40:34.563000",
      "content": "<p>Congratulations to you both for your gold medal !</p>",
      "votes": 2,
      "replies": [
        {
          "id": 3143479,
          "author_name": "Mahdi Ravaghi",
          "author_url": "",
          "post_date": "2025-03-07T09:11:29.550000",
          "content": "<p>Thank you!</p>\n<p>We used your fast concordance index metric extensively in our work. It was especially useful in our hill-climbing code.</p>",
          "votes": 1,
          "replies": [
            {
              "id": 3143929,
              "author_name": "aldparis",
              "author_url": "",
              "post_date": "2025-03-07T18:22:22.147000",
              "content": "<p>Thank you for the feedback and congratulations again !</p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3145295,
      "author_name": "Matvey Maevskiy",
      "author_url": "",
      "post_date": "2025-03-09T17:01:22.953000",
      "content": "<p>Great job! So much work has been done</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 3144762,
      "author_name": "",
      "author_url": "",
      "post_date": "2025-03-08T20:30:48.157000",
      "content": "<p>Congratulation on your gold medals.I am also trying to get a gold medal for my profile.</p>",
      "votes": 0,
      "replies": []
    }
  ],
  "comment_count": 25,
  "messages": [
    {
      "id": 3142118,
      "postDate": "2025-03-06T05:35:15.063Z",
      "content": "<p>Given the similarities between this competition and the Tabular Playground Series competitions, and the fact that both my teammate and I are experienced TPS participants with a history of success, we decided to apply our knowledge of synthetic tabular datasets to this competition.  </p>\n<p><strong>TL;DR: Large ensembles with minimal feature engineering, plus a few additional tricks.</strong>  </p>\n<p>Over the course of three months, we trained a large repository of models and experimented with various ensembling techniques. By the end of the competition, we had accumulated a total of 98 models trained on a variety of different target transformations. Given the large number of base models, we also did feature selection during ensembling to reduce the number of models and improve our CV score.  </p>\n<h2>Final Solution</h2>\n<p>Our final approach consisted of a <strong>multi-layered ensemble</strong>:  </p>\n<ol>\n<li><strong>First Layer:</strong> A diverse set of base models, including gradient boosted tree models, neural networks, and AutoML.</li>\n<li><strong>Second Layer:</strong> Three different ensemble methods—Ridge regression, hill climbing, and AutoGluon. We conducted feature selection separately for each of these ensemble methods.  </li>\n<li><strong>Third Layer:</strong> A weighted ensemble of the OOF predictions from the three second-layer models.  </li>\n<li><strong>Final Step:</strong> We used an LGBM classifier and applied the masking trick to obtain our final predictions.  </li>\n</ol>\n<p>Below, we provide the CV scores for all our base models and ensemble models.  <br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F16179447%2Fa0bbc02c1271070caaa39331958e9406%2F__results___122_0.png?generation=1741239162520085&amp;alt=media\" alt=\"\"></p>\n<h2>Acknowledgments</h2>\n<p>We would like to thank the organizers for an interesting competition, as well as everyone who shared their insights and ideas, especially <a href=\"https://www.kaggle.com/ambrosm\" target=\"_blank\">@ambrosm</a>, <a href=\"https://www.kaggle.com/adaubas\" target=\"_blank\">@adaubas</a>, <a href=\"https://www.kaggle.com/andreasbis\" target=\"_blank\">@andreasbis</a>, and <a href=\"https://www.kaggle.com/mtinti\" target=\"_blank\">@mtinti</a>.</p>\n<p>On a personal note, I want to congratulate, and give a big thank you to my teammate, <a href=\"https://www.kaggle.com/rzatemizel\" target=\"_blank\">@rzatemizel</a>. This was our first competition medal, and I couldn't have asked for a better partner!  </p>",
      "rawMarkdown": "Given the similarities between this competition and the Tabular Playground Series competitions, and the fact that both my teammate and I are experienced TPS participants with a history of success, we decided to apply our knowledge of synthetic tabular datasets to this competition.  \n\n**TL;DR: Large ensembles with minimal feature engineering, plus a few additional tricks.**  \n\nOver the course of three months, we trained a large repository of models and experimented with various ensembling techniques. By the end of the competition, we had accumulated a total of 98 models trained on a variety of different target transformations. Given the large number of base models, we also did feature selection during ensembling to reduce the number of models and improve our CV score.  \n\n## Final Solution  \n\nOur final approach consisted of a **multi-layered ensemble**:  \n\n1. **First Layer:** A diverse set of base models, including gradient boosted tree models, neural networks, and AutoML.\n2. **Second Layer:** Three different ensemble methods—Ridge regression, hill climbing, and AutoGluon. We conducted feature selection separately for each of these ensemble methods.  \n3. **Third Layer:** A weighted ensemble of the OOF predictions from the three second-layer models.  \n4. **Final Step:** We used an LGBM classifier and applied the masking trick to obtain our final predictions.  \n\nBelow, we provide the CV scores for all our base models and ensemble models.  \n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F16179447%2Fa0bbc02c1271070caaa39331958e9406%2F__results___122_0.png?generation=1741239162520085&alt=media)\n\n## Acknowledgments  \n\nWe would like to thank the organizers for an interesting competition, as well as everyone who shared their insights and ideas, especially @ambrosm, @adaubas, @andreasbis, and @mtinti.\n\nOn a personal note, I want to congratulate, and give a big thank you to my teammate, @rzatemizel. This was our first competition medal, and I couldn't have asked for a better partner!  \n",
      "votes": 27
    },
    {
      "id": 3142156,
      "postDate": "2025-03-06T06:24:03.947Z",
      "content": "<p>Wow, great that you made gold! Nice to see you two doing so well. And this is an amazing amount of models! How did you ensemble them without running into out of memory errors? I could add autogluon and NNs, but as soon as I added my pickle saves of the trained models I got an out of memory error (only when submitting). So I ended up training my models in the submission notebook.</p>",
      "rawMarkdown": "Wow, great that you made gold! Nice to see you two doing so well. And this is an amazing amount of models! How did you ensemble them without running into out of memory errors? I could add autogluon and NNs, but as soon as I added my pickle saves of the trained models I got an out of memory error (only when submitting). So I ended up training my models in the submission notebook.",
      "votes": 3,
      "replies": [
        {
          "id": 3142164,
          "postDate": "2025-03-06T06:38:16.670Z",
          "content": "<p>Thank you! </p>\n<p>We trained our models in separate notebooks and only ran inference on them during submission. The pickles and OOF files we collected were uploaded to a dataset. We didn't run into any memory or space issues. AutoGluon could have encountered disk space problems, but during inference, we moved the pretrained models to the root directory instead of the working directory, which gave us more space to store the models.</p>",
          "rawMarkdown": "Thank you! \n\nWe trained our models in separate notebooks and only ran inference on them during submission. The pickles and OOF files we collected were uploaded to a dataset. We didn't run into any memory or space issues. AutoGluon could have encountered disk space problems, but during inference, we moved the pretrained models to the root directory instead of the working directory, which gave us more space to store the models.",
          "votes": 2
        },
        {
          "id": 3142837,
          "postDate": "2025-03-06T17:46:11.643Z",
          "content": "<p>Ironically my final day submission error might have been the equal and opposite: I was training a crazy number of Autogluon models, and maybe ran out of disk space or(?) on the hidden test set run. So I had to switch to inference but thankfully the \"failed\" run I couldn't debug had all the models right there since my local version passed. </p>",
          "rawMarkdown": "Ironically my final day submission error might have been the equal and opposite: I was training a crazy number of Autogluon models, and maybe ran out of disk space or(?) on the hidden test set run. So I had to switch to inference but thankfully the \"failed\" run I couldn't debug had all the models right there since my local version passed. ",
          "votes": 1,
          "replies": [
            {
              "id": 3142868,
              "postDate": "2025-03-06T18:10:20.383Z",
              "content": "<p>Glad you made it to 5th place despite the last-minute submission errors. </p>\n<p>How many do you consider a crazy amount? 😄</p>",
              "rawMarkdown": "Glad you made it to 5th place despite the last-minute submission errors. \n\nHow many do you consider a crazy amount? 😄"
            },
            {
              "id": 3142979,
              "postDate": "2025-03-06T19:54:09.077Z",
              "content": "<p>Well, my code is homebrew with Autogluon (as one option) underneath, so I was building a separate AG model each fold. And separate for 4 different targets. Plus one more with target encoding. So 25 AG models with separate directories probably keeping all info like 25 copies of validation data or something. I recall when trying to debug seeing about 1.5 GB on the working submission output pane with the small test set. Don't know internals enough to know if they would increase size at all if predicting on more test data? Shouldn't unless they save some type of cached predictions for some reason 🤷🏻‍♂️.</p>\n<p>Not aware that there's a limit anywhere near that for kaggle, but I was saving test predictions as I went so that would also increase size on the hidden run at least a little more. </p>",
              "rawMarkdown": "Well, my code is homebrew with Autogluon (as one option) underneath, so I was building a separate AG model each fold. And separate for 4 different targets. Plus one more with target encoding. So 25 AG models with separate directories probably keeping all info like 25 copies of validation data or something. I recall when trying to debug seeing about 1.5 GB on the working submission output pane with the small test set. Don't know internals enough to know if they would increase size at all if predicting on more test data? Shouldn't unless they save some type of cached predictions for some reason 🤷🏻‍♂️.\n\nNot aware that there's a limit anywhere near that for kaggle, but I was saving test predictions as I went so that would also increase size on the hidden run at least a little more. "
            },
            {
              "id": 3142986,
              "postDate": "2025-03-06T20:00:21Z",
              "content": "<p>If I hadn't seen errors, I likely would've added another 2 Target Encoding variations. For those I didn't want to write Target Encoding inference, so I would have had to run at least the TE auto gluon training during submission notebook. </p>\n<p>The final submit did that but only for a single model config with a single AG run. I never tried to ensemble in the additional TE runs and see which if any got pulled into final sub. </p>",
              "rawMarkdown": "If I hadn't seen errors, I likely would've added another 2 Target Encoding variations. For those I didn't want to write Target Encoding inference, so I would have had to run at least the TE auto gluon training during submission notebook. \n\nThe final submit did that but only for a single model config with a single AG run. I never tried to ensemble in the additional TE runs and see which if any got pulled into final sub. "
            },
            {
              "id": 3143373,
              "postDate": "2025-03-07T07:00:32.147Z",
              "content": "<p>I guess you could have gotten away with only five models instead of 25 and saved yourself some headache. I used to create one model for each fold as well. The problem is that they take a lot of time to train, and you may end up with a different set of models in each fold.  If I had done this, then I would have ended up with 70 AutoGluon models!</p>\n<p>What I did was create one model for each target transformation, then predefine the folds for AutoGluon like this:  </p>\n<pre><code>kf = KFold(n_splits=CFG.n_folds, random_state=CFG.seed, shuffle=)\nsplit = kf.split(train, train[[, ]])\n\n i, (train_index, val_index)  (split):\n    train.loc[val_index, ] = i\n\n    train.loc[train_index, CFG.target], train.loc[val_index, CFG.target] = TargetTransformer(\n        train.loc[train_index, [, ]], \n        train.loc[val_index, [, ]]\n    ).fit_transform(CFG.target)\n</code></pre>\n<p>Then, I told AutoGluon to use these predefined folds like this:</p>\n<pre><code>predictor = TabularPredictor(\n    ...\n    groups=\n)\n</code></pre>",
              "rawMarkdown": "I guess you could have gotten away with only five models instead of 25 and saved yourself some headache. I used to create one model for each fold as well. The problem is that they take a lot of time to train, and you may end up with a different set of models in each fold.  If I had done this, then I would have ended up with 70 AutoGluon models!\n\nWhat I did was create one model for each target transformation, then predefine the folds for AutoGluon like this:  \n\n```python\nkf = KFold(n_splits=CFG.n_folds, random_state=CFG.seed, shuffle=True)\nsplit = kf.split(train, train[[\"efs\", \"efs_time\"]])\n\nfor i, (train_index, val_index) in enumerate(split):\n    train.loc[val_index, \"fold\"] = i\n    \n    train.loc[train_index, CFG.target], train.loc[val_index, CFG.target] = TargetTransformer(\n        train.loc[train_index, [\"efs\", \"efs_time\"]], \n        train.loc[val_index, [\"efs\", \"efs_time\"]]\n    ).fit_transform(CFG.target)\n```\n\nThen, I told AutoGluon to use these predefined folds like this:\n```python\npredictor = TabularPredictor(\n    ...\n    groups=\"fold\"\n)\n```",
              "votes": 1
            },
            {
              "id": 3143553,
              "postDate": "2025-03-07T10:29:35.080Z",
              "content": "<p><a href=\"https://www.kaggle.com/competitions/equity-post-HCT-survival-predictions/discussion/566584#3143511\" target=\"_blank\">It was pointed out to me</a> that there is a bug in my code. I realize now why you had to create a new model for each fold.</p>",
              "rawMarkdown": "[It was pointed out to me](https://www.kaggle.com/competitions/equity-post-HCT-survival-predictions/discussion/566584#3143511) that there is a bug in my code. I realize now why you had to create a new model for each fold."
            },
            {
              "id": 3145473,
              "postDate": "2025-03-09T21:03:49.053Z",
              "content": "<p>In any case, one reason I have done this way is I might well run 100 CPU based models on a large dataset on a single fold in Kaggle, which if train data size is large enough, could take 4+ hours. So that way I start all 5 folds simultaneously on different notebooks without timing out, make sure that it doesn't delete my models (do NOT optimize for deployment) and then after I run my own personal ensembling (patterned after AG's), I manually force the future runs to only include the contributing models.</p>\n<p>But that same use case means that each AG model with optimize for deployment False is probably saving a lot of things I don't care about.</p>",
              "rawMarkdown": "In any case, one reason I have done this way is I might well run 100 CPU based models on a large dataset on a single fold in Kaggle, which if train data size is large enough, could take 4+ hours. So that way I start all 5 folds simultaneously on different notebooks without timing out, make sure that it doesn't delete my models (do NOT optimize for deployment) and then after I run my own personal ensembling (patterned after AG's), I manually force the future runs to only include the contributing models.\n\nBut that same use case means that each AG model with optimize for deployment False is probably saving a lot of things I don't care about."
            }
          ]
        }
      ]
    },
    {
      "id": 3142149,
      "postDate": "2025-03-06T06:10:13.873Z",
      "content": "<p>A big congrats to you and <a href=\"https://www.kaggle.com/rzatemizel\" target=\"_blank\">@rzatemizel</a> on your gold medal! 98 models sounds a lot like what I might have done over 3 months as well. Great to see TPS veterans at the top 😀</p>",
      "rawMarkdown": "A big congrats to you and @rzatemizel on your gold medal! 98 models sounds a lot like what I might have done over 3 months as well. Great to see TPS veterans at the top 😀",
      "votes": 4,
      "replies": [
        {
          "id": 3142161,
          "postDate": "2025-03-06T06:31:53.997Z",
          "content": "<p>Thank you, and congratulations to you as well for your first silver medal.</p>",
          "rawMarkdown": "Thank you, and congratulations to you as well for your first silver medal.",
          "votes": 3
        }
      ]
    },
    {
      "id": 3143842,
      "postDate": "2025-03-07T16:50:40.223Z",
      "content": "<p>Wow great analysis !! 😀</p>",
      "rawMarkdown": "Wow great analysis !! 😀",
      "votes": 1
    },
    {
      "id": 3143453,
      "postDate": "2025-03-07T08:53:03.940Z",
      "content": "<p>Hi Mahdi, congrats! I have two questions: there was some speculation over whether the target creation method caused overfitting - did you create the combined targets using the full train set or just on the fold? Second, what is the masking trick?</p>",
      "rawMarkdown": "Hi Mahdi, congrats! I have two questions: there was some speculation over whether the target creation method caused overfitting - did you create the combined targets using the full train set or just on the fold? Second, what is the masking trick?",
      "votes": 1,
      "replies": [
        {
          "id": 3143472,
          "postDate": "2025-03-07T09:09:21.350Z",
          "content": "<p>We started by running target transformation on the full training set and noticed little difference when performing the transformation inside the CV loop. However, just to be on the safe side, we decided to go with the latter approach.</p>\n<p>The masking trick involves creating a binary classifier to predict efs. Then, we add a constant (which we tune) to the data points predicted as efs=1. This gave a slight boost to the CV score. That said, we also have gold-medal solutions that do not use this trick.</p>",
          "rawMarkdown": "We started by running target transformation on the full training set and noticed little difference when performing the transformation inside the CV loop. However, just to be on the safe side, we decided to go with the latter approach.\n\nThe masking trick involves creating a binary classifier to predict efs. Then, we add a constant (which we tune) to the data points predicted as efs=1. This gave a slight boost to the CV score. That said, we also have gold-medal solutions that do not use this trick.",
          "replies": [
            {
              "id": 3143486,
              "postDate": "2025-03-07T09:16:43.010Z",
              "content": "<p>Thanks, that makes sense. Is there an easy way to create the targets for autogluon? Afaik it expects a column called 'group' but if you need to recalculate targets for each train fold I can't see an easy way to do it.</p>",
              "rawMarkdown": "Thanks, that makes sense. Is there an easy way to create the targets for autogluon? Afaik it expects a column called 'group' but if you need to recalculate targets for each train fold I can't see an easy way to do it."
            },
            {
              "id": 3143494,
              "postDate": "2025-03-07T09:24:20.973Z",
              "content": "<p>It's very easy! <a href=\"https://www.kaggle.com/competitions/equity-post-HCT-survival-predictions/discussion/566584#3143373\" target=\"_blank\">Here</a> is how we did it.</p>",
              "rawMarkdown": "It's very easy! [Here](https://www.kaggle.com/competitions/equity-post-HCT-survival-predictions/discussion/566584#3143373) is how we did it."
            },
            {
              "id": 3143511,
              "postDate": "2025-03-07T09:44:02.570Z",
              "content": "<p>I might have misinterpreted the code in the notebook, but wouldn't this approach overwrite the target in each iteration of the for loop, so your final target would just be the transformation for the last fold?</p>",
              "rawMarkdown": "I might have misinterpreted the code in the notebook, but wouldn't this approach overwrite the target in each iteration of the for loop, so your final target would just be the transformation for the last fold?"
            },
            {
              "id": 3143549,
              "postDate": "2025-03-07T10:21:08.017Z",
              "rawMarkdown": "",
              "isDeleted": true
            },
            {
              "id": 3143550,
              "postDate": "2025-03-07T10:24:25.550Z",
              "content": "<p>You are right. I did not notice this before now.</p>",
              "rawMarkdown": "You are right. I did not notice this before now."
            }
          ]
        }
      ]
    },
    {
      "id": 3142842,
      "postDate": "2025-03-06T17:49:18.510Z",
      "content": "<p>Tons of models for the win! Considering at least top 7 all used a strangely powerful trick of separate model types predicting efs vs efs_time rank, your 12th without that is all the more impressive!</p>",
      "rawMarkdown": "Tons of models for the win! Considering at least top 7 all used a strangely powerful trick of separate model types predicting efs vs efs_time rank, your 12th without that is all the more impressive!",
      "votes": 2
    },
    {
      "id": 3142833,
      "postDate": "2025-03-06T17:40:34.563Z",
      "content": "<p>Congratulations to you both for your gold medal !</p>",
      "rawMarkdown": "Congratulations to you both for your gold medal !",
      "votes": 2,
      "replies": [
        {
          "id": 3143479,
          "postDate": "2025-03-07T09:11:29.550Z",
          "content": "<p>Thank you!</p>\n<p>We used your fast concordance index metric extensively in our work. It was especially useful in our hill-climbing code.</p>",
          "rawMarkdown": "Thank you!\n\nWe used your fast concordance index metric extensively in our work. It was especially useful in our hill-climbing code.",
          "votes": 1,
          "replies": [
            {
              "id": 3143929,
              "postDate": "2025-03-07T18:22:22.147Z",
              "content": "<p>Thank you for the feedback and congratulations again !</p>",
              "rawMarkdown": "Thank you for the feedback and congratulations again !"
            }
          ]
        }
      ]
    },
    {
      "id": 3145295,
      "postDate": "2025-03-09T17:01:22.953Z",
      "content": "<p>Great job! So much work has been done</p>",
      "rawMarkdown": "Great job! So much work has been done"
    },
    {
      "id": 3144762,
      "postDate": "2025-03-08T20:30:48.157Z",
      "content": "<p>Congratulation on your gold medals.I am also trying to get a gold medal for my profile.</p>",
      "rawMarkdown": "Congratulation on your gold medals.I am also trying to get a gold medal for my profile."
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-19T19:47:21Z",
  "competition_id": 70942,
  "competition_slug": "equity-post-HCT-survival-predictions",
  "team_id": 13174076,
  "solution_url": "/competitions/equity-post-HCT-survival-predictions/writeups/mahdi-riza-12th-place-solution"
}