<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/optimize-for-expected-profit-in-lift-models/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://samcarlos.netlify.com/2018/07/10/optimize-for-expected-profit-in-lift-models/"> Sweiss' Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p><em>hete is the wild west of analytics. no wrong answers yet</em> – Bill Lattner</p>
<div>
<h2>Intro</h2>
<p>Generally lift models use a Qini coefficient to measure the performance of a model. However this metric is generally an indirect measure of what the user wants to achieve: profit. In this post I’ll discuss a measure of profitability in lift models. A neural network can optimize this cost function directly. A comparison between this method compared with a causal tree implementation shows promising results.</p>
</div>
<div>
<h2>Current lift models</h2>
<p>The goal of lift modeling (or Heterogeneous Treatment Effects ) is to assign an optimal action for a particular observation. This can be, among other things, targeted advertisement or price discrimination. There are several different formulations of lift models which include flip, causal trees, etc.</p>
<p>Essentially all try to estimate the interaction between covariates and the treatment. The most simple parameterized model is: <span>\(y\)</span>: response</p>
<p><span>\(x\)</span>: covariates</p>
<p><span>\(t\)</span>: randomly assigned treatment variable. Assumed to be binary here.</p>
<p><span>\(y = \beta_{1}x + \beta_{2}t+ \beta_{3}t*x\)</span></p>
<p>Here the treatment effect for a particular observation is <span>\(\beta_{2+} \beta_{3}x\)</span>. The key point here is that the treatment effect is now a function of <span>\(x\)</span> which means we can see which observations are more or less effected than others.</p>
<p>Alternatively one can estimate a machine learning model <span>\(y = f(t,x)\)</span> and the treatment effect can be calculated <span>\(\hat{f}(t=1,x) – \hat{f}(t=0,x)\)</span>.</p>
<p>However there are a few issues estimating this accurately which has spun several methods to accurately estimate it.</p>
<ol>
<li>
<p>The heterogeneous treatment effect is probably very small. Indeed one may find that the treatment effect relative to main effect is so small it does not get split on in normal random forests / GBTs! This means we need a model to focus particularly on the treatment effect if we want the results to be useful.</p>
</li>
<li>
<p>We can have potentially hundreds of covariates available to include interactions with. We have no idea a priori which covariates are important so usually we have to expand parameter space significantly. Also, we don’t necessarily have the functional form available so we may take into account nonlinear transformations to the data.</p>
</li>
<li>
<p>We can’t compare the fitted treatment effect values to the ‘truth’. This is the biggest difference between lift models and normal prediction. In prediction settings we can set aside a test set and evaluate our predictions on known responses. Here we want to know the counterfactual; what would have happened if we gave an observation a different value, which lead us to the <a rel="nofollow" href="https://en.wikipedia.org/wiki/Rubin_causal_model#The_fundamental_problem_of_causal_inference" target="_blank">fundamental problem of causality</a>.</p>
</li>
</ol>
<p>So to sum up; we’re trying to estimate a very noisy signal, distributed among a large number of covariates, and we can’t check our estimated model directly.</p>
</div>
<div>
<h2>Metrics to use</h2>
<p>Ok 3) might be a bit of a stretch because there are metrics people can use to assess the performance of their model. One is qini coefficient.</p>
<p>This is a measure that observations with similar treatment effects and groups them into the treatment they were given. If these groups are very different then that is a good measure the model is.</p>
<p>One particular drawback among qini coefficient is that it focuses only on the rank ordering of predicted values. This can be an adequate measure when you care about ranking but there are limitations. The most important being that it does not assign an obvious cutoff between those affected and those not. In the next section I will describe the problem in terms of cost / benefit and suggest a different metric.</p>
</div>
<div>
<h2>A new kind of metric</h2>
<p>Suppose we have <span>\(1…K\)</span> options in the treatment and the goal is to assign the most profitable treatment for each observation. We have a model to assign an optimal treatment for observation <span>\(i\)</span>: <span>\(optim_{i,k}\)</span>. This takes the value 1 if <span>\(k\)</span> is best for observation <span>\(i\)</span> else it’s 0.The expected profit is:</p>
<p><span>\(Expected Profit = \sum_{n=1}^{N}{I(t = optim_{i,k})* y_{i}(x,t=optim_{i,k})}\)</span></p>
<p>The problem is that we cannot assign and observe a treatment to our training data. Instead we can only look at the values we have. Instead I will ‘simulate’ an experiment the following way:</p>
<p><span>\(AverageProfit = {\frac{\sum_{i=1}^{N}\sum_{k=1}^{K}{I(optim_{i,k} = t_{i,k})*y_{i}}}{\sum_{i=1}^{N}\sum_{k=1}^{K}{I(optim_{i} = t_{i,k})}}}\)</span></p>
<p>Basically this is saying if the optimal results equal the randomly assigned treatment then we include those in our hypothetical model. Since I am assuming the treatment is randomly assigned I think this would give a good indicator on the average increase for each observations under this new models decisions. In order to test this out I compared the expected gain with the actual gain of a simulated dataset. Below is the scatterplot and it appears to be a pretty good metric for the actual results.</p>
<p><img src="https://i1.wp.com/samcarlos.netlify.com/post/2018-07-10-asdf_files/figure-html/unnamed-chunk-1-1.png?w=450&ssl=1" data-recalc-dims="1"></p>
</div>
<div>
<h2>Model this Metric Directly?</h2>
<p>If we have a measure that can accurately measure what we want, can we use it as a loss function? This should lead to a better model since the model will optimize over the metric of interest.</p>
<p>We cannot optimize this directly b/c the indicator function is non-differentiable. Instead replacing I() function with a probability and use the custom function below to maximize. – Thanks to <a rel="nofollow" href="https://github.com/beckermr" target="_blank">Matt Becker</a> for this insight.</p>
<p><span>\(CustomLoss = – \sum_{k=1}^{K}{\hat{p_{i,k}(x)}*I(t_i=k)*y_{i}}\)</span></p>
<p>This is essentialy answering the question: what is the probability that action <span>\(k\)</span> is best for observation <span>\(i\)</span>?</p>
<p>Using Keras I <a rel="nofollow" href="https://github.com/samcarlos/hete_post/blob/master/hete_optim.py#L40" target="_blank">hacked together a prototype</a>.</p>
</div>
<div>
<h2>Experiment</h2>
<p>To test this new model (I’m calling it hete-optim) I simulated a similar dataset to that found in <a rel="nofollow" href="https://arxiv.org/pdf/1707.00102.pdf" target="_blank">this paper</a>. There are 200 variables with 15,000 training set and 3,000 test set. Of these there are 8 different scenarios using several nonlinear functions from the explanatory variables. One major difference is that I binarized the response. In addition I increased the random noise and decreased the relative treatment effect to get a more ‘realistic’</p>
<p>I’m comparing this model which my former colleague, Bill Lattner, Developed <a rel="nofollow" href="https://github.com/wlattner/hete" target="_blank">hete</a> and to <a rel="nofollow" href="https://cran.r-project.org/web/packages/grf/index.html" target="_blank">grf</a></p>
</div>
<div>
<h1>Results</h1>
<p>The Metric I’m comparing is profits with true model / profits with fitted model. So if a model get’s a score of .75 then that means that it captures 75% of potential gain using a lift model. This is sort of a normalized regret score so we aggregate results among the 8 scenarios. Below is a boxplot of scores by model type.</p>
<pre><code>## Using  as id variables</code></pre>
<p><img src="https://i0.wp.com/samcarlos.netlify.com/post/2018-07-10-asdf_files/figure-html/unnamed-chunk-2-1.png?w=450&ssl=1" data-recalc-dims="1"></p>
<p>This method performs best on 7 out of 8 datasets. On average hete_opim gets ~99.8% of the gains while hete gets ~98.9% and grf is 99.5%. This suggests that this method might be on to something.</p>
</div>
<div>
<h1>Conclusion</h1>
<p>This post described a method to simulate profits in a real world lift model and the optimize it direclty. It shows promising results to existing techniques.</p>
<p><a rel="nofollow" href="https://github.com/samcarlos/hete_post" target="_blank">Code</a> <a rel="nofollow" href="http://scweiss.blogspot.com/2018/07/comments-for-optimize-for-expected.html" target="_blank">Comments</a></p>
</div>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://samcarlos.netlify.com/2018/07/10/optimize-for-expected-profit-in-lift-models/"> Sweiss' Blog</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/n2zBbDsEdXA" height="1"></a></div>