{
  "id": 324084,
  "title": "11th place solution",
  "url": "/competitions/h-and-m-personalized-fashion-recommendations/writeups/11th-place-solution",
  "author_name": "",
  "post_date": "2022-05-12T01:01:10.237Z",
  "votes": 49,
  "comment_count": 16,
  "views": 0,
  "content": "<p>Thanks Kaggle and H&amp;M for hosting this exciting competition, my teammate <a href=\"https://www.kaggle.com/niwatori\" target=\"_blank\">@niwatori</a> and all participants competing with us.</p>\n<p>Here is a brief summary of our solution.</p>\n<h2>1. Candidate generation</h2>\n<p>As discussed in the forum, we used multiple recall methods to generate the candidates.</p>\n<ul>\n<li>repurchase</li>\n<li>items with the same product code in repurchase</li>\n<li>popular items</li>\n<li>category-wise popular items<ul>\n<li>list the popular items for each department_no</li>\n<li>add them if the customer has bought the item with the same department_no</li></ul></li>\n<li>item2item collaborative filtering</li>\n<li>similarity based on tag ohe vector<ul>\n<li>create item ohe vector from the tags (product_type_no, product_group_name, etc…)</li>\n<li>create user vector which is the average of the item vector bought by the customer</li>\n<li>select top-k items based on the similarity between the user vector and item vector</li></ul></li>\n</ul>\n<p>We left most of the columns added during the candidate generation stage so that we can utilize them as features.</p>\n<h2>2. Feature engineering</h2>\n<p>In addition to the columns generated during the above phase, We added features as follows:</p>\n<ul>\n<li>user static features</li>\n<li>item static features</li>\n<li>dynamic features (same for both user and item)<ul>\n<li>mean and std of price, sales_channel_id</li>\n<li>date-diff since the last transaction</li>\n<li>volume/rank of volume in the last few weeks</li></ul></li>\n<li>user-item features<ul>\n<li>date-diff since the day (user, item) pair last occurred</li>\n<li>count of (user, item), (user’s age, item) pair occurred in the last few weeks</li></ul></li>\n<li>dot product of item ohe vector and user vector</li>\n<li>user embedding from light-fm</li>\n</ul>\n<h2>3. Training</h2>\n<p>We used CatBoost ranker (YetiRank). We also tried to use LGBMRanker, but CatBoost gave much better results in our case. We found that the default parameter gave decent results compared tuned one.</p>\n<p>We used 6, 8, and 12 weeks for training and left the last week for validation. It took up to 20h with a 224 core machine for training a single model.</p>\n<p>Our best single was cv: 0.03589, public: 0.03381,  private: 0.03391.</p>\n<p>Throughout the competition, our validation/public basically correlated positively, but we observed that changing the training weeks gave a negative correlation. (worse cv score, better public/private score)</p>\n<h2>4. Ensembling</h2>\n<p>We followed the ensembling method introduced by <a href=\"https://www.kaggle.com/code/chaudhariharsh/lb-0-0238-h-m-ensembling-how-to-get-bronze\" target=\"_blank\">https://www.kaggle.com/code/chaudhariharsh/lb-0-0238-h-m-ensembling-how-to-get-bronze</a></p>\n<p>We ensembled 4 models trained with different training weeks and different parameters.</p>\n<h2>Notes</h2>\n<p><strong>update</strong> Here is our source code: <a href=\"https://github.com/ryowk/kaggle-h-and-m-personalized-fashion-recommendations\" target=\"_blank\">https://github.com/ryowk/kaggle-h-and-m-personalized-fashion-recommendations</a></p>",
  "messages": [
    {
      "id": "1783015",
      "postDate": "05/10/2022 04:08:20",
      "content": "<p>Thanks Kaggle and H&amp;M for hosting this exciting competition, my teammate <a href=\"https://www.kaggle.com/niwatori\" target=\"_blank\">@niwatori</a> and all participants competing with us.</p>\n<p>Here is a brief summary of our solution.</p>\n<h2>1. Candidate generation</h2>\n<p>As discussed in the forum, we used multiple recall methods to generate the candidates.</p>\n<ul>\n<li>repurchase</li>\n<li>items with the same product code in repurchase</li>\n<li>popular items</li>\n<li>category-wise popular items<ul>\n<li>list the popular items for each department_no</li>\n<li>add them if the customer has bought the item with the same department_no</li></ul></li>\n<li>item2item collaborative filtering</li>\n<li>similarity based on tag ohe vector<ul>\n<li>create item ohe vector from the tags (product_type_no, product_group_name, etc…)</li>\n<li>create user vector which is the average of the item vector bought by the customer</li>\n<li>select top-k items based on the similarity between the user vector and item vector</li></ul></li>\n</ul>\n<p>We left most of the columns added during the candidate generation stage so that we can utilize them as features.</p>\n<h2>2. Feature engineering</h2>\n<p>In addition to the columns generated during the above phase, We added features as follows:</p>\n<ul>\n<li>user static features</li>\n<li>item static features</li>\n<li>dynamic features (same for both user and item)<ul>\n<li>mean and std of price, sales_channel_id</li>\n<li>date-diff since the last transaction</li>\n<li>volume/rank of volume in the last few weeks</li></ul></li>\n<li>user-item features<ul>\n<li>date-diff since the day (user, item) pair last occurred</li>\n<li>count of (user, item), (user’s age, item) pair occurred in the last few weeks</li></ul></li>\n<li>dot product of item ohe vector and user vector</li>\n<li>user embedding from light-fm</li>\n</ul>\n<h2>3. Training</h2>\n<p>We used CatBoost ranker (YetiRank). We also tried to use LGBMRanker, but CatBoost gave much better results in our case. We found that the default parameter gave decent results compared tuned one.</p>\n<p>We used 6, 8, and 12 weeks for training and left the last week for validation. It took up to 20h with a 224 core machine for training a single model.</p>\n<p>Our best single was cv: 0.03589, public: 0.03381,  private: 0.03391.</p>\n<p>Throughout the competition, our validation/public basically correlated positively, but we observed that changing the training weeks gave a negative correlation. (worse cv score, better public/private score)</p>\n<h2>4. Ensembling</h2>\n<p>We followed the ensembling method introduced by <a href=\"https://www.kaggle.com/code/chaudhariharsh/lb-0-0238-h-m-ensembling-how-to-get-bronze\" target=\"_blank\">https://www.kaggle.com/code/chaudhariharsh/lb-0-0238-h-m-ensembling-how-to-get-bronze</a></p>\n<p>We ensembled 4 models trained with different training weeks and different parameters.</p>\n<h2>Notes</h2>\n<p><strong>update</strong> Here is our source code: <a href=\"https://github.com/ryowk/kaggle-h-and-m-personalized-fashion-recommendations\" target=\"_blank\">https://github.com/ryowk/kaggle-h-and-m-personalized-fashion-recommendations</a></p>",
      "rawMarkdown": "Thanks Kaggle and H&M for hosting this exciting competition, my teammate @niwatori and all participants competing with us.\n\nHere is a brief summary of our solution.\n\n## 1. Candidate generation\n\nAs discussed in the forum, we used multiple recall methods to generate the candidates.\n\n- repurchase\n- items with the same product code in repurchase\n- popular items\n- category-wise popular items\n    - list the popular items for each department_no\n    - add them if the customer has bought the item with the same department_no\n- item2item collaborative filtering\n- similarity based on tag ohe vector\n    - create item ohe vector from the tags (product_type_no, product_group_name, etc...)\n    - create user vector which is the average of the item vector bought by the customer\n    - select top-k items based on the similarity between the user vector and item vector\n\nWe left most of the columns added during the candidate generation stage so that we can utilize them as features.\n\n## 2. Feature engineering\n\nIn addition to the columns generated during the above phase, We added features as follows:\n\n- user static features\n- item static features\n- dynamic features (same for both user and item)\n    - mean and std of price, sales_channel_id\n    - date-diff since the last transaction\n    - volume/rank of volume in the last few weeks\n- user-item features\n    - date-diff since the day (user, item) pair last occurred\n    - count of (user, item), (user’s age, item) pair occurred in the last few weeks\n- dot product of item ohe vector and user vector\n- user embedding from light-fm\n\n## 3. Training\n\nWe used CatBoost ranker (YetiRank). We also tried to use LGBMRanker, but CatBoost gave much better results in our case. We found that the default parameter gave decent results compared tuned one.\n\nWe used 6, 8, and 12 weeks for training and left the last week for validation. It took up to 20h with a 224 core machine for training a single model.\n\nOur best single was cv: 0.03589, public: 0.03381,  private: 0.03391.\n\nThroughout the competition, our validation/public basically correlated positively, but we observed that changing the training weeks gave a negative correlation. (worse cv score, better public/private score)\n\n## 4. Ensembling\n\nWe followed the ensembling method introduced by [https://www.kaggle.com/code/chaudhariharsh/lb-0-0238-h-m-ensembling-how-to-get-bronze](https://www.kaggle.com/code/chaudhariharsh/lb-0-0238-h-m-ensembling-how-to-get-bronze)\n\nWe ensembled 4 models trained with different training weeks and different parameters.\n\n## Notes\n\n**update** Here is our source code: https://github.com/ryowk/kaggle-h-and-m-personalized-fashion-recommendations",
      "votes": null
    },
    {
      "id": "1783025",
      "postDate": "05/10/2022 04:19:02",
      "content": "<p>We also try the YetiRank, but the cv score is much lower than binary(lightgbm and catboost) and lgb lambdarank. 😂</p>",
      "rawMarkdown": "We also try the YetiRank, but the cv score is much lower than binary(lightgbm and catboost) and lgb lambdarank. 😂",
      "votes": null
    },
    {
      "id": "1783439",
      "postDate": "05/10/2022 11:59:03",
      "content": "<p>So what's your best single model?</p>",
      "rawMarkdown": "So what's your best single model?",
      "votes": null
    },
    {
      "id": "1783910",
      "postDate": "05/10/2022 19:13:49",
      "content": "<p>Hey there, thanks for sharing your solution! It sounds like you put a lot of work into this and it paid off - congrats on your 11th place finish!</p>\n<p>I'm curious about the ensembling method you used. Can you share more details on that? I'm always looking to learn new techniques.</p>",
      "rawMarkdown": "Hey there, thanks for sharing your solution! It sounds like you put a lot of work into this and it paid off - congrats on your 11th place finish!\n\nI'm curious about the ensembling method you used. Can you share more details on that? I'm always looking to learn new techniques.",
      "votes": null
    },
    {
      "id": "1784647",
      "postDate": "05/11/2022 10:53:58",
      "content": "<p>Hi, thank you!</p>\n<p>We created pairs of submission file and prediction for validation week by following 4 models:</p>\n<ul>\n<li>our public best model (train weeks=8)</li>\n<li>our public best model (train weeks=12)</li>\n<li>our local best model (train weeks=6)</li>\n<li>our local best model (train weeks=8)</li>\n</ul>\n<p>(The reason why we used these models is that they are the only patterns we had before the competition deadline.)</p>\n<p>Then, we determined blending weights by optuna to maximize validation score, and created submission with the tuned weights.</p>",
      "rawMarkdown": "Hi, thank you!\n\nWe created pairs of submission file and prediction for validation week by following 4 models:\n- our public best model (train weeks=8)\n- our public best model (train weeks=12)\n- our local best model (train weeks=6)\n- our local best model (train weeks=8)\n\n(The reason why we used these models is that they are the only patterns we had before the competition deadline.)\n\nThen, we determined blending weights by optuna to maximize validation score, and created submission with the tuned weights.",
      "votes": null
    },
    {
      "id": "1784755",
      "postDate": "05/11/2022 12:44:32",
      "content": "<p>catboost binary classifier.</p>",
      "rawMarkdown": "catboost binary classifier.",
      "votes": null
    },
    {
      "id": "1792300",
      "postDate": "05/16/2022 19:54:13",
      "content": "<p>Thanks for sharing and congratulations for the gold!<br>\nOne question: do you used GPU to train the models or for anything else in this solution?</p>",
      "rawMarkdown": "Thanks for sharing and congratulations for the gold!\nOne question: do you used GPU to train the models or for anything else in this solution?",
      "votes": null
    },
    {
      "id": "1792500",
      "postDate": "05/17/2022 02:52:17",
      "content": "<p>We didn't use GPU to train the models but used to generate candidates(faiss-gpu, specifically).<br>\nWe tested using GPU to train CatBoost model, but it yielded a much worse performance.</p>",
      "rawMarkdown": "We didn't use GPU to train the models but used to generate candidates(faiss-gpu, specifically).\nWe tested using GPU to train CatBoost model, but it yielded a much worse performance.",
      "votes": null
    },
    {
      "id": "1792891",
      "postDate": "05/17/2022 11:55:05",
      "content": "<p>Thanks for the answer. I was trying to run your solution here, but had problems with faiss. Shouldn't you use <code>faiss-gpu</code> instead of <code>faiss-cpu</code> in <code>setup.sh</code>? I installed <code>faiss-gpu</code> and it worked.</p>",
      "rawMarkdown": "Thanks for the answer. I was trying to run your solution here, but had problems with faiss. Shouldn't you use `faiss-gpu` instead of `faiss-cpu` in `setup.sh`? I installed `faiss-gpu` and it worked.",
      "votes": null
    },
    {
      "id": "1793072",
      "postDate": "05/17/2022 15:19:22",
      "content": "<p>As you mentioned, that should be <code>faiss-gpu</code>. Thak you for pointing out!</p>",
      "rawMarkdown": "As you mentioned, that should be `faiss-gpu`. Thak you for pointing out!",
      "votes": null
    },
    {
      "id": "1794018",
      "postDate": "05/18/2022 12:39:27",
      "content": "<p>How much do you boosted your CV when finding best weights from Optuna? We also used blending but without optimizing the weights.</p>",
      "rawMarkdown": "How much do you boosted your CV when finding best weights from Optuna? We also used blending but without optimizing the weights.",
      "votes": null
    },
    {
      "id": "1794267",
      "postDate": "05/18/2022 16:30:20",
      "content": "<p>thanks for sharing hehe</p>",
      "rawMarkdown": "thanks for sharing hehe",
      "votes": null
    },
    {
      "id": "1794774",
      "postDate": "05/19/2022 06:41:12",
      "content": "<p>CV scores of the above four models are 0.03484, 0.03521, 0.03589, 0.03582, respectively, and CV score of the optimized blending is 0.03619. I think it is overestimated, however, its private score was better than blending with equal weights (but only two models).</p>",
      "rawMarkdown": "CV scores of the above four models are 0.03484, 0.03521, 0.03589, 0.03582, respectively, and CV score of the optimized blending is 0.03619. I think it is overestimated, however, its private score was better than blending with equal weights (but only two models).",
      "votes": null
    },
    {
      "id": "1795845",
      "postDate": "05/20/2022 06:56:45",
      "content": "<ol>\n<li><p>What is the intuition behind below line?<br>\n<code>candidates['rank_meta'] = 10**9 * candidates['day_rank'] + candidates['volume_rank']</code></p></li>\n<li><p>I could see the loop for week range from 0-12 only, you have filtered users only for the first week (0) until 12th week and performed your calculations on day, week, ranking etc (in general) for these users. What about the user who appeared in recent weeks from (92nd week until 104th) ? It will be great if you can put some description on your week filters ?</p></li>\n</ol>",
      "rawMarkdown": "1. What is the intuition behind below line?\n`candidates['rank_meta'] = 10**9 * candidates['day_rank'] + candidates['volume_rank']`\n\n2. I could see the loop for week range from 0-12 only, you have filtered users only for the first week (0) until 12th week and performed your calculations on day, week, ranking etc (in general) for these users. What about the user who appeared in recent weeks from (92nd week until 104th) ? It will be great if you can put some description on your week filters ?",
      "votes": null
    },
    {
      "id": "1795878",
      "postDate": "05/20/2022 07:37:24",
      "content": "<ol>\n<li>To sort by <code>day_rank</code> first and then sort by <code>volume_rank</code>  if there is a tie.</li>\n<li>We assigned the week number backward, so week(0) corresponds to the last week. So we performed the calculations over the last 12 weeks.</li>\n</ol>",
      "rawMarkdown": "1. To sort by `day_rank` first and then sort by `volume_rank`  if there is a tie.\n2. We assigned the week number backward, so week(0) corresponds to the last week. So we performed the calculations over the last 12 weeks.",
      "votes": null
    },
    {
      "id": "1796013",
      "postDate": "05/20/2022 11:33:04",
      "content": "<p>Can you please tell me what was the idea behind \"age shifts\" ? I read the code but don't got the point.</p>",
      "rawMarkdown": "Can you please tell me what was the idea behind \"age shifts\" ? I read the code but don't got the point.",
      "votes": null
    },
    {
      "id": "1796191",
      "postDate": "05/20/2022 15:21:28",
      "content": "<p>For a given <code>age</code>, we wanted to get an age range <code>[age-i, age+i]</code> such that the number of the people in the range equals that of between 24 and 26 yo.<br>\n<code>age shifts</code> gives the optimal <code>i</code> for each age. &nbsp;</p>",
      "rawMarkdown": "For a given `age`, we wanted to get an age range `[age-i, age+i]` such that the number of the people in the range equals that of between 24 and 26 yo.\n`age shifts` gives the optimal `i` for each age.",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 1783025,
      "author_name": "juzqyxs",
      "author_url": "",
      "post_date": "05/10/2022 04:19:02",
      "content": "<p>We also try the YetiRank, but the cv score is much lower than binary(lightgbm and catboost) and lgb lambdarank. 😂</p>",
      "votes": null,
      "replies": [
        {
          "id": 1783439,
          "author_name": "biubiug",
          "author_url": "",
          "post_date": "05/10/2022 11:59:03",
          "content": "<p>So what's your best single model?</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 1784755,
          "author_name": "juzqyxs",
          "author_url": "",
          "post_date": "05/11/2022 12:44:32",
          "content": "<p>catboost binary classifier.</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 1783910,
      "author_name": "",
      "author_url": "",
      "post_date": "05/10/2022 19:13:49",
      "content": "<p>Hey there, thanks for sharing your solution! It sounds like you put a lot of work into this and it paid off - congrats on your 11th place finish!</p>\n<p>I'm curious about the ensembling method you used. Can you share more details on that? I'm always looking to learn new techniques.</p>",
      "votes": null,
      "replies": [
        {
          "id": 1784647,
          "author_name": "niwatori",
          "author_url": "",
          "post_date": "05/11/2022 10:53:58",
          "content": "<p>Hi, thank you!</p>\n<p>We created pairs of submission file and prediction for validation week by following 4 models:</p>\n<ul>\n<li>our public best model (train weeks=8)</li>\n<li>our public best model (train weeks=12)</li>\n<li>our local best model (train weeks=6)</li>\n<li>our local best model (train weeks=8)</li>\n</ul>\n<p>(The reason why we used these models is that they are the only patterns we had before the competition deadline.)</p>\n<p>Then, we determined blending weights by optuna to maximize validation score, and created submission with the tuned weights.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 1794018,
          "author_name": "igorkf",
          "author_url": "",
          "post_date": "05/18/2022 12:39:27",
          "content": "<p>How much do you boosted your CV when finding best weights from Optuna? We also used blending but without optimizing the weights.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 1794774,
          "author_name": "niwatori",
          "author_url": "",
          "post_date": "05/19/2022 06:41:12",
          "content": "<p>CV scores of the above four models are 0.03484, 0.03521, 0.03589, 0.03582, respectively, and CV score of the optimized blending is 0.03619. I think it is overestimated, however, its private score was better than blending with equal weights (but only two models).</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 1792300,
      "author_name": "igorkf",
      "author_url": "",
      "post_date": "05/16/2022 19:54:13",
      "content": "<p>Thanks for sharing and congratulations for the gold!<br>\nOne question: do you used GPU to train the models or for anything else in this solution?</p>",
      "votes": null,
      "replies": [
        {
          "id": 1792500,
          "author_name": "keisho",
          "author_url": "",
          "post_date": "05/17/2022 02:52:17",
          "content": "<p>We didn't use GPU to train the models but used to generate candidates(faiss-gpu, specifically).<br>\nWe tested using GPU to train CatBoost model, but it yielded a much worse performance.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 1792891,
          "author_name": "igorkf",
          "author_url": "",
          "post_date": "05/17/2022 11:55:05",
          "content": "<p>Thanks for the answer. I was trying to run your solution here, but had problems with faiss. Shouldn't you use <code>faiss-gpu</code> instead of <code>faiss-cpu</code> in <code>setup.sh</code>? I installed <code>faiss-gpu</code> and it worked.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 1793072,
          "author_name": "keisho",
          "author_url": "",
          "post_date": "05/17/2022 15:19:22",
          "content": "<p>As you mentioned, that should be <code>faiss-gpu</code>. Thak you for pointing out!</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 1794267,
      "author_name": "fajarwibowo",
      "author_url": "",
      "post_date": "05/18/2022 16:30:20",
      "content": "<p>thanks for sharing hehe</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 1795845,
      "author_name": "ahmadzia",
      "author_url": "",
      "post_date": "05/20/2022 06:56:45",
      "content": "<ol>\n<li><p>What is the intuition behind below line?<br>\n<code>candidates['rank_meta'] = 10**9 * candidates['day_rank'] + candidates['volume_rank']</code></p></li>\n<li><p>I could see the loop for week range from 0-12 only, you have filtered users only for the first week (0) until 12th week and performed your calculations on day, week, ranking etc (in general) for these users. What about the user who appeared in recent weeks from (92nd week until 104th) ? It will be great if you can put some description on your week filters ?</p></li>\n</ol>",
      "votes": null,
      "replies": [
        {
          "id": 1795878,
          "author_name": "keisho",
          "author_url": "",
          "post_date": "05/20/2022 07:37:24",
          "content": "<ol>\n<li>To sort by <code>day_rank</code> first and then sort by <code>volume_rank</code>  if there is a tie.</li>\n<li>We assigned the week number backward, so week(0) corresponds to the last week. So we performed the calculations over the last 12 weeks.</li>\n</ol>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 1796013,
      "author_name": "igorkf",
      "author_url": "",
      "post_date": "05/20/2022 11:33:04",
      "content": "<p>Can you please tell me what was the idea behind \"age shifts\" ? I read the code but don't got the point.</p>",
      "votes": null,
      "replies": [
        {
          "id": 1796191,
          "author_name": "keisho",
          "author_url": "",
          "post_date": "05/20/2022 15:21:28",
          "content": "<p>For a given <code>age</code>, we wanted to get an age range <code>[age-i, age+i]</code> such that the number of the people in the range equals that of between 24 and 26 yo.<br>\n<code>age shifts</code> gives the optimal <code>i</code> for each age. &nbsp;</p>",
          "votes": null,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "1783015": "Thanks Kaggle and H&M for hosting this exciting competition, my teammate @niwatori and all participants competing with us.\n\nHere is a brief summary of our solution.\n\n## 1. Candidate generation\n\nAs discussed in the forum, we used multiple recall methods to generate the candidates.\n\n- repurchase\n- items with the same product code in repurchase\n- popular items\n- category-wise popular items\n    - list the popular items for each department_no\n    - add them if the customer has bought the item with the same department_no\n- item2item collaborative filtering\n- similarity based on tag ohe vector\n    - create item ohe vector from the tags (product_type_no, product_group_name, etc...)\n    - create user vector which is the average of the item vector bought by the customer\n    - select top-k items based on the similarity between the user vector and item vector\n\nWe left most of the columns added during the candidate generation stage so that we can utilize them as features.\n\n## 2. Feature engineering\n\nIn addition to the columns generated during the above phase, We added features as follows:\n\n- user static features\n- item static features\n- dynamic features (same for both user and item)\n    - mean and std of price, sales_channel_id\n    - date-diff since the last transaction\n    - volume/rank of volume in the last few weeks\n- user-item features\n    - date-diff since the day (user, item) pair last occurred\n    - count of (user, item), (user’s age, item) pair occurred in the last few weeks\n- dot product of item ohe vector and user vector\n- user embedding from light-fm\n\n## 3. Training\n\nWe used CatBoost ranker (YetiRank). We also tried to use LGBMRanker, but CatBoost gave much better results in our case. We found that the default parameter gave decent results compared tuned one.\n\nWe used 6, 8, and 12 weeks for training and left the last week for validation. It took up to 20h with a 224 core machine for training a single model.\n\nOur best single was cv: 0.03589, public: 0.03381,  private: 0.03391.\n\nThroughout the competition, our validation/public basically correlated positively, but we observed that changing the training weeks gave a negative correlation. (worse cv score, better public/private score)\n\n## 4. Ensembling\n\nWe followed the ensembling method introduced by [https://www.kaggle.com/code/chaudhariharsh/lb-0-0238-h-m-ensembling-how-to-get-bronze](https://www.kaggle.com/code/chaudhariharsh/lb-0-0238-h-m-ensembling-how-to-get-bronze)\n\nWe ensembled 4 models trained with different training weeks and different parameters.\n\n## Notes\n\n**update** Here is our source code: https://github.com/ryowk/kaggle-h-and-m-personalized-fashion-recommendations",
    "1783025": "We also try the YetiRank, but the cv score is much lower than binary(lightgbm and catboost) and lgb lambdarank. 😂",
    "1783439": "So what's your best single model?",
    "1783910": "Hey there, thanks for sharing your solution! It sounds like you put a lot of work into this and it paid off - congrats on your 11th place finish!\n\nI'm curious about the ensembling method you used. Can you share more details on that? I'm always looking to learn new techniques.",
    "1784647": "Hi, thank you!\n\nWe created pairs of submission file and prediction for validation week by following 4 models:\n- our public best model (train weeks=8)\n- our public best model (train weeks=12)\n- our local best model (train weeks=6)\n- our local best model (train weeks=8)\n\n(The reason why we used these models is that they are the only patterns we had before the competition deadline.)\n\nThen, we determined blending weights by optuna to maximize validation score, and created submission with the tuned weights.",
    "1784755": "catboost binary classifier.",
    "1792300": "Thanks for sharing and congratulations for the gold!\nOne question: do you used GPU to train the models or for anything else in this solution?",
    "1792500": "We didn't use GPU to train the models but used to generate candidates(faiss-gpu, specifically).\nWe tested using GPU to train CatBoost model, but it yielded a much worse performance.",
    "1792891": "Thanks for the answer. I was trying to run your solution here, but had problems with faiss. Shouldn't you use `faiss-gpu` instead of `faiss-cpu` in `setup.sh`? I installed `faiss-gpu` and it worked.",
    "1793072": "As you mentioned, that should be `faiss-gpu`. Thak you for pointing out!",
    "1794018": "How much do you boosted your CV when finding best weights from Optuna? We also used blending but without optimizing the weights.",
    "1794267": "thanks for sharing hehe",
    "1794774": "CV scores of the above four models are 0.03484, 0.03521, 0.03589, 0.03582, respectively, and CV score of the optimized blending is 0.03619. I think it is overestimated, however, its private score was better than blending with equal weights (but only two models).",
    "1795845": "1. What is the intuition behind below line?\n`candidates['rank_meta'] = 10**9 * candidates['day_rank'] + candidates['volume_rank']`\n\n2. I could see the loop for week range from 0-12 only, you have filtered users only for the first week (0) until 12th week and performed your calculations on day, week, ranking etc (in general) for these users. What about the user who appeared in recent weeks from (92nd week until 104th) ? It will be great if you can put some description on your week filters ?",
    "1795878": "1. To sort by `day_rank` first and then sort by `volume_rank`  if there is a tie.\n2. We assigned the week number backward, so week(0) corresponds to the last week. So we performed the calculations over the last 12 weeks.",
    "1796013": "Can you please tell me what was the idea behind \"age shifts\" ? I read the code but don't got the point.",
    "1796191": "For a given `age`, we wanted to get an age range `[age-i, age+i]` such that the number of the people in the range equals that of between 24 and 26 yo.\n`age shifts` gives the optimal `i` for each age."
  },
  "source": "meta"
}