{
  "id": 82893,
  "title": "#228 Solution - ELO(utliers)  ",
  "url": "/competitions/elo-merchant-category-recommendation/discussion/82893",
  "author_name": "Prashanth Thangavel",
  "post_date": "2019-03-05T06:52:43.594000",
  "votes": 5,
  "comment_count": 0,
  "views": 0,
  "content": "<h1>Data Preprocessing</h1>\n\n<p>We know that the purchase amount has been Normalized by ELO. I used the following steps to back transform the purchase amount.</p>\n\n<ul>\n<li>Step 1 - Get Unique values of purchase amount. Sort the unique values in ascending order.</li>\n<li><p>Step 2 - Scaling purchase_amount back </p></li>\n<li><p>(a) Look at differences between neighbours</p></li>\n<li>(b) Group the differences and get counts.</li>\n<li>(c) Divide purchase_amount by the difference with maximum count in step (b)</li>\n<li>(d) Finally add the minimum value </li>\n</ul>\n\n<p><code>\nn_merc = fread('new_merchant_transactions.csv',select = c('card_id','purchase_amount'))\n</code>\n<code>\nx = data.table('purchase_amount' = unique(n_merc$purchase_amount)) \n</code>\n<code>\ncols = 'purchase_amount'\n</code>\n<code>\nx[,c(\"lag1\"):=shift(.SD,1),.SDcols=cols]\n</code>\n <code>\nx$diff = round(x$purchase_amount - x$lag1,8)\n</code>\n<code>\nc = x %&amp;gt;% group_by(diff) %&amp;gt;% summarise(cnt = n()) %&amp;gt;% arrange(desc(cnt))\n</code>\n<code>\nx$transformed = (x$purchase_amount / 0.00001503)\n</code>\n<code>\nx$transformed = x$transformed - min(x$transformed)\n</code>\n<code>\nx$transformed = log1p(x$transformed)\n</code></p>\n\n<p>Applying log1p over the transformed purchase amount gave 0.04 boost along with aggregate features derived from it. </p>\n\n<h1>Feature Engineering</h1>\n\n<h2>CLV Features</h2>\n\n<p><a href=\"https://www.kaggle.com/prashanththangavel/c-ustomer-l-ifetime-v-alue\">CLV</a> - This is my kernel explaining the basics of it. Lifetime package in python automatically calculates R (Recency), F (Frequency) , T (Time) and M (Monitary value). (<a href=\"https://towardsdatascience.com/whats-a-customer-worth-8daf183f8a4f\">Lifetimes</a>)  This also helps us calculate predicted purchases using regression techniques (you will have to specify time frame in days as prediction period for purchase amount)  In addition, two way interactions between R,F,M and T were also included. (+,-,*,)</p>\n\n<h2>Regression Features</h2>\n\n<p><a href=\"https://www.kaggle.com/c/elo-merchant-category-recommendation/discussion/79217\">Oleg's</a> regression features. Transformed the purchase amount as mentioned above, before running regression.</p>\n\n<h2>Ratio and Percentage change Features</h2>\n\n<ol>\n<li>Subset for purchase amount, purchase date and card_id from historical transactions.</li>\n<li>Sort by purchase date and card_id.</li>\n<li>Ratio of current-purchase_amount / prev-puchase_amount.</li>\n<li>Percentage change from prev-puchase_amount to current-purchase_amount.</li>\n<li>Repeat the step (3) using time stamp to get ratios. (Ideal time between each transaction)</li>\n<li>Finally used mean, min and max over each card_id for the features obtained in the steps above. </li>\n</ol>\n\n<h2>Aggregate Features</h2>\n\n<p>Aggregate features from hist_transactions, splitting based on authorized and unauthorized transactions before aggregation was very useful. Similar aggregates for new_transactions table.    </p>\n\n<h1>Feature Selection and Models</h1>\n\n<p>Shout out to <a href=\"https://www.kaggle.com/ogrellier\">Olivier</a> for sharing this remarkable kernel on feature selection using <a href=\"https://www.kaggle.com/ogrellier/feature-selection-with-null-importances\">NULL IMPORTANCE</a>. Several thresholds for feature importance was used iteratively to remove insignificant features.</p>\n\n<p><strong>Regression Model trained without outliers</strong>\n1. LightGBM \n2. XgBoost </p>\n\n<p><strong>Classification Model</strong>\n1. LightGBM model for binary classification.\n2. Optimal threshold for classifying probabilities into class 1 (outlier) and 0 (not outlier) was determined using <a href=\"https://www.saedsayad.com/model_evaluation_c.htm\">KStat</a>\n3. Built a Ridge regression over 2207 outliers with some additional rows (having low loyalty scores) and predicted over the results which has class 1 from step 2.</p>\n\n<p>Combined both regression and classification model results. Best private score was 3.611 which would have helped our team end at silver position instead of a bronze. None the less, it was an amazing contest. </p>\n\n<h1>Thanks for your time.</h1>",
  "messages": [
    {
      "id": 483801,
      "postDate": "2019-03-05T06:52:43.593Z",
      "content": "<h1>Data Preprocessing</h1>\n\n<p>We know that the purchase amount has been Normalized by ELO. I used the following steps to back transform the purchase amount.</p>\n\n<ul>\n<li>Step 1 - Get Unique values of purchase amount. Sort the unique values in ascending order.</li>\n<li><p>Step 2 - Scaling purchase_amount back </p></li>\n<li><p>(a) Look at differences between neighbours</p></li>\n<li>(b) Group the differences and get counts.</li>\n<li>(c) Divide purchase_amount by the difference with maximum count in step (b)</li>\n<li>(d) Finally add the minimum value </li>\n</ul>\n\n<p><code>\nn_merc = fread('new_merchant_transactions.csv',select = c('card_id','purchase_amount'))\n</code>\n<code>\nx = data.table('purchase_amount' = unique(n_merc$purchase_amount)) \n</code>\n<code>\ncols = 'purchase_amount'\n</code>\n<code>\nx[,c(\"lag1\"):=shift(.SD,1),.SDcols=cols]\n</code>\n <code>\nx$diff = round(x$purchase_amount - x$lag1,8)\n</code>\n<code>\nc = x %&amp;gt;% group_by(diff) %&amp;gt;% summarise(cnt = n()) %&amp;gt;% arrange(desc(cnt))\n</code>\n<code>\nx$transformed = (x$purchase_amount / 0.00001503)\n</code>\n<code>\nx$transformed = x$transformed - min(x$transformed)\n</code>\n<code>\nx$transformed = log1p(x$transformed)\n</code></p>\n\n<p>Applying log1p over the transformed purchase amount gave 0.04 boost along with aggregate features derived from it. </p>\n\n<h1>Feature Engineering</h1>\n\n<h2>CLV Features</h2>\n\n<p><a href=\"https://www.kaggle.com/prashanththangavel/c-ustomer-l-ifetime-v-alue\">CLV</a> - This is my kernel explaining the basics of it. Lifetime package in python automatically calculates R (Recency), F (Frequency) , T (Time) and M (Monitary value). (<a href=\"https://towardsdatascience.com/whats-a-customer-worth-8daf183f8a4f\">Lifetimes</a>)  This also helps us calculate predicted purchases using regression techniques (you will have to specify time frame in days as prediction period for purchase amount)  In addition, two way interactions between R,F,M and T were also included. (+,-,*,)</p>\n\n<h2>Regression Features</h2>\n\n<p><a href=\"https://www.kaggle.com/c/elo-merchant-category-recommendation/discussion/79217\">Oleg's</a> regression features. Transformed the purchase amount as mentioned above, before running regression.</p>\n\n<h2>Ratio and Percentage change Features</h2>\n\n<ol>\n<li>Subset for purchase amount, purchase date and card_id from historical transactions.</li>\n<li>Sort by purchase date and card_id.</li>\n<li>Ratio of current-purchase_amount / prev-puchase_amount.</li>\n<li>Percentage change from prev-puchase_amount to current-purchase_amount.</li>\n<li>Repeat the step (3) using time stamp to get ratios. (Ideal time between each transaction)</li>\n<li>Finally used mean, min and max over each card_id for the features obtained in the steps above. </li>\n</ol>\n\n<h2>Aggregate Features</h2>\n\n<p>Aggregate features from hist_transactions, splitting based on authorized and unauthorized transactions before aggregation was very useful. Similar aggregates for new_transactions table.    </p>\n\n<h1>Feature Selection and Models</h1>\n\n<p>Shout out to <a href=\"https://www.kaggle.com/ogrellier\">Olivier</a> for sharing this remarkable kernel on feature selection using <a href=\"https://www.kaggle.com/ogrellier/feature-selection-with-null-importances\">NULL IMPORTANCE</a>. Several thresholds for feature importance was used iteratively to remove insignificant features.</p>\n\n<p><strong>Regression Model trained without outliers</strong>\n1. LightGBM \n2. XgBoost </p>\n\n<p><strong>Classification Model</strong>\n1. LightGBM model for binary classification.\n2. Optimal threshold for classifying probabilities into class 1 (outlier) and 0 (not outlier) was determined using <a href=\"https://www.saedsayad.com/model_evaluation_c.htm\">KStat</a>\n3. Built a Ridge regression over 2207 outliers with some additional rows (having low loyalty scores) and predicted over the results which has class 1 from step 2.</p>\n\n<p>Combined both regression and classification model results. Best private score was 3.611 which would have helped our team end at silver position instead of a bronze. None the less, it was an amazing contest. </p>\n\n<h1>Thanks for your time.</h1>",
      "rawMarkdown": "# Data Preprocessing \n\nWe know that the purchase amount has been Normalized by ELO. I used the following steps to back transform the purchase amount.\n\n - Step 1 - Get Unique values of purchase amount. Sort the unique values in ascending order.\n - Step 2 - Scaling purchase_amount back \n  \n - (a) Look at differences between neighbours\n - (b) Group the differences and get counts.\n - (c) Divide purchase_amount by the difference with maximum count in step (b)\n - (d) Finally add the minimum value \n\n```    \nn_merc = fread('new_merchant_transactions.csv',select = c('card_id','purchase_amount'))\n```\n```\nx = data.table('purchase_amount' = unique(n_merc$purchase_amount)) \n```\n```\t\ncols = 'purchase_amount'\n```\n```\nx[,c(\"lag1\"):=shift(.SD,1),.SDcols=cols]\n```\n ``` \nx$diff = round(x$purchase_amount - x$lag1,8)\n```\n```\nc = x %&gt;% group_by(diff) %&gt;% summarise(cnt = n()) %&gt;% arrange(desc(cnt))\n```\n```\nx$transformed = (x$purchase_amount / 0.00001503)\n```\n```\nx$transformed = x$transformed - min(x$transformed)\n```\n```\nx$transformed = log1p(x$transformed)\n```\n\nApplying log1p over the transformed purchase amount gave 0.04 boost along with aggregate features derived from it. \n\n# Feature Engineering \n\n##CLV Features\n[CLV][1] - This is my kernel explaining the basics of it. Lifetime package in python automatically calculates R (Recency), F (Frequency) , T (Time) and M (Monitary value). ([Lifetimes][2])  This also helps us calculate predicted purchases using regression techniques (you will have to specify time frame in days as prediction period for purchase amount)  In addition, two way interactions between R,F,M and T were also included. (+,-,*,\\)\n\n##Regression Features\n[Oleg's](https://www.kaggle.com/c/elo-merchant-category-recommendation/discussion/79217) regression features. Transformed the purchase amount as mentioned above, before running regression.\n\n##Ratio and Percentage change Features\n1.  Subset for purchase amount, purchase date and card_id from historical transactions.\n2. Sort by purchase date and card_id.\n3. Ratio of current-purchase_amount / prev-puchase_amount.\n4. Percentage change from prev-puchase_amount to current-purchase_amount.\n5. Repeat the step (3) using time stamp to get ratios. (Ideal time between each transaction)\n6. Finally used mean, min and max over each card_id for the features obtained in the steps above. \n\n##Aggregate Features\nAggregate features from hist_transactions, splitting based on authorized and unauthorized transactions before aggregation was very useful. Similar aggregates for new_transactions table.    \n\n# Feature Selection and Models\nShout out to [Olivier](https://www.kaggle.com/ogrellier) for sharing this remarkable kernel on feature selection using [NULL IMPORTANCE](https://www.kaggle.com/ogrellier/feature-selection-with-null-importances). Several thresholds for feature importance was used iteratively to remove insignificant features.\n\n**Regression Model trained without outliers**\n1. LightGBM \n2. XgBoost \n\n**Classification Model**\n1. LightGBM model for binary classification.\n2. Optimal threshold for classifying probabilities into class 1 (outlier) and 0 (not outlier) was determined using [KStat](https://www.saedsayad.com/model_evaluation_c.htm)\n3. Built a Ridge regression over 2207 outliers with some additional rows (having low loyalty scores) and predicted over the results which has class 1 from step 2.\n\nCombined both regression and classification model results. Best private score was 3.611 which would have helped our team end at silver position instead of a bronze. None the less, it was an amazing contest. \n\n#Thanks for your time.\n\n  [1]: https://www.kaggle.com/prashanththangavel/c-ustomer-l-ifetime-v-alue\n  [2]: https://towardsdatascience.com/whats-a-customer-worth-8daf183f8a4f",
      "votes": 5
    }
  ],
  "comments": [],
  "raw_markdown_by_id": {
    "483801": "# Data Preprocessing \n\nWe know that the purchase amount has been Normalized by ELO. I used the following steps to back transform the purchase amount.\n\n - Step 1 - Get Unique values of purchase amount. Sort the unique values in ascending order.\n - Step 2 - Scaling purchase_amount back \n  \n - (a) Look at differences between neighbours\n - (b) Group the differences and get counts.\n - (c) Divide purchase_amount by the difference with maximum count in step (b)\n - (d) Finally add the minimum value \n\n```    \nn_merc = fread('new_merchant_transactions.csv',select = c('card_id','purchase_amount'))\n```\n```\nx = data.table('purchase_amount' = unique(n_merc$purchase_amount)) \n```\n```\t\ncols = 'purchase_amount'\n```\n```\nx[,c(\"lag1\"):=shift(.SD,1),.SDcols=cols]\n```\n ``` \nx$diff = round(x$purchase_amount - x$lag1,8)\n```\n```\nc = x %&gt;% group_by(diff) %&gt;% summarise(cnt = n()) %&gt;% arrange(desc(cnt))\n```\n```\nx$transformed = (x$purchase_amount / 0.00001503)\n```\n```\nx$transformed = x$transformed - min(x$transformed)\n```\n```\nx$transformed = log1p(x$transformed)\n```\n\nApplying log1p over the transformed purchase amount gave 0.04 boost along with aggregate features derived from it. \n\n# Feature Engineering \n\n##CLV Features\n[CLV][1] - This is my kernel explaining the basics of it. Lifetime package in python automatically calculates R (Recency), F (Frequency) , T (Time) and M (Monitary value). ([Lifetimes][2])  This also helps us calculate predicted purchases using regression techniques (you will have to specify time frame in days as prediction period for purchase amount)  In addition, two way interactions between R,F,M and T were also included. (+,-,*,\\)\n\n##Regression Features\n[Oleg's](https://www.kaggle.com/c/elo-merchant-category-recommendation/discussion/79217) regression features. Transformed the purchase amount as mentioned above, before running regression.\n\n##Ratio and Percentage change Features\n1.  Subset for purchase amount, purchase date and card_id from historical transactions.\n2. Sort by purchase date and card_id.\n3. Ratio of current-purchase_amount / prev-puchase_amount.\n4. Percentage change from prev-puchase_amount to current-purchase_amount.\n5. Repeat the step (3) using time stamp to get ratios. (Ideal time between each transaction)\n6. Finally used mean, min and max over each card_id for the features obtained in the steps above. \n\n##Aggregate Features\nAggregate features from hist_transactions, splitting based on authorized and unauthorized transactions before aggregation was very useful. Similar aggregates for new_transactions table.    \n\n# Feature Selection and Models\nShout out to [Olivier](https://www.kaggle.com/ogrellier) for sharing this remarkable kernel on feature selection using [NULL IMPORTANCE](https://www.kaggle.com/ogrellier/feature-selection-with-null-importances). Several thresholds for feature importance was used iteratively to remove insignificant features.\n\n**Regression Model trained without outliers**\n1. LightGBM \n2. XgBoost \n\n**Classification Model**\n1. LightGBM model for binary classification.\n2. Optimal threshold for classifying probabilities into class 1 (outlier) and 0 (not outlier) was determined using [KStat](https://www.saedsayad.com/model_evaluation_c.htm)\n3. Built a Ridge regression over 2207 outliers with some additional rows (having low loyalty scores) and predicted over the results which has class 1 from step 2.\n\nCombined both regression and classification model results. Best private score was 3.611 which would have helped our team end at silver position instead of a bronze. None the less, it was an amazing contest. \n\n#Thanks for your time.\n\n  [1]: https://www.kaggle.com/prashanththangavel/c-ustomer-l-ifetime-v-alue\n  [2]: https://towardsdatascience.com/whats-a-customer-worth-8daf183f8a4f"
  },
  "complete": true,
  "source": "existing_discussion",
  "competition_id": 10445,
  "competition_slug": "elo-merchant-category-recommendation",
  "team_id": 2445973,
  "solution_url": "/competitions/elo-merchant-category-recommendation/writeups/elo-utliers-228-solution-elo-utliers"
}