{
  "id": 127396,
  "title": "19th Place Solution - Optimizing QWK with Feature Selection and Model Ensembling",
  "content": "<p>First, I would like to thank the BS KIDS team, Kaggle team and all kagglers for this amazing competition. </p>\n<p>It was hard to handle qwk metric with so few test samples without fall in the public LB climbing! </p>\n<p>Here <a href=\"https://www.kaggle.com/steubk/dsb2019-bs-26-lgb-auc-xgb\" target=\"_blank\">https://www.kaggle.com/steubk/dsb2019-bs-26-lgb-auc-xgb</a> you can find  (100% kaggle kernel) solution.</p>\n<p>This is a summary of my solution:</p>\n<ul>\n<li>The Magic\nFor those about to \"hey, where is the kaggle's magic ?\", this is my <em>magic blend</em>:</li>\n</ul>\n<p><code>y  = (2*0.7*y_lgb + 2*0.3*y_xgb + 2*3*y_auc_solved  + 3*y_first_try_success)/5</code></p>\n<p>with y_lgb as lgb regression (rmse) , y_xgb as xgb regression (rmse), y_auc_solved as binary classification(auc) for solved assessments (0/123) and y_first_try_success as binary classifcation (auc) for first try success assessments (012/3) </p>\n<ul>\n<li><p>Data Augmentation\nthanks to <a href=\"/akasyanama13\" target=\"_blank\">@akasyanama13</a> and his kernel <a href=\"https://www.kaggle.com/akasyanama13/another-way-of-validation\" target=\"_blank\">https://www.kaggle.com/akasyanama13/another-way-of-validation</a> I added about 11% training samples (2.018/17.690) in public and many more (75% ?) in private.  </p></li>\n<li><p>Validation Strategy\nFor each learning model trained a 5 GroupKFold on installation_id, with fixed number of iterations (no early stopping), averaged with 5 seeds and validated with median of 5.000 shuffled truncated samples: this guaranteed the stability of the rmse and qwk on cv and qwk on private. </p></li>\n<li><p>Feature enginering \nI generated more than thousand features (1.047), starting from public kernels (@artgor <a href=\"https://www.kaggle.com/artgor/quick-and-dirty-regression\" target=\"_blank\">https://www.kaggle.com/artgor/quick-and-dirty-regression</a> , <a href=\"/braquino\" target=\"_blank\">@braquino</a> <a href=\"https://www.kaggle.com/braquino/890-features\" target=\"_blank\">https://www.kaggle.com/braquino/890-features</a>  and others)\nand then added features for:\ncurrent-assessment,  last-game, last-activity, last-assessment, \"correct\" event_data and encoded timestamp hour in cyclical continuous features.</p></li>\n<li><p>Feature selection \nI selected 128 features with RFE.\nI done first elimation steps removing correlate features (corrcoef &gt; 0.9999) and features with minimal gain in lgb regression model. \nFor last step (from 148 to 128) I computed rmse and qwk for each single feature and removed features for which the gain for rmse AND qwk was negative regardless of the lgb feature importance.\nLast step gives an improvement for qwk in cv and private (cv: 0,5616 --&gt; 0,5624, private: 0.545 --&gt; 0.553)</p></li>\n<li><p>From RMSE to QWK (aka threshold definition)\nI built a simple Bayesian optimization and validated with 5.000 shuffled truncated samples from train.</p></li>\n<li><p>The Magic Revisited (Simple models and ensembling)\nThis was the score before blending: </p></li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>model</th>\n<th>cv</th>\n<th>cv std</th>\n<th>(public)</th>\n<th>private</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>xgb</td>\n<td>0.5574</td>\n<td>0.008</td>\n<td>0.544</td>\n<td>0.550</td>\n</tr>\n<tr>\n<td>lgb</td>\n<td>0.5638</td>\n<td>0.008</td>\n<td>0.538</td>\n<td>0.553</td>\n</tr>\n</tbody>\n</table>\n<p>A simple blend  <code>(0.7*y_lgb + 0.3*y_xgb)</code> of xgb and lgb model has given no imporvements on cv and public  but some improvements in private (0.555).</p>\n<p>In the last days I tried some binary classifications with auc:\nbinary classification for solved assessments (0/123) and binary classification for  first try success (012/3)</p>\n<p>The ordering induced by auc and the small number of elements for qwk made me think that I could try to blend the auc models directly with the regression models: In fact the blend  gives an improvement in cv (0.5680) and an improvement of 0.002 over the simple blend in private. (qwk final score:0.557)  </p>\n<p>Thank you for reading !</p>",
  "comments": [
    {
      "id": 745570,
      "author_name": "Kevin Liu",
      "author_url": "",
      "post_date": "2020-02-14T00:00:21.693000",
      "content": "<p>Your way to blend in the binary classification models is very inspiring. Code is super neat. Thanks for sharing and congratulations on your silver medal. A bit more luck should have landed you in the gold zone.</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 728025,
      "author_name": "Serigne ",
      "author_url": "",
      "post_date": "2020-01-24T10:49:23.963000",
      "content": "<p>Big congrats <a href=\"/steubk\">@steubk</a> </p>",
      "votes": 0,
      "replies": [
        {
          "id": 728123,
          "author_name": "steubk",
          "author_url": "",
          "post_date": "2020-01-24T12:25:16.513000",
          "content": "<p>Grazie <a href=\"/serigne\">@serigne</a> !</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 727751,
      "author_name": "Ailurophile",
      "author_url": "",
      "post_date": "2020-01-24T02:21:00.873000",
      "content": "<p>Congratulations\nThanks for Sharing your Approach &amp; Insights!! <a href=\"/steubk\">@steubk</a> </p>",
      "votes": 0,
      "replies": [
        {
          "id": 727884,
          "author_name": "steubk",
          "author_url": "",
          "post_date": "2020-01-24T06:46:03.760000",
          "content": "<p>thank you <a href=\"/veeralakrishna\">@veeralakrishna</a>  !</p>",
          "votes": 0,
          "replies": []
        }
      ]
    }
  ],
  "comment_count": 5,
  "messages": [
    {
      "id": 727364,
      "postDate": "2020-01-23T16:50:16.603Z",
      "content": "<p>First, I would like to thank the BS KIDS team, Kaggle team and all kagglers for this amazing competition. </p>\n<p>It was hard to handle qwk metric with so few test samples without fall in the public LB climbing! </p>\n<p>Here <a href=\"https://www.kaggle.com/steubk/dsb2019-bs-26-lgb-auc-xgb\" target=\"_blank\">https://www.kaggle.com/steubk/dsb2019-bs-26-lgb-auc-xgb</a> you can find  (100% kaggle kernel) solution.</p>\n<p>This is a summary of my solution:</p>\n<ul>\n<li>The Magic\nFor those about to \"hey, where is the kaggle's magic ?\", this is my <em>magic blend</em>:</li>\n</ul>\n<p><code>y  = (2*0.7*y_lgb + 2*0.3*y_xgb + 2*3*y_auc_solved  + 3*y_first_try_success)/5</code></p>\n<p>with y_lgb as lgb regression (rmse) , y_xgb as xgb regression (rmse), y_auc_solved as binary classification(auc) for solved assessments (0/123) and y_first_try_success as binary classifcation (auc) for first try success assessments (012/3) </p>\n<ul>\n<li><p>Data Augmentation\nthanks to <a href=\"/akasyanama13\" target=\"_blank\">@akasyanama13</a> and his kernel <a href=\"https://www.kaggle.com/akasyanama13/another-way-of-validation\" target=\"_blank\">https://www.kaggle.com/akasyanama13/another-way-of-validation</a> I added about 11% training samples (2.018/17.690) in public and many more (75% ?) in private.  </p></li>\n<li><p>Validation Strategy\nFor each learning model trained a 5 GroupKFold on installation_id, with fixed number of iterations (no early stopping), averaged with 5 seeds and validated with median of 5.000 shuffled truncated samples: this guaranteed the stability of the rmse and qwk on cv and qwk on private. </p></li>\n<li><p>Feature enginering \nI generated more than thousand features (1.047), starting from public kernels (@artgor <a href=\"https://www.kaggle.com/artgor/quick-and-dirty-regression\" target=\"_blank\">https://www.kaggle.com/artgor/quick-and-dirty-regression</a> , <a href=\"/braquino\" target=\"_blank\">@braquino</a> <a href=\"https://www.kaggle.com/braquino/890-features\" target=\"_blank\">https://www.kaggle.com/braquino/890-features</a>  and others)\nand then added features for:\ncurrent-assessment,  last-game, last-activity, last-assessment, \"correct\" event_data and encoded timestamp hour in cyclical continuous features.</p></li>\n<li><p>Feature selection \nI selected 128 features with RFE.\nI done first elimation steps removing correlate features (corrcoef &gt; 0.9999) and features with minimal gain in lgb regression model. \nFor last step (from 148 to 128) I computed rmse and qwk for each single feature and removed features for which the gain for rmse AND qwk was negative regardless of the lgb feature importance.\nLast step gives an improvement for qwk in cv and private (cv: 0,5616 --&gt; 0,5624, private: 0.545 --&gt; 0.553)</p></li>\n<li><p>From RMSE to QWK (aka threshold definition)\nI built a simple Bayesian optimization and validated with 5.000 shuffled truncated samples from train.</p></li>\n<li><p>The Magic Revisited (Simple models and ensembling)\nThis was the score before blending: </p></li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>model</th>\n<th>cv</th>\n<th>cv std</th>\n<th>(public)</th>\n<th>private</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>xgb</td>\n<td>0.5574</td>\n<td>0.008</td>\n<td>0.544</td>\n<td>0.550</td>\n</tr>\n<tr>\n<td>lgb</td>\n<td>0.5638</td>\n<td>0.008</td>\n<td>0.538</td>\n<td>0.553</td>\n</tr>\n</tbody>\n</table>\n<p>A simple blend  <code>(0.7*y_lgb + 0.3*y_xgb)</code> of xgb and lgb model has given no imporvements on cv and public  but some improvements in private (0.555).</p>\n<p>In the last days I tried some binary classifications with auc:\nbinary classification for solved assessments (0/123) and binary classification for  first try success (012/3)</p>\n<p>The ordering induced by auc and the small number of elements for qwk made me think that I could try to blend the auc models directly with the regression models: In fact the blend  gives an improvement in cv (0.5680) and an improvement of 0.002 over the simple blend in private. (qwk final score:0.557)  </p>\n<p>Thank you for reading !</p>",
      "rawMarkdown": "First, I would like to thank the BS KIDS team, Kaggle team and all kagglers for this amazing competition. \n\nIt was hard to handle qwk metric with so few test samples without fall in the public LB climbing! \n\nHere https://www.kaggle.com/steubk/dsb2019-bs-26-lgb-auc-xgb you can find  (100% kaggle kernel) solution.\n\nThis is a summary of my solution:\n\n- The Magic\nFor those about to \"hey, where is the kaggle's magic ?\", this is my _magic blend_:\n\n```y  = (2*0.7*y_lgb + 2*0.3*y_xgb + 2*3*y_auc_solved  + 3*y_first_try_success)/5```\n\nwith y\\_lgb as lgb regression (rmse) , y\\_xgb as xgb regression (rmse), y\\_auc\\_solved as binary classification(auc) for solved assessments (0/123) and y\\_first\\_try\\_success as binary classifcation (auc) for first try success assessments (012/3) \n\n- Data Augmentation\nthanks to @akasyanama13 and his kernel https://www.kaggle.com/akasyanama13/another-way-of-validation I added about 11% training samples (2.018/17.690) in public and many more (75% ?) in private.  \n\n- Validation Strategy\nFor each learning model trained a 5 GroupKFold on installation_id, with fixed number of iterations (no early stopping), averaged with 5 seeds and validated with median of 5.000 shuffled truncated samples: this guaranteed the stability of the rmse and qwk on cv and qwk on private. \n\n- Feature enginering \nI generated more than thousand features (1.047), starting from public kernels (@artgor https://www.kaggle.com/artgor/quick-and-dirty-regression , @braquino https://www.kaggle.com/braquino/890-features  and others)\nand then added features for:\ncurrent-assessment,  last-game, last-activity, last-assessment, \"correct\" event_data and encoded timestamp hour in cyclical continuous features.\n \n- Feature selection \nI selected 128 features with RFE.\nI done first elimation steps removing correlate features (corrcoef &gt; 0.9999) and features with minimal gain in lgb regression model. \nFor last step (from 148 to 128) I computed rmse and qwk for each single feature and removed features for which the gain for rmse AND qwk was negative regardless of the lgb feature importance.\nLast step gives an improvement for qwk in cv and private (cv: 0,5616 --&gt; 0,5624, private: 0.545 --&gt; 0.553)\n\n- From RMSE to QWK (aka threshold definition)\nI built a simple Bayesian optimization and validated with 5.000 shuffled truncated samples from train.\n\n- The Magic Revisited (Simple models and ensembling)\nThis was the score before blending: \n\n| model | cv |cv std|(public)|private| \n| --- | --- |---|---|---|\n|xgb|0.5574|0.008|0.544|0.550|\n|lgb|0.5638|0.008|0.538|0.553|\n\nA simple blend  ```(0.7*y_lgb + 0.3*y_xgb)``` of xgb and lgb model has given no imporvements on cv and public  but some improvements in private (0.555).\n\nIn the last days I tried some binary classifications with auc:\nbinary classification for solved assessments (0/123) and binary classification for  first try success (012/3)\n\nThe ordering induced by auc and the small number of elements for qwk made me think that I could try to blend the auc models directly with the regression models: In fact the blend  gives an improvement in cv (0.5680) and an improvement of 0.002 over the simple blend in private. (qwk final score:0.557)  \n\n\nThank you for reading !",
      "votes": 18
    },
    {
      "id": 745570,
      "postDate": "2020-02-14T00:00:21.693Z",
      "content": "<p>Your way to blend in the binary classification models is very inspiring. Code is super neat. Thanks for sharing and congratulations on your silver medal. A bit more luck should have landed you in the gold zone.</p>",
      "rawMarkdown": "Your way to blend in the binary classification models is very inspiring. Code is super neat. Thanks for sharing and congratulations on your silver medal. A bit more luck should have landed you in the gold zone."
    },
    {
      "id": 728025,
      "postDate": "2020-01-24T10:49:23.963Z",
      "content": "<p>Big congrats <a href=\"/steubk\">@steubk</a> </p>",
      "rawMarkdown": "Big congrats @steubk ",
      "replies": [
        {
          "id": 728123,
          "postDate": "2020-01-24T12:25:16.513Z",
          "content": "<p>Grazie <a href=\"/serigne\">@serigne</a> !</p>",
          "rawMarkdown": "Grazie @serigne !"
        }
      ]
    },
    {
      "id": 727751,
      "postDate": "2020-01-24T02:21:00.873Z",
      "content": "<p>Congratulations\nThanks for Sharing your Approach &amp; Insights!! <a href=\"/steubk\">@steubk</a> </p>",
      "rawMarkdown": "Congratulations\nThanks for Sharing your Approach &amp; Insights!! @steubk ",
      "replies": [
        {
          "id": 727884,
          "postDate": "2020-01-24T06:46:03.760Z",
          "content": "<p>thank you <a href=\"/veeralakrishna\">@veeralakrishna</a>  !</p>",
          "rawMarkdown": "thank you @veeralakrishna  !"
        }
      ]
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-23T06:53:41Z",
  "competition_id": 16531,
  "competition_slug": "data-science-bowl-2019",
  "team_id": 4180066,
  "solution_url": "/competitions/data-science-bowl-2019/writeups/steubk-19th-place-solution"
}