{
  "id": 417821,
  "title": "6th Place Solution - Lightgbm with Target flattened",
  "content": "<p>Great Thanks to kaggle and Godaddy to hold this competition. Congratulations to all the winners. And many thanks go to people who created some mazing public notebooks.<br>\nHere is my Solution:</p>\n<h1>Validation</h1>\n<ul>\n<li>Last 12 month data for validation. </li>\n<li>To evaluate any solution is validate, I additionally compute the number of improve months of the 12 valid month instead of simple average cv improve.Because some month have abnormal high/low raising rate:<code>mbd(curr_month+1)/mbd(curr_month)-1</code>,average cv may lead to overfit</li>\n</ul>\n<h1>Outlier smooth</h1>\n<ul>\n<li>Mean smoothing for 2022-06-&gt;2022-08 to handle the general sharp rise-fall phenomenon \n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2F97e293203e0ddc5a997612331e424658%2F2023-06-17%2017.54.47.png?generation=1686995741884356&amp;alt=media\" alt=\"\"><ul>\n<li>There are also other data points have the phenomenon like \"origin-&gt;Sharp rise-&gt; Sharp fall-&gt;origin\".But I haven't found the best way to deal with them yet.</li></ul></li>\n<li>Basic constant smoothing by fraction from giba</li>\n<li>Stable blacklist for those nearly unchanged cfips<ul>\n<li>[28055, 13101, 13265, 31009, 31115, 31149, 38047, 38087, 48033, 48301]</li></ul></li>\n</ul>\n<h1>features：</h1>\n<ul>\n<li>Action diff, Target shift, Target diff</li>\n<li>Target diff window <ul>\n<li>Sum</li>\n<li>Std</li></ul></li>\n<li>Target window<ul>\n<li>Sum</li>\n<li>Quantile 0.2</li>\n<li>Quantile 0.8</li>\n<li>Lowwer bound：<ul>\n<li>only have value when sign(Quantile 0.2)=sign(Quantile 0.8)，0 for other situations</li>\n<li>Quantile 0.8 for negative value</li>\n<li>Quantile 0.2 for positive value</li></ul></li></ul></li>\n<li>State cluster</li>\n</ul>\n<h1>Enhance modeling framework</h1>\n<p>construct the Enhance model frame, input 1)feature and 2) n_cross: number of future month to predict, output the raising rate of mbd in future n_cross month. In this way we can directly predict the public/private mbd by changing n_cross from 1-5<br>\nDetail structure:</p>\n<ul>\n<li>Enhance modeling frame features=features+n_corss</li>\n<li>n_corss=num of month to predict future mbd</li>\n<li>output target：[mbd(curr_month+n_corss)/mbd(curr_month)]**(1/n_corss)-1</li>\n<li>Model：Xgboost </li>\n</ul>\n<h1>Target_flatten：Train with flattened target, and do reverse transform in prediction</h1>\n<ul>\n<li>The distribution of target variables changes with the change of active base. The lower the active base is, the higher the absolute value of the target is.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2Fdac497d7f6b9266fcd2e81242c29cf3c%2FWechatIMG1604.jpeg?generation=1686995149378846&amp;alt=media\" alt=\"\"></li>\n<li>Do a simulate to transform all active base into same target distribution. We assume the distribution will be flatttened after the transformation, in this way we can construct the transform formula by testing:<ul>\n<li><code>coef=(1/(0.007*(active_series/10+105))+1)</code></li>\n<li><code>target_flatten=target_series/coef</code></li></ul></li>\n<li>Train with flattened target, and do reverse transform in prediction</li>\n</ul>\n<h1>Post process</h1>\n<ul>\n<li>I noticed that the trend of public leaderboard month is abnormal higher than normal months.This phenomenon also happends on other month like 2022-07, In my opnion, such whole month trend is unpredictable, our model should not overfit it.</li>\n<li>Considering that the mbd for the public month is the basis for the subsequent private month, I post-processed the forecast results like:<br>\n<code>prediction=prediction*(1+0.001)</code></li>\n</ul>",
  "comments": [
    {
      "id": 2309734,
      "author_name": "@kaggleqrdl",
      "author_url": "",
      "post_date": "2023-06-19T21:06:23.347000",
      "content": "<p>Well done, 此般浅薄.   </p>",
      "votes": 1,
      "replies": [
        {
          "id": 2309884,
          "author_name": "此般浅薄",
          "author_url": "",
          "post_date": "2023-06-20T00:47:18.113000",
          "content": "<p>Congratulations winning the 1st place!</p>",
          "votes": 1,
          "replies": [
            {
              "id": 2309887,
              "author_name": "@kaggleqrdl",
              "author_url": "",
              "post_date": "2023-06-20T00:49:46.960000",
              "content": "<p>Cheers.  Solo gold is a tough one!  Congrats to you as well.</p>\n<p>Any chance I can entice you to take a look at <a href=\"https://www.kaggle.com/competitions/godaddy-microbusiness-density-forecasting/discussion/418308\" target=\"_blank\">https://www.kaggle.com/competitions/godaddy-microbusiness-density-forecasting/discussion/418308</a> :)   You have an intriguing approach here</p>",
              "votes": 1,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 2306616,
      "author_name": "CoreyJamesLevinson",
      "author_url": "",
      "post_date": "2023-06-17T12:45:36.590000",
      "content": "<p><code>coef=(1/(0.007*(active_series/10+105))+1)</code> Why? I don't understand this part</p>",
      "votes": 1,
      "replies": [
        {
          "id": 2306681,
          "author_name": "此般浅薄",
          "author_url": "",
          "post_date": "2023-06-17T13:29:20.113000",
          "content": "<p>This formula is construct by testing without theoretical basis. Here is the procedure:</p>\n<ol>\n<li>get the initial target:<br>\n<code>raw['target'] = raw.groupby('cfips')['microbusiness_density'].shift(-1)</code><br>\n<code>raw['target'] = raw['target']/raw['microbusiness_density'] - 1</code></li>\n<li>plot the target distribution for different active base.The distribution of target variables changes with the change of active base. The lower the active base is, the higher the absolute value of the target is.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2F2d5b2ff154d7bcf3b275d00c216cc819%2FWechatIMG1609.png?generation=1687007781010306&amp;alt=media\" alt=\"\"><br>\n3.Assume that after transforming all active base into same target distribution,the distribution will be flattened like a straight line.Then find a suitable transform formula just like this:<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2F6a3bada85896f94a78b9c9d3eb36b525%2FWechatIMG1608.png?generation=1687007922643410&amp;alt=media\" alt=\"\"></li>\n</ol>",
          "votes": 0,
          "replies": []
        }
      ]
    }
  ],
  "comment_count": 5,
  "messages": [
    {
      "id": 2306470,
      "postDate": "2023-06-17T10:33:39.793Z",
      "content": "<p>Great Thanks to kaggle and Godaddy to hold this competition. Congratulations to all the winners. And many thanks go to people who created some mazing public notebooks.<br>\nHere is my Solution:</p>\n<h1>Validation</h1>\n<ul>\n<li>Last 12 month data for validation. </li>\n<li>To evaluate any solution is validate, I additionally compute the number of improve months of the 12 valid month instead of simple average cv improve.Because some month have abnormal high/low raising rate:<code>mbd(curr_month+1)/mbd(curr_month)-1</code>,average cv may lead to overfit</li>\n</ul>\n<h1>Outlier smooth</h1>\n<ul>\n<li>Mean smoothing for 2022-06-&gt;2022-08 to handle the general sharp rise-fall phenomenon \n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2F97e293203e0ddc5a997612331e424658%2F2023-06-17%2017.54.47.png?generation=1686995741884356&amp;alt=media\" alt=\"\"><ul>\n<li>There are also other data points have the phenomenon like \"origin-&gt;Sharp rise-&gt; Sharp fall-&gt;origin\".But I haven't found the best way to deal with them yet.</li></ul></li>\n<li>Basic constant smoothing by fraction from giba</li>\n<li>Stable blacklist for those nearly unchanged cfips<ul>\n<li>[28055, 13101, 13265, 31009, 31115, 31149, 38047, 38087, 48033, 48301]</li></ul></li>\n</ul>\n<h1>features：</h1>\n<ul>\n<li>Action diff, Target shift, Target diff</li>\n<li>Target diff window <ul>\n<li>Sum</li>\n<li>Std</li></ul></li>\n<li>Target window<ul>\n<li>Sum</li>\n<li>Quantile 0.2</li>\n<li>Quantile 0.8</li>\n<li>Lowwer bound：<ul>\n<li>only have value when sign(Quantile 0.2)=sign(Quantile 0.8)，0 for other situations</li>\n<li>Quantile 0.8 for negative value</li>\n<li>Quantile 0.2 for positive value</li></ul></li></ul></li>\n<li>State cluster</li>\n</ul>\n<h1>Enhance modeling framework</h1>\n<p>construct the Enhance model frame, input 1)feature and 2) n_cross: number of future month to predict, output the raising rate of mbd in future n_cross month. In this way we can directly predict the public/private mbd by changing n_cross from 1-5<br>\nDetail structure:</p>\n<ul>\n<li>Enhance modeling frame features=features+n_corss</li>\n<li>n_corss=num of month to predict future mbd</li>\n<li>output target：[mbd(curr_month+n_corss)/mbd(curr_month)]**(1/n_corss)-1</li>\n<li>Model：Xgboost </li>\n</ul>\n<h1>Target_flatten：Train with flattened target, and do reverse transform in prediction</h1>\n<ul>\n<li>The distribution of target variables changes with the change of active base. The lower the active base is, the higher the absolute value of the target is.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2Fdac497d7f6b9266fcd2e81242c29cf3c%2FWechatIMG1604.jpeg?generation=1686995149378846&amp;alt=media\" alt=\"\"></li>\n<li>Do a simulate to transform all active base into same target distribution. We assume the distribution will be flatttened after the transformation, in this way we can construct the transform formula by testing:<ul>\n<li><code>coef=(1/(0.007*(active_series/10+105))+1)</code></li>\n<li><code>target_flatten=target_series/coef</code></li></ul></li>\n<li>Train with flattened target, and do reverse transform in prediction</li>\n</ul>\n<h1>Post process</h1>\n<ul>\n<li>I noticed that the trend of public leaderboard month is abnormal higher than normal months.This phenomenon also happends on other month like 2022-07, In my opnion, such whole month trend is unpredictable, our model should not overfit it.</li>\n<li>Considering that the mbd for the public month is the basis for the subsequent private month, I post-processed the forecast results like:<br>\n<code>prediction=prediction*(1+0.001)</code></li>\n</ul>",
      "rawMarkdown": "Great Thanks to kaggle and Godaddy to hold this competition. Congratulations to all the winners. And many thanks go to people who created some mazing public notebooks.\nHere is my Solution:\n# Validation\n- Last 12 month data for validation. \n- To evaluate any solution is validate, I additionally compute the number of improve months of the 12 valid month instead of simple average cv improve.Because some month have abnormal high/low raising rate:`mbd(curr_month+1)/mbd(curr_month)-1`,average cv may lead to overfit\n\n\n#  Outlier smooth\n- Mean smoothing for 2022-06->2022-08 to handle the general sharp rise-fall phenomenon \n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2F97e293203e0ddc5a997612331e424658%2F2023-06-17%2017.54.47.png?generation=1686995741884356&alt=media)\n - There are also other data points have the phenomenon like \"origin->Sharp rise-> Sharp fall->origin\".But I haven't found the best way to deal with them yet.\n- Basic constant smoothing by fraction from giba\n- Stable blacklist for those nearly unchanged cfips\n - [28055, 13101, 13265, 31009, 31115, 31149, 38047, 38087, 48033, 48301]\n# features：\n  - Action diff, Target shift, Target diff\n  - Target diff window \n     - Sum\n     - Std\n  - Target window\n     - Sum\n     - Quantile 0.2\n     - Quantile 0.8\n     - Lowwer bound：\n         - only have value when sign(Quantile 0.2)=sign(Quantile 0.8)，0 for other situations\n         - Quantile 0.8 for negative value\n         - Quantile 0.2 for positive value\n  - State cluster\n# Enhance modeling framework\nconstruct the Enhance model frame, input 1)feature and 2) n_cross: number of future month to predict, output the raising rate of mbd in future n_cross month. In this way we can directly predict the public/private mbd by changing n_cross from 1-5\nDetail structure:\n- Enhance modeling frame features=features+n_corss\n- n_corss=num of month to predict future mbd\n- output target：[mbd(curr_month+n_corss)/mbd(curr_month)]**(1/n_corss)-1\n- Model：Xgboost \n# Target_flatten：Train with flattened target, and do reverse transform in prediction\n- The distribution of target variables changes with the change of active base. The lower the active base is, the higher the absolute value of the target is.\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2Fdac497d7f6b9266fcd2e81242c29cf3c%2FWechatIMG1604.jpeg?generation=1686995149378846&alt=media)\n- Do a simulate to transform all active base into same target distribution. We assume the distribution will be flatttened after the transformation, in this way we can construct the transform formula by testing:\n  - `coef=(1/(0.007*(active_series/10+105))+1)`\n  - `target_flatten=target_series/coef`\n- Train with flattened target, and do reverse transform in prediction\n# Post process\n- I noticed that the trend of public leaderboard month is abnormal higher than normal months.This phenomenon also happends on other month like 2022-07, In my opnion, such whole month trend is unpredictable, our model should not overfit it.\n-  Considering that the mbd for the public month is the basis for the subsequent private month, I post-processed the forecast results like:\n`prediction=prediction*(1+0.001)`\n\n\n",
      "votes": 24
    },
    {
      "id": 2309734,
      "postDate": "2023-06-19T21:06:23.347Z",
      "content": "<p>Well done, 此般浅薄.   </p>",
      "rawMarkdown": "Well done, 此般浅薄.   ",
      "votes": 1,
      "replies": [
        {
          "id": 2309884,
          "postDate": "2023-06-20T00:47:18.113Z",
          "content": "<p>Congratulations winning the 1st place!</p>",
          "rawMarkdown": "Congratulations winning the 1st place!",
          "votes": 1,
          "replies": [
            {
              "id": 2309887,
              "postDate": "2023-06-20T00:49:46.960Z",
              "content": "<p>Cheers.  Solo gold is a tough one!  Congrats to you as well.</p>\n<p>Any chance I can entice you to take a look at <a href=\"https://www.kaggle.com/competitions/godaddy-microbusiness-density-forecasting/discussion/418308\" target=\"_blank\">https://www.kaggle.com/competitions/godaddy-microbusiness-density-forecasting/discussion/418308</a> :)   You have an intriguing approach here</p>",
              "rawMarkdown": "Cheers.  Solo gold is a tough one!  Congrats to you as well.\n\nAny chance I can entice you to take a look at https://www.kaggle.com/competitions/godaddy-microbusiness-density-forecasting/discussion/418308 :)   You have an intriguing approach here",
              "votes": 1
            }
          ]
        }
      ]
    },
    {
      "id": 2306616,
      "postDate": "2023-06-17T12:45:36.590Z",
      "content": "<p><code>coef=(1/(0.007*(active_series/10+105))+1)</code> Why? I don't understand this part</p>",
      "rawMarkdown": "`coef=(1/(0.007*(active_series/10+105))+1)` Why? I don't understand this part",
      "votes": 1,
      "replies": [
        {
          "id": 2306681,
          "postDate": "2023-06-17T13:29:20.113Z",
          "content": "<p>This formula is construct by testing without theoretical basis. Here is the procedure:</p>\n<ol>\n<li>get the initial target:<br>\n<code>raw['target'] = raw.groupby('cfips')['microbusiness_density'].shift(-1)</code><br>\n<code>raw['target'] = raw['target']/raw['microbusiness_density'] - 1</code></li>\n<li>plot the target distribution for different active base.The distribution of target variables changes with the change of active base. The lower the active base is, the higher the absolute value of the target is.<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2F2d5b2ff154d7bcf3b275d00c216cc819%2FWechatIMG1609.png?generation=1687007781010306&amp;alt=media\" alt=\"\"><br>\n3.Assume that after transforming all active base into same target distribution,the distribution will be flattened like a straight line.Then find a suitable transform formula just like this:<br>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2F6a3bada85896f94a78b9c9d3eb36b525%2FWechatIMG1608.png?generation=1687007922643410&amp;alt=media\" alt=\"\"></li>\n</ol>",
          "rawMarkdown": "This formula is construct by testing without theoretical basis. Here is the procedure:\n1. get the initial target:\n`raw['target'] = raw.groupby('cfips')['microbusiness_density'].shift(-1)`\n`raw['target'] = raw['target']/raw['microbusiness_density'] - 1`\n2. plot the target distribution for different active base.The distribution of target variables changes with the change of active base. The lower the active base is, the higher the absolute value of the target is.\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2F2d5b2ff154d7bcf3b275d00c216cc819%2FWechatIMG1609.png?generation=1687007781010306&alt=media)\n3.Assume that after transforming all active base into same target distribution,the distribution will be flattened like a straight line.Then find a suitable transform formula just like this:\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F425081%2F6a3bada85896f94a78b9c9d3eb36b525%2FWechatIMG1608.png?generation=1687007922643410&alt=media)"
        }
      ]
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-19T19:28:34Z",
  "competition_id": 41881,
  "competition_slug": "godaddy-microbusiness-density-forecasting",
  "team_id": 9644183,
  "solution_url": "/competitions/godaddy-microbusiness-density-forecasting/writeups/6th-place-solution-lightgbm-with-target-flattened"
}