<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/vtreat-prepare-data/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://www.win-vector.com/blog/2017/03/vtreat-prepare-data/"> R – Win-Vector Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>This article is on preparing data for modeling in <a target="_blank" rel="nofollow" href="https://cran.r-project.org/"><code>R</code></a> using <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=vtreat"><code>vtreat</code></a>.</p>
<p><img title="vtreat.png" alt="Vtreat" src="https://i1.wp.com/www.win-vector.com/blog/wp-content/uploads/2017/03/vtreat.png?w=660" border="0" data-recalc-dims="1"><span></span></p>
<h2>Our example</h2>
<p>Suppose we wish to work with some data. Our example task is to train a classification model for credit approval using the <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=ranger"><code>ranger</code></a> implementation of the random forests method. We will take our data from <a target="_blank" rel="nofollow" href="https://archive.ics.uci.edu/ml/datasets/Credit+Approval">John Ross Quinlan's re-processed &quot;credit approval&quot; dataset</a> hosted at <a target="_blank" rel="nofollow" href="http://archive.ics.uci.edu/ml">Lichman, M. (2013). UCI Machine Learning Repository, http://archive.ics.uci.edu/ml; Irvine, CA: University of California, School of Information and Computer Science</a>.</p>
<p>For convenience we have copied the data to our working directory <a target="_blank" rel="nofollow" href="https://github.com/WinVector/Examples/tree/master/vtreat">here</a>. We start by loading the data, identifying the outcome, and splitting the data into training and evaluation portions:</p>
<pre>
# load data
d &lt;- read.table(
  'crx.data.txt',
  header = FALSE,
  sep = ',',
  stringsAsFactors = FALSE,
  na.strings = '?'
)

# prepare outcome column and level
outcome &lt;- 'V16'
positive &lt;- '+'
d[[outcome]] &lt;- as.factor(d[[outcome]])

# identify variables
vars &lt;- setdiff(colnames(d), outcome)

# split into train and test/evaluation
set.seed(25325)
isTrain &lt;- runif(nrow(d)) &lt;= 0.8
dTrain &lt;- d[isTrain, , drop = FALSE]
dTest &lt;- d[!isTrain, , drop = FALSE]
rm(list = 'd')
</pre>
<h2>Without <code>vtreat</code></h2>
<p>We could try to model directly on the original variables without <code>vtreat</code> as below.</p>
<pre>
library(&quot;ranger&quot;)
f &lt;- paste(outcome, 
           paste(vars, collapse = ' + '), 
           sep = ' ~ ')
model &lt;- ranger(as.formula(f),  
                probability = TRUE,
                data = dTrain)
 #  Error: Missing data in columns: V1, V2, V4, V5, V6, V7, V14.
</pre>
<p><code>ranger</code> signaled it did not want to work with this data as there are variables missing values in the training set. This is only one of the <em>many</em> potentially analysis ruining issues that can be lurking in real world data (and as always, detected or signaled errors are better news than undetected errors!).</p>
<p>We name just a few of the issues that could be lurking in real world data:</p>
<p>– Missing values.<br>
– Categorical variable levels that occur in the evaluation set, but were not in the training set (bad luck).<br>
– Categorical variables with large sets of levels.</p>
<h2>With <code>vtreat</code></h2>
<p><code>vtreat</code> is designed to prepare your data for analysis in a statistically sound manner. After <code>vtreat</code> processing all columns are numeric, there are no missing values, and the information in the original data is preserved (modulo user discretion in selecting variables and categorical variable levels).</p>
<p><code>vtreat::prepare()</code> is roughly a powered-up replacement for <code>stats::model.matrix()</code> (which itself is implicit in many <code>R</code> modeling work-flows).</p>
<p>Let's finish the modeling task with <code>vtreat</code>.</p>
<h3>Cross frame experiment</h3>
<p>First we run a &quot;cross frame experiment.&quot; A cross frame experiment is a sophisticated modeling step that:</p>
<p>– Collects statistics on the relations between your original modeling variables and the training outcome.<br>
– Introduces proposed new transformed modeling variables.<br>
– Produces a &quot;simulated out of sample&quot; training frame that is a version of your model training data prepared in such a way as to simulate having been produced without having looked at that same data during the design of the variable transformations. This is an attempt to eliminate any <a target="_blank" rel="nofollow" href="http://www.win-vector.com/blog/2016/04/on-nested-models/">nested model bias</a> introduced by the transform design and application step. This step is performed using cross-validation inspired methods.</p>
<p>In short <code>vtreat</code> thinks very hard on your data (called the design phase). We call <code>vtreat</code> and pull out the promised results as follows.</p>
<pre>
library(&quot;vtreat&quot;)

# Run a &quot;cross frame experiment&quot;
cfe &lt;- vtreat::mkCrossFrameCExperiment(dTrain, vars,
                                       outcome, positive)

# get the &quot;treatment plan&quot; or mapping from original variables
# to derived variables.
plan &lt;- cfe$treatments

# get the performance statistics on the derived variables.
sf &lt;- plan$scoreFrame

# get the simulated out of sample transformed training data.frame
treatedTrain &lt;- cfe$crossFrame
</pre>
<h3>Training a model</h3>
<p>The <code>scoreFrame</code> collects estimated effects sizes and significances on the new modeling variables. The analyst can use this to evaluate and choose modeling variables. In this example we will use all the derived variables that have a training significance below <code>1/NumberOfVariables</code> (which is a fun way to try and avoid <a target="_blank" rel="nofollow" href="https://en.wikipedia.org/wiki/Bonferroni_correction">multiple comparison bias</a> in picking modeling variables).</p>
<pre>
newVars &lt;- sf$varName[sf$sig&lt;1/nrow(sf)]
</pre>
<p>We now build our model using our transformed training data (the cross frame) and our chosen variables.</p>
<pre>
f &lt;- paste(outcome, 
           paste(newVars, collapse = ' + '), 
           sep = ' ~ ')
model &lt;- ranger(as.formula(f), 
                probability = TRUE,
                data = treatedTrain)
</pre>
<h2>Evaluating a model</h2>
<p>We now prepare a transformed version of the evaluation/test frame using the treatment plan.<br>
This is done directly using <code>vtreat::prepare</code>. We could have converted our training data the same way, but as we said it is more rigorous to use the supplied cross frame (though the nested model bias we are trying to avoid is strongest on high-cardinality categorical variables, which are not present in this example). In a real world applications you would keep the <code>plan</code> data structure around to treat or prepare any future application data for model application.</p>
<pre>
treatedTest &lt;- vtreat::prepare(plan, dTest, 
                               pruneSig = NULL, 
                               varRestriction = newVars)

pred &lt;- predict(model, 
                data=treatedTest, 
                type='response')
treatedTest$pred &lt;- pred$predictions[,positive]
</pre>
<p>And we are now ready to examine the model's out of sample performance. In this case we are going to use ROC/AUC as our evaluation.</p>
<pre>
library(&quot;WVPlots&quot;)
WVPlots::ROCPlot(treatedTest, 
                 'pred', outcome, positive,
                 'test performance')
</pre>
<p><img title="eval-1.png" alt="Eval 1" src="https://i1.wp.com/www.win-vector.com/blog/wp-content/uploads/2017/03/eval-1.png?w=660" border="0" data-recalc-dims="1"></p>
<p>And that's it, we have fit and evaluated a model!</p>
<h2>Variable statistics</h2>
<p>Let's take a moment and look at the <code>vtreat</code> supplied variable statistics. These are roughly the predictive power of each derived column treated as a single variable model. Obviously this <a target="_blank" rel="nofollow" href="http://www.win-vector.com/blog/2016/09/variables-can-synergize-even-in-a-linear-model/">isn't always going to always correlate with the performance of the variable as part of a joint model</a>; but frankly in real world problems this measure is in fact a useful heuristic.</p>
<p><code>vtreat</code> reports both an effect size (in this case <code>rsq</code> which for categorization is a pseudo-Rsquared, or portion of deviance explained) and a significance estimate. <code>vtreat</code> also reports the new variable name (`varName`), the original column the variable was derived from (`origName`), and the transformation performed (<a target="_blank" rel="nofollow" href="https://cran.r-project.org/web/packages/vtreat/vignettes/vtreatVariableTypes.html">`code`</a>).</p>
<p>Below we add an indicator (&quot;`take`&quot;) showing if we used the variable in our model and exhibit a few rows of <code>scoreFrame</code>.</p>
<pre>
sf$take &lt;- sf$varName %in% newVars
head(sf[, c('varName', 'rsq', 'sig', 'origName', 'code', 'take')])
 #       varName          rsq          sig origName  code  take
 #  1 V1_lev_x.a 7.475340e-04 0.4485378512       V1   lev FALSE
 #  2 V1_lev_x.b 1.694203e-04 0.7182571422       V1   lev FALSE
 #  3    V1_catP 1.878477e-05 0.9043753424       V1  catP FALSE
 #  4    V1_catB 4.921671e-04 0.5385998340       V1  catB FALSE
 #  5   V2_clean 2.191721e-02 0.0000406801       V2 clean  TRUE
 #  6   V2_isBAD 9.136120e-03 0.0080629087       V2 isBAD  TRUE
</pre>
<p>One thing I would like to call out is that categorical variables (such as &quot;<code>V1</code>&quot;) are eligible for a great number of transformations including:</p>
<p>– Retaining non-negligible levels as dummy or indicator variables (code: &quot;<code>lev</code>&quot;).<br>
– Re-encoding the entire column as an <a target="_blank" rel="nofollow" href="http://www.win-vector.com/blog/2012/07/modeling-trick-impact-coding-of-categorical-variables-with-many-levels/">effect code or impact code</a> (code: &quot;<code>catB</code>&quot;). <code>vtreat</code> can also take a user supplied per-level significance filter to control the formation of this encoding.<br>
– Other statistics, such as per-level prevalence (allows pooling of rare or common events) (code: &quot;<code>catP</code>&quot;).</p>
<h2>Conclusion</h2>
<p>And that is it: <code>vtreat</code> data preparation.</p>
<p><code>vtreat</code> data preparation is sound, very powerful, and can greatly improve the quality of your predictive models. The package is available from <code>CRAN</code> <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=vtreat">here</a> and includes a large number of worked vignettes. We have a formal write-up of the technique <a target="_blank" rel="nofollow" href="https://arxiv.org/abs/1611.09477">here</a>, many articles and tutorials on the methodology <a target="_blank" rel="nofollow" href="http://www.win-vector.com/blog/tag/vtreat/">here</a>, and a good central resource is <a target="_blank" rel="nofollow" href="https://github.com/WinVector/vtreat">here</a>.</p>
<p>I <em>strongly</em> advise adding <code>vtreat</code> to your data science or predictive analytic work-flows.</p>
<p>And a thanks to Dmitry Larko of <a target="_blank" rel="nofollow" href="http://www.h2o.ai/">h2o.ai</a> for his generous advocacy:</p>
<p><center><br>
<img src="https://i0.wp.com/www.win-vector.com/blog/wp-content/uploads/2016/11/NewImage.png?w=660" data-recalc-dims="1"><br>
</center></p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://www.win-vector.com/blog/2017/03/vtreat-prepare-data/"> R – Win-Vector 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 title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/Bzip3uQb-Nk"></a></div>