<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/handling-class-imbalance-with-r-and-caret-caveats-when-using-the-auc/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://dpmartin42.github.io/blogposts/r/imbalanced-classes-part-2"> Wicked Good Data - r</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>In my <a target="_blank" rel="nofollow" href="http://dpmartin42.github.io/blogposts/r/imbalanced-classes-part-1">last post</a>, I went over how weighting and sampling methods can help to improve predictive performance in the case of imbalanced classes. I also included an applied example with a simulated dataset that used the area under the ROC curve (AUC) as the evaluation metric. In this post, I will go over some issues to keep in mind when using the AUC in the case of imbalanced classes and highlight another metric that is useful to examine: area under the precision-recall curve (AUPRC).</p>
<p>To quickly catch up, essential code from the previous post is below:</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>dplyr</span><span>)</span><span> </span><span># for data manipulation
</span><span>library</span><span>(</span><span>caret</span><span>)</span><span> </span><span># for model-building
</span><span>library</span><span>(</span><span>DMwR</span><span>)</span><span> </span><span># for smote implementation
</span><span>library</span><span>(</span><span>purrr</span><span>)</span><span> </span><span># for functional programming (map)
</span><span>library</span><span>(</span><span>pROC</span><span>)</span><span> </span><span># for AUC calculations
</span><span>library</span><span>(</span><span>PRROC</span><span>)</span><span> </span><span># for Precision-Recall curve calculations
</span><span>
</span><span>set.seed</span><span>(</span><span>2969</span><span>)</span><span>
</span><span>imbal_train</span><span> </span><span>&lt;-</span><span> </span><span>twoClassSim</span><span>(</span><span>5000</span><span>,</span><span>
</span><span>intercept</span><span> </span><span>=</span><span> </span><span>-25</span><span>,</span><span>
</span><span>linearVars</span><span> </span><span>=</span><span> </span><span>20</span><span>,</span><span>
</span><span>noiseVars</span><span> </span><span>=</span><span> </span><span>10</span><span>)</span><span>
</span><span>imbal_test</span><span> </span><span>&lt;-</span><span> </span><span>twoClassSim</span><span>(</span><span>5000</span><span>,</span><span>
</span><span>intercept</span><span> </span><span>=</span><span> </span><span>-25</span><span>,</span><span>
</span><span>linearVars</span><span> </span><span>=</span><span> </span><span>20</span><span>,</span><span>
</span><span>noiseVars</span><span> </span><span>=</span><span> </span><span>10</span><span>)</span><span>
</span><span># Set up control function for training
</span><span>
</span><span>ctrl</span><span> </span><span>&lt;-</span><span> </span><span>trainControl</span><span>(</span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;repeatedcv&quot;</span><span>,</span><span>
</span><span>number</span><span> </span><span>=</span><span> </span><span>10</span><span>,</span><span>
</span><span>repeats</span><span> </span><span>=</span><span> </span><span>5</span><span>,</span><span>
</span><span>summaryFunction</span><span> </span><span>=</span><span> </span><span>twoClassSummary</span><span>,</span><span>
</span><span>classProbs</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span><span>
</span><span># Build a standard classifier using a gradient boosted machine
</span><span>
</span><span>set.seed</span><span>(</span><span>5627</span><span>)</span><span>
</span><span>orig_fit</span><span> </span><span>&lt;-</span><span> </span><span>train</span><span>(</span><span>Class</span><span> </span><span>~</span><span> </span><span>.</span><span>,</span><span>
</span><span>data</span><span> </span><span>=</span><span> </span><span>imbal_train</span><span>,</span><span>
</span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;gbm&quot;</span><span>,</span><span>
</span><span>verbose</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>,</span><span>
</span><span>metric</span><span> </span><span>=</span><span> </span><span>&quot;ROC&quot;</span><span>,</span><span>
</span><span>trControl</span><span> </span><span>=</span><span> </span><span>ctrl</span><span>)</span><span>
</span><span># Create model weights (they sum to one)
</span><span>
</span><span>model_weights</span><span> </span><span>&lt;-</span><span> </span><span>ifelse</span><span>(</span><span>imbal_train</span><span>$</span><span>Class</span><span> </span><span>==</span><span> </span><span>&quot;Class1&quot;</span><span>,</span><span>
</span><span>(</span><span>1</span><span>/</span><span>table</span><span>(</span><span>imbal_train</span><span>$</span><span>Class</span><span>)[</span><span>1</span><span>])</span><span> </span><span>*</span><span> </span><span>0.5</span><span>,</span><span>
</span><span>(</span><span>1</span><span>/</span><span>table</span><span>(</span><span>imbal_train</span><span>$</span><span>Class</span><span>)[</span><span>2</span><span>])</span><span> </span><span>*</span><span> </span><span>0.5</span><span>)</span><span>
</span><span># Use the same seed to ensure same cross-validation splits
</span><span>
</span><span>ctrl</span><span>$</span><span>seeds</span><span> </span><span>&lt;-</span><span> </span><span>orig_fit</span><span>$</span><span>control</span><span>$</span><span>seeds</span><span>
</span><span>weighted_fit</span><span> </span><span>&lt;-</span><span> </span><span>train</span><span>(</span><span>Class</span><span> </span><span>~</span><span> </span><span>.</span><span>,</span><span>
</span><span>data</span><span> </span><span>=</span><span> </span><span>imbal_train</span><span>,</span><span>
</span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;gbm&quot;</span><span>,</span><span>
</span><span>verbose</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>,</span><span>
</span><span>weights</span><span> </span><span>=</span><span> </span><span>model_weights</span><span>,</span><span>
</span><span>metric</span><span> </span><span>=</span><span> </span><span>&quot;ROC&quot;</span><span>,</span><span>
</span><span>trControl</span><span> </span><span>=</span><span> </span><span>ctrl</span><span>)</span><span>
</span><span>ctrl</span><span>$</span><span>sampling</span><span> </span><span>&lt;-</span><span> </span><span>&quot;down&quot;</span><span>
</span><span>down_fit</span><span> </span><span>&lt;-</span><span> </span><span>train</span><span>(</span><span>Class</span><span> </span><span>~</span><span> </span><span>.</span><span>,</span><span>
</span><span>data</span><span> </span><span>=</span><span> </span><span>imbal_train</span><span>,</span><span>
</span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;gbm&quot;</span><span>,</span><span>
</span><span>verbose</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>,</span><span>
</span><span>metric</span><span> </span><span>=</span><span> </span><span>&quot;ROC&quot;</span><span>,</span><span>
</span><span>trControl</span><span> </span><span>=</span><span> </span><span>ctrl</span><span>)</span><span>
</span><span>ctrl</span><span>$</span><span>sampling</span><span> </span><span>&lt;-</span><span> </span><span>&quot;up&quot;</span><span>
</span><span>up_fit</span><span> </span><span>&lt;-</span><span> </span><span>train</span><span>(</span><span>Class</span><span> </span><span>~</span><span> </span><span>.</span><span>,</span><span>
</span><span>data</span><span> </span><span>=</span><span> </span><span>imbal_train</span><span>,</span><span>
</span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;gbm&quot;</span><span>,</span><span>
</span><span>verbose</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>,</span><span>
</span><span>metric</span><span> </span><span>=</span><span> </span><span>&quot;ROC&quot;</span><span>,</span><span>
</span><span>trControl</span><span> </span><span>=</span><span> </span><span>ctrl</span><span>)</span><span>
</span><span>ctrl</span><span>$</span><span>sampling</span><span> </span><span>&lt;-</span><span> </span><span>&quot;smote&quot;</span><span>
</span><span>smote_fit</span><span> </span><span>&lt;-</span><span> </span><span>train</span><span>(</span><span>Class</span><span> </span><span>~</span><span> </span><span>.</span><span>,</span><span>
</span><span>data</span><span> </span><span>=</span><span> </span><span>imbal_train</span><span>,</span><span>
</span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;gbm&quot;</span><span>,</span><span>
</span><span>verbose</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>,</span><span>
</span><span>metric</span><span> </span><span>=</span><span> </span><span>&quot;ROC&quot;</span><span>,</span><span>
</span><span>trControl</span><span> </span><span>=</span><span> </span><span>ctrl</span><span>)</span><span>
</span><span># Examine results for test set
</span><span>
</span><span>model_list</span><span> </span><span>&lt;-</span><span> </span><span>list</span><span>(</span><span>original</span><span> </span><span>=</span><span> </span><span>orig_fit</span><span>,</span><span>
</span><span>weighted</span><span> </span><span>=</span><span> </span><span>weighted_fit</span><span>,</span><span>
</span><span>down</span><span> </span><span>=</span><span> </span><span>down_fit</span><span>,</span><span>
</span><span>up</span><span> </span><span>=</span><span> </span><span>up_fit</span><span>,</span><span>
</span><span>SMOTE</span><span> </span><span>=</span><span> </span><span>smote_fit</span><span>)</span></code></pre>
</figure>
<h2>Issues with using ROC for imbalanced classes</h2>
<p>While using the AUC as an evaluation metric for classifiers on data with imbalanced classes is a popular choice, it can be a misleading one if you are not careful. Take the following example from <a target="_blank" rel="nofollow" href="http://pages.cs.wisc.edu/~jdavis/davisgoadrichcamera2.pdf">Davis and Goadrich (2006)</a>. Below we see the model performance for two classifiers on an imbalanced dataset, with the ROC curve on the left and the precision-recall curve on the right. In the left example, the AUC for Curve 1 is reported in the paper as 0.813 and the AUC for Curve 2 is 0.875. So blindly choosing the best AUC value will choose Model 2 as the best. However, the precision-recall curve on the right tells a much different story. Here the area under Curve 1 is 0.513 and for Curve 2 it is 0.038. Due to Curve 1 having much better early retrieval compared to Curve 2, we see this massive discrepancy in the precision and recall performance between the two classifiers.</p>
<p><img alt="" src="https://i1.wp.com/dpmartin42.github.io/blogposts/r/figs/2017-01-03-imbalanced-classes-part-2/roc_pr_compare.PNG?w=456" data-recalc-dims="1"></p>
<p>Another example of how the ROC curve can be misleading comes from <a target="_blank" rel="nofollow" href="http://people.inf.elte.hu/kiss/11dwhdm/roc.pdf">Fawcett (2005)</a>. Here, we have two datasets, one that has perfect balance between two classes (1:1) and the other has moderate imbalance (10:1). The column on the left shows the ROC curves of two classifiers for both datasets being identical, with the classifier represented by the dashed line having better early retrieval than the classifier represented by the solid line. Again, the precision-recall curve displayed on the right highlights a large discrepancy in performance between the two classifiers on the two datasets. In the case of balanced classes, both classifiers have consistently good precision and recall performance across all thresholds. On the imbalanced data, however, the classifier with better early retrieval has much better precision for lower values of recall.</p>
<p><img alt="" src="https://i1.wp.com/dpmartin42.github.io/blogposts/r/figs/2017-01-03-imbalanced-classes-part-2/roc_pr_balance_imbalance.PNG?w=456" data-recalc-dims="1"></p>
<p>For these reasons, <a target="_blank" rel="nofollow" href="http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0118432">Saito and Rehmsmeier (2015)</a> recommend examining the precision-recall curve as it is more explicitly informative than a ROC curve in the case of imbalanced classes. We can calculate the area under the precision-recall curve for our 5 classifiers using the PRROC package in R to create a custom function, <code>calc_auprc</code>. Here, we see a similar story to what was found with the AUC metric in the <a target="_blank" rel="nofollow" href="http://dpmartin42.github.io/blogposts/r/imbalanced-classes-part-1">last blog post</a>; we have better performance for the weighted model, followed by the sampled models, with the original model coming in last. However, now the difference in performance is much more apparent.</p>
<figure>
<pre><code data-lang="r"><span>calc_auprc</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>model</span><span>,</span><span> </span><span>data</span><span>){</span><span>
</span><span>index_class2</span><span> </span><span>&lt;-</span><span> </span><span>data</span><span>$</span><span>Class</span><span> </span><span>==</span><span> </span><span>&quot;Class2&quot;</span><span>
</span><span>index_class1</span><span> </span><span>&lt;-</span><span> </span><span>data</span><span>$</span><span>Class</span><span> </span><span>==</span><span> </span><span>&quot;Class1&quot;</span><span>
</span><span>predictions</span><span> </span><span>&lt;-</span><span> </span><span>predict</span><span>(</span><span>model</span><span>,</span><span> </span><span>data</span><span>,</span><span> </span><span>type</span><span> </span><span>=</span><span> </span><span>&quot;prob&quot;</span><span>)</span><span>
</span><span>pr.curve</span><span>(</span><span>predictions</span><span>$</span><span>Class2</span><span>[</span><span>index_class2</span><span>],</span><span> </span><span>predictions</span><span>$</span><span>Class2</span><span>[</span><span>index_class1</span><span>],</span><span> </span><span>curve</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span><span>
</span><span>}</span><span>
</span><span># Get results for all 5 models
</span><span>
</span><span>model_list_pr</span><span> </span><span>&lt;-</span><span> </span><span>model_list</span><span> </span><span>%>%</span><span>
</span><span>map</span><span>(</span><span>calc_auprc</span><span>,</span><span> </span><span>data</span><span> </span><span>=</span><span> </span><span>imbal_test</span><span>)</span><span>
</span><span>model_list_pr</span><span> </span><span>%>%</span><span>
</span><span>map</span><span>(</span><span>function</span><span>(</span><span>the_mod</span><span>)</span><span> </span><span>the_mod</span><span>$</span><span>auc.integral</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## $original
## [1] 0.5271963
## 
## $weighted
## [1] 0.6463645
## 
## $down
## [1] 0.6293265
## 
## $up
## [1] 0.6459151
## 
## $SMOTE
## [1] 0.6195916</code></pre>
</figure>
<p>We can dig deeper into these results by actually plotting the precision-recall curves. Below, we see that both up sampling and weighting offer the best precision and recall performance depending on the threshold that is chosen, while the original classifier is essentially the worst performing across all thresholds. For example, the weighted classifier simultaneously has a recall of 75% and a precision of 50%, resulting in an F1 score of 0.6, while the original classifier has a recall of 75% and a precision of 25%, resulting in an F1 score of 0.38. In other words, when both classifiers create their predictions and use a particular threshold to obtain hard classifications, they both correctly identify 75% of the cases that are actually in the minority class. However, the weighted classifier is more efficient in these predictions, in that 50% of the observations predicted to be in the minority class actually are, while for the original classifier, only 25% of the observations predicted to be in the minority class actually are.</p>
<figure>
<pre><code data-lang="r"><span># Plot the AUPRC curve for all 5 models
</span><span>
</span><span>results_list_pr</span><span> </span><span>&lt;-</span><span> </span><span>list</span><span>(</span><span>NA</span><span>)</span><span>
</span><span>num_mod</span><span> </span><span>&lt;-</span><span> </span><span>1</span><span>
</span><span>for</span><span>(</span><span>the_pr</span><span> </span><span>in</span><span> </span><span>model_list_pr</span><span>){</span><span>
</span><span>results_list_pr</span><span>[[</span><span>num_mod</span><span>]]</span><span> </span><span>&lt;-</span><span> </span><span>data_frame</span><span>(</span><span>recall</span><span> </span><span>=</span><span> </span><span>the_pr</span><span>$</span><span>curve</span><span>[,</span><span> </span><span>1</span><span>],</span><span>
</span><span>precision</span><span> </span><span>=</span><span> </span><span>the_pr</span><span>$</span><span>curve</span><span>[,</span><span> </span><span>2</span><span>],</span><span>
</span><span>model</span><span> </span><span>=</span><span> </span><span>names</span><span>(</span><span>model_list_pr</span><span>)[</span><span>num_mod</span><span>])</span><span>
</span><span>num_mod</span><span> </span><span>&lt;-</span><span> </span><span>num_mod</span><span> </span><span>+</span><span> </span><span>1</span><span>
</span><span>}</span><span>
</span><span>results_df_pr</span><span> </span><span>&lt;-</span><span> </span><span>bind_rows</span><span>(</span><span>results_list_pr</span><span>)</span><span>
</span><span>custom_col</span><span> </span><span>&lt;-</span><span> </span><span>c</span><span>(</span><span>&quot;#000000&quot;</span><span>,</span><span> </span><span>&quot;#009E73&quot;</span><span>,</span><span> </span><span>&quot;#0072B2&quot;</span><span>,</span><span> </span><span>&quot;#D55E00&quot;</span><span>,</span><span> </span><span>&quot;#CC79A7&quot;</span><span>)</span><span>
</span><span>ggplot</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>recall</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>precision</span><span>,</span><span> </span><span>group</span><span> </span><span>=</span><span> </span><span>model</span><span>),</span><span> </span><span>data</span><span> </span><span>=</span><span> </span><span>results_df_pr</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>model</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>1</span><span>)</span><span> </span><span>+</span><span>
</span><span>scale_color_manual</span><span>(</span><span>values</span><span> </span><span>=</span><span> </span><span>custom_col</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_abline</span><span>(</span><span>intercept</span><span> </span><span>=</span><span> </span><span>sum</span><span>(</span><span>imbal_test</span><span>$</span><span>Class</span><span> </span><span>==</span><span> </span><span>&quot;Class2&quot;</span><span>)</span><span>/</span><span>nrow</span><span>(</span><span>imbal_test</span><span>),</span><span>
</span><span>slope</span><span> </span><span>=</span><span> </span><span>0</span><span>,</span><span> </span><span>color</span><span> </span><span>=</span><span> </span><span>&quot;gray&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>1</span><span>)</span><span> </span><span>+</span><span>
</span><span>theme_bw</span><span>()</span></code></pre>
</figure>
<p><img alt="center" src="https://i2.wp.com/dpmartin42.github.io/figs/2017-01-03-imbalanced-classes-part-2/unnamed-chunk-3-1.png?w=456" data-recalc-dims="1"></p>
<h2>Implementing the area under the precision-recall curve metric in caret</h2>
<p>One might imagine wanting to choose hyperparameters of a classifier by using the area under the precision-recall curve rather than the AUC, as some combinations of hyperparameters for a given model might have better early retrieval performance compared to others. It is incredibly easy to create a custom summary function in caret to allow you to do this by combining the code for the <code>calc_auprc</code> function with <a target="_blank" rel="nofollow" href="https://topepo.github.io/caret/model-training-and-tuning.html#metrics">these instructions</a> found in the caret documentation.</p>
<p>This custom summary function is implemented below, along with code to re-run the original model now using area under the precision-recall curve as the evaluation metric. Here, we see that the original model implementation has the exact same results on the test set for the area under the PR curve, regardless of whether we build the model using the area under the ROC curve or the area under the precision-recall curve. This is because both select the same combination of hyperparameters to build the final model on. Note that this may not always be the case, especially if you decide to use the <a target="_blank" rel="nofollow" href="http://www.stat.cmu.edu/~ryantibs/datamining/lectures/19-val2-marked.pdf">1-SE</a> rule when choosing the hyperparameters in order to encourage a more parsimonious solution.</p>
<figure>
<pre><code data-lang="r"><span>auprcSummary</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>data</span><span>,</span><span> </span><span>lev</span><span> </span><span>=</span><span> </span><span>NULL</span><span>,</span><span> </span><span>model</span><span> </span><span>=</span><span> </span><span>NULL</span><span>){</span><span>
</span><span>index_class2</span><span> </span><span>&lt;-</span><span> </span><span>data</span><span>$</span><span>obs</span><span> </span><span>==</span><span> </span><span>&quot;Class2&quot;</span><span>
</span><span>index_class1</span><span> </span><span>&lt;-</span><span> </span><span>data</span><span>$</span><span>obs</span><span> </span><span>==</span><span> </span><span>&quot;Class1&quot;</span><span>
</span><span>the_curve</span><span> </span><span>&lt;-</span><span> </span><span>pr.curve</span><span>(</span><span>data</span><span>$</span><span>Class2</span><span>[</span><span>index_class2</span><span>],</span><span> </span><span>data</span><span>$</span><span>Class2</span><span>[</span><span>index_class1</span><span>],</span><span> </span><span>curve</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span><span>out</span><span> </span><span>&lt;-</span><span> </span><span>the_curve</span><span>$</span><span>auc.integral</span><span>
</span><span>names</span><span>(</span><span>out</span><span>)</span><span> </span><span>&lt;-</span><span> </span><span>&quot;AUPRC&quot;</span><span>
</span><span>out</span><span>
</span><span>}</span><span>
</span><span># Re-initialize control function to remove smote and
# include our new summary function
</span><span>
</span><span>ctrl</span><span> </span><span>&lt;-</span><span> </span><span>trainControl</span><span>(</span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;repeatedcv&quot;</span><span>,</span><span>
</span><span>number</span><span> </span><span>=</span><span> </span><span>10</span><span>,</span><span>
</span><span>repeats</span><span> </span><span>=</span><span> </span><span>5</span><span>,</span><span>
</span><span>summaryFunction</span><span> </span><span>=</span><span> </span><span>auprcSummary</span><span>,</span><span>
</span><span>classProbs</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>,</span><span>
</span><span>seeds</span><span> </span><span>=</span><span> </span><span>orig_fit</span><span>$</span><span>control</span><span>$</span><span>seeds</span><span>)</span><span>
</span><span>orig_pr</span><span> </span><span>&lt;-</span><span> </span><span>train</span><span>(</span><span>Class</span><span> </span><span>~</span><span> </span><span>.</span><span>,</span><span>
</span><span>data</span><span> </span><span>=</span><span> </span><span>imbal_train</span><span>,</span><span>
</span><span>method</span><span> </span><span>=</span><span> </span><span>&quot;gbm&quot;</span><span>,</span><span>
</span><span>verbose</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>,</span><span>
</span><span>metric</span><span> </span><span>=</span><span> </span><span>&quot;AUPRC&quot;</span><span>,</span><span>
</span><span>trControl</span><span> </span><span>=</span><span> </span><span>ctrl</span><span>)</span><span>
</span><span># Get results for auprc on the test set
</span><span>
</span><span>orig_fit_test</span><span> </span><span>&lt;-</span><span> </span><span>orig_fit</span><span> </span><span>%>%</span><span>
</span><span>calc_auprc</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>imbal_test</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>(</span><span>function</span><span>(</span><span>the_mod</span><span>)</span><span> </span><span>the_mod</span><span>$</span><span>auc.integral</span><span>)</span><span>
</span><span>orig_pr_test</span><span> </span><span>&lt;-</span><span> </span><span>orig_pr</span><span> </span><span>%>%</span><span>
</span><span>calc_auprc</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>imbal_test</span><span>)</span><span> </span><span>%>%</span><span>
</span><span>(</span><span>function</span><span>(</span><span>the_mod</span><span>)</span><span> </span><span>the_mod</span><span>$</span><span>auc.integral</span><span>)</span><span>
</span><span># The test errors are the same
</span><span>
</span><span>identical</span><span>(</span><span>orig_fit_test</span><span>,</span><span>
</span><span>orig_pr_test</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## [1] TRUE</code></pre>
</figure>
<figure>
<pre><code data-lang="r"><span># Because both chose the same
# hyperparameter combination
</span><span>
</span><span>identical</span><span>(</span><span>orig_fit</span><span>$</span><span>bestTune</span><span>,</span><span>
</span><span>orig_pr</span><span>$</span><span>bestTune</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## [1] TRUE</code></pre>
</figure>
<h2>Final thoughts</h2>
<p>The area under the precision-recall curve can be a useful metric to help differentiate between two competing models in the case of imbalanced classes. For the AUC, weights and sampling techniques may only provide modest improvements. However, this improvement typically impacts early retrieval performance, resulting in a much larger gain in the overall precision of a model. In conjunction with trying weighting or sampling, it is also recommended to avoid relying solely on the AUC when evaluating the performance of a classifier that has imbalanced classes as it can be a misleading metric. The code above shows how easy it is to use the precision-recall curve, a more sensitive measure of classification performance when there are imbalanced classes.</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://dpmartin42.github.io/blogposts/r/imbalanced-classes-part-2"> Wicked Good Data - r</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/9FUQcEO0Izs"></a></div>