<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>roc on Everyday Is A School Day</title>
    <link>https://www.kenkoonwong.com/tags/roc/</link>
    <description>Recent content in roc on Everyday Is A School Day</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Wed, 02 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.kenkoonwong.com/tags/roc/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>ROC, Paper, Scissor, Shoe</title>
      <link>https://www.kenkoonwong.com/blog/roc-auc-dca/</link>
      <pubDate>Wed, 02 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://www.kenkoonwong.com/blog/roc-auc-dca/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;📊 Working through ROC-AUC from scratch, then poking at its blind spots — low prevalence, calibration, and finally Decision Curve Analysis. Mostly notes to myself on what I learned (and got confused by) along the way. 🤔📈&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2 id=&#34;motivations&#34;&gt;Motivations
  &lt;a href=&#34;#motivations&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;We see ROC-AUC so often with classification models, we know the higher the better, but there is always that, well it depends scenario. I&amp;rsquo;ve always wanted to know what the pitfall is, how to avoid it, and how to do better. Let&amp;rsquo;s go from the basics on how to code ROC-AUC from scratch to decision curve analysis!&lt;/p&gt;




&lt;h2 id=&#34;objectives&#34;&gt;Objectives:
  &lt;a href=&#34;#objectives&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&#34;#what&#34;&gt;What is ROC, why we use it?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;#calc&#34;&gt;How To Calculate ROC from Scratch?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;#pitfall&#34;&gt;Pitfall of ROC-AUC&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&#34;#sim-lowprev&#34;&gt;Low Prevalence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;#miscal&#34;&gt;Miscalibration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;#dca&#34;&gt;Decision Curve Analysis&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&#34;#auc&#34;&gt;AUC for both models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;#brier&#34;&gt;Brier score&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;#cox&#34;&gt;Cox calibration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;#dca2&#34;&gt;Decision Curve Analysis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;#opportunities&#34;&gt;Opportunities For Improvement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;#lessons&#34;&gt;Lessons Learnt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2 id=&#34;what&#34;&gt;What is ROC, Why We Use It
  &lt;a href=&#34;#what&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Receiver Operating Characteristic (ROC) Curve is a plot that shows the performance of a binary classification model. The y-axis consists of &lt;code&gt;Sensitivity&lt;/code&gt; (True positive rate), and the x-axis consists of &lt;code&gt;1 - Specificity&lt;/code&gt; (aka false positive rate).  ROC curve is obtained as the cdf of the detection probability in the y-axis vs the cdf of x-axis (false positivity rate). It was first developed by electrical and radar engineers during World War II for detecting enemy objects in battlefields, starting in 1941, which led to its name. Since then it has been widely introduced to other fields. This tool is used for its convenience, interpretability and also models comparison, hence the wide adoption of this metric. 
&lt;a href=&#34;https://en.wikipedia.org/wiki/Receiver_operating_characteristic&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;wiki link&lt;/a&gt;. Alright, enough of the history, let&amp;rsquo;s move on to the next section.&lt;/p&gt;




&lt;h2 id=&#34;calc&#34;&gt;How To Calculate ROC from Scratch
  &lt;a href=&#34;#calc&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h2&gt;




&lt;h3 id=&#34;sim&#34;&gt;Simulate Data
  &lt;a href=&#34;#sim&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;library&lt;/span&gt;(tidyverse)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;set.seed&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;n_neg &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;15&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;n_pos &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;15&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;score_neg &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;rnorm&lt;/span&gt;(n_neg, mean &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;3&lt;/span&gt;, sd &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;score_pos &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;rnorm&lt;/span&gt;(n_pos, mean &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;5&lt;/span&gt;, sd &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  y_true  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;rep&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;, n_neg), &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;rep&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;, n_pos)), 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  y_score &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(score_neg, score_pos))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3 id=&#34;procedure&#34;&gt;Procedure for ROC
  &lt;a href=&#34;#procedure&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h3&gt;




&lt;h4 id=&#34;step-1-sort-the-predicted-scores-in-descending-order-and-assign-a-threshold-for-each-unique-score&#34;&gt;Step 1: Sort the predicted scores in descending order and assign a threshold for each unique score.
  &lt;a href=&#34;#step-1-sort-the-predicted-scores-in-descending-order-and-assign-a-threshold-for-each-unique-score&#34;&gt;&lt;/a&gt;
&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;threshold_vec &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;arrange&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;desc&lt;/span&gt;(y_score)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;pull&lt;/span&gt;(y_score)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3 id=&#34;step-2-for-each-threshold-calculate-the-true-positive-rate-tpr-and-false-positive-rate-fpr&#34;&gt;Step 2: For each threshold, calculate the True Positive Rate (TPR) and False Positive Rate (FPR).
  &lt;a href=&#34;#step-2-for-each-threshold-calculate-the-true-positive-rate-tpr-and-false-positive-rate-fpr&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# we&amp;#39;ll use for loop here for better understanding&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;true_pos_vec &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; false_pos_vec &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;vector&lt;/span&gt;(mode &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;numeric&amp;#34;&lt;/span&gt;, length &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;length&lt;/span&gt;(threshold_vec))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;for &lt;/span&gt;(i in &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;length&lt;/span&gt;(threshold_vec)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  tp_sum &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fp_sum &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;for &lt;/span&gt;(j in &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;nrow&lt;/span&gt;(df)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    y_true_j &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; df[[j, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;y_true&amp;#34;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    y_score_j &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; df[[j, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;y_score&amp;#34;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;if &lt;/span&gt;(y_score_j &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;=&lt;/span&gt; threshold_vec[i] &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt; y_true_j &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;) { tp_sum &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; tp_sum &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;if &lt;/span&gt;(y_score_j &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;=&lt;/span&gt; threshold_vec[i] &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt; y_true_j &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;) { fp_sum &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; fp_sum &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  true_pos_vec[i] &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; tp_sum
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  false_pos_vec[i] &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; fp_sum
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;df_auc &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;arrange&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;desc&lt;/span&gt;(y_score)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(tp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; true_pos_vec,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         fp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; false_pos_vec,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         fn &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;sum&lt;/span&gt;(y_true &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; tp,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         tn &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;sum&lt;/span&gt;(y_true &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; fp,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         tpr &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; tp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt; (tp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; fn),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         fpr &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; fp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt; (fp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; tn))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;df_auc &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ggplot&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; fpr, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; tpr)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_point&lt;/span&gt;() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_line&lt;/span&gt;() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;theme_bw&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-3-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;p&gt;Alright, the above is just a for loop that looks at all of the predicted scores and calculates the true positive rate and false positive rate for each threshold. The ROC curve is then plotted using ggplot2. Now let&amp;rsquo;s add up all the rectangles to calculate ROC-AUC.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;df_auc &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(test &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;abs&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;lag&lt;/span&gt;(fpr, default &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; fpr),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         area &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; test &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt; tpr) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(auc &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;sum&lt;/span&gt;(area)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;distinct&lt;/span&gt;(auc) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;pull&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## [1] 0.9333333
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Woo hoo! ROC-AUC is 0.93! Awesome!&lt;/p&gt;
&lt;p&gt;OK, so what if we were able to calculate ROC-AUC? Is it a good metric to evaluate model performance? In comes &lt;code&gt;Youden-J&lt;/code&gt; index, which is a metric that is used to find the optimal threshold for a binary classification model. It is defined as &lt;code&gt;Youden-J = Sensitivity + Specificity - 1&lt;/code&gt;. The optimal threshold is the one that maximizes Youden-J. Let&amp;rsquo;s calculate it along with sens, spec, ppv, and npv.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;df_optimal &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; df_auc &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    spec &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; fpr,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ppv &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; tp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt; (tp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; fp),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    npv &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; tn &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt; (tn &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; fn),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    J &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; tpr &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; spec &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;arrange&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;desc&lt;/span&gt;(J)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;head&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;paste0&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;J: &amp;#34;&lt;/span&gt;, df_optimal&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;J, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;; sensitivity: &amp;#34;&lt;/span&gt;, df_optimal&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;tpr &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;round&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;), &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;; specificity: &amp;#34;&lt;/span&gt;, df_optimal&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;spec &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;round&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;), &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;; ppv: &amp;#34;&lt;/span&gt;, df_optimal&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;ppv &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;round&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;), &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;; npv: &amp;#34;&lt;/span&gt;,df_optimal&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;npv &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;round&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## [1] &amp;#34;J: 0.8; sensitivity: 0.8; specificity: 1; ppv: 1; npv: 0.83&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alright! Looks pretty good! We have nice looking ROC-AUC along with nice looking ppv and npv! lol, yes &amp;ldquo;nice looking&amp;rdquo; is an official statistical term 🤣 Now that we have seen the ROC-AUC and Youden-J index, let&amp;rsquo;s simulate a scenario where we have low prevalence and low sample size to see how it affects the ROC-AUC and Youden-J index.&lt;/p&gt;




&lt;h2 id=&#34;pitfall&#34;&gt;Pitfall of ROC-AUC
  &lt;a href=&#34;#pitfall&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h2&gt;




&lt;h3 id=&#34;sim-lowprev&#34;&gt;Simulate Low Prevalence
  &lt;a href=&#34;#sim-lowprev&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;We&amp;rsquo;re going to set &lt;code&gt;n_neg to 99&lt;/code&gt; and &lt;code&gt;n_pos to 1&lt;/code&gt;, with the same code as above. Let&amp;rsquo;s look at the curve, AUC, and the metrics
&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-6-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## [1] &amp;#34;ROC-AUC: 0.94949494949495&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## [1] &amp;#34;J: 0.95; sensitivity: 1; specificity: 0.95; ppv: 0.17; npv: 1&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Holy cow, notice how great AUC, sens, and spec are but look at ppv! Do we want a test like that and have a bunch of false positives? I don&amp;rsquo;t think so. This is a classic example of how ROC-AUC can be misleading in low prevalence scenarios.&lt;/p&gt;




&lt;h3 id=&#34;miscal&#34;&gt;Miscalibration
  &lt;a href=&#34;#miscal&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Now, let&amp;rsquo;s look at another scenario where we have a well-calibrated model, a biased model, an overconfident model, and an underconfident model. We&amp;rsquo;ll simulate 3000 samples and look at the ROC-AUC and calibration curves.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;code&lt;/summary&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;library&lt;/span&gt;(tidyverse)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;set.seed&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;n &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;true_logit &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;rnorm&lt;/span&gt;(n)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;true_prob  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plogis&lt;/span&gt;(true_logit)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;y_true     &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;rbinom&lt;/span&gt;(n, &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;, true_prob)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(y_true, true_logit) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pred_wellcal    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plogis&lt;/span&gt;(true_logit),           &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# reference: correct&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pred_biased     &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plogis&lt;/span&gt;(true_logit &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1.0&lt;/span&gt;),      &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# intercept shift -&amp;gt; BIAS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pred_overconf   &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plogis&lt;/span&gt;(true_logit &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;3&lt;/span&gt;),        &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# slope shrink -&amp;gt; MISCALIBRATION&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pred_underconf  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plogis&lt;/span&gt;(true_logit &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.4&lt;/span&gt;)       &lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# slope stretch -&amp;gt; MISCALIBRATION&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;library&lt;/span&gt;(pROC)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;roc_wellcal   &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;roc&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_wellcal,   quiet &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;TRUE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;roc_biased    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;roc&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_biased,    quiet &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;TRUE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;roc_overconf  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;roc&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_overconf,  quiet &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;TRUE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;roc_underconf &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;roc&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_underconf, quiet &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;TRUE&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  model &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;wellcal&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;biased&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;overconf&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;underconf&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  auc   &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;auc&lt;/span&gt;(roc_wellcal), &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;auc&lt;/span&gt;(roc_biased), &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;auc&lt;/span&gt;(roc_overconf), &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;auc&lt;/span&gt;(roc_underconf))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 4 × 2
##   model       auc
##   &amp;lt;chr&amp;gt;     &amp;lt;dbl&amp;gt;
## 1 wellcal   0.740
## 2 biased    0.740
## 3 overconf  0.740
## 4 underconf 0.740
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ggroc&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;list&lt;/span&gt;(wellcal &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; roc_wellcal, biased &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; roc_biased,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           overconf &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; roc_overconf, underconf &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; roc_underconf)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;theme_bw&lt;/span&gt;() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;labs&lt;/span&gt;(title &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Identical ROC curves despite very different calibration&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-7-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;/details&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 4 × 2
##   model       auc
##   &amp;lt;chr&amp;gt;     &amp;lt;dbl&amp;gt;
## 1 wellcal   0.740
## 2 biased    0.740
## 3 overconf  0.740
## 4 underconf 0.740
&lt;/code&gt;&lt;/pre&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-8-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;p&gt;Notice how a point estimate of ROC-AUC and the curve hide the fact that the models are very different in terms of calibration. Let&amp;rsquo;s look at the calibration curves for each model.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Interesting note that I didn&amp;rsquo;t know bias is a shift in the intercept and miscalibration is a shift in the slope. I always thought they&amp;rsquo;re all bias.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;details&gt;
&lt;summary&gt;code&lt;/summary&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calibration_data &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;function&lt;/span&gt;(pred, y, model_name, n_bins &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;10&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(pred &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; pred, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; y) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(bin &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ntile&lt;/span&gt;(pred, n_bins)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;group_by&lt;/span&gt;(bin) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;summarise&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      mean_pred &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mean&lt;/span&gt;(pred), 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      observed_rate &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mean&lt;/span&gt;(y), 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      n &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;n&lt;/span&gt;(), .groups &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;drop&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(model &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; model_name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cal_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;bind_rows&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;calibration_data&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_wellcal,   df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;wellcal&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;calibration_data&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_biased,    df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;biased&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;calibration_data&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_overconf,  df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;overconf&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;calibration_data&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_underconf, df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;underconf&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cal_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ggplot&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; mean_pred, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; observed_rate, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; model)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_point&lt;/span&gt;(size &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_line&lt;/span&gt;() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_abline&lt;/span&gt;(slope &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;, intercept &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;, linetype &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;dashed&amp;#34;&lt;/span&gt;, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;gray40&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;coord_equal&lt;/span&gt;(xlim &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;), ylim &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;labs&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Mean predicted probability&amp;#34;&lt;/span&gt;, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Observed event rate&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       title &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Same ROC-AUC, four very different calibration curves&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;theme_bw&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-9-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;/details&gt;
&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-10-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;p&gt;Very quickly, a visual heuristic of looking at calibration curve is you want your model&amp;rsquo;s prediction frequency on average to be close to the observed frequency. If your model is overconfident, it will be above the diagonal line, and if your model is underconfident, it will be below the diagonal line. If your model is biased, it will be shifted to the left or right of the diagonal line. How we get here is by binning the predicted probabilities into 10 bins and then calculate the mean predicted probability and the mean observed event rate for each bin. A well-calibrated model will have the mean predicted probability close to the mean observed event rate for each bin.&lt;/p&gt;
&lt;p&gt;A quick visual of the above, you see that the well-calibrated model is close to the diagonal line, the biased model is shifted to the right (only intercept changed), the overconfident model is above the diagonal line (slope reduced), and the underconfident model is below the diagonal line (slope increased).&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see if we can fit a logistic regression model to see if we can quantify the calibration of each model. We will fit a logistic regression model with the predicted probabilities as the independent variable and the true labels as the dependent variable. The intercept and slope of the fitted model will give us an idea of how well-calibrated the model is.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note to self: Apparently this is called Cox calibration, which is a method to assess the calibration of a model by fitting a logistic regression model with the predicted probabilities as the independent variable and the true labels as the dependent variable. The intercept and slope of the fitted model will give us an idea of how well-calibrated the model is. A well-calibrated model will have an intercept close to 0 and a slope close to 1. A biased model will have an intercept that is not close to 0, and a miscalibrated model will have a slope that is not close to 1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;details&gt;
&lt;summary&gt;code&lt;/summary&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cox_calib &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;function&lt;/span&gt;(y, p) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  logit_p &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;qlogis&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;pmin&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;pmax&lt;/span&gt;(p, &lt;span style=&#34;color:#099&#34;&gt;1e-6&lt;/span&gt;), &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1e-6&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fit &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;glm&lt;/span&gt;(y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;~&lt;/span&gt; logit_p, family &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; binomial)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(intercept_a &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;coef&lt;/span&gt;(fit)[1], slope_b &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;coef&lt;/span&gt;(fit)[2])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;bind_rows&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  wellcal   &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;cox_calib&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_wellcal),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  biased    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;cox_calib&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_biased),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  overconf  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;cox_calib&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_overconf),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  underconf &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;cox_calib&lt;/span&gt;(df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_underconf),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  .id &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;model&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 4 × 3
##   model     intercept_a slope_b
##   &amp;lt;chr&amp;gt;           &amp;lt;dbl&amp;gt;   &amp;lt;dbl&amp;gt;
## 1 wellcal       0.00597   0.958
## 2 biased       -0.952     0.958
## 3 overconf      0.00597   0.319
## 4 underconf     0.00597   2.39
&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 4 × 3
##   model     intercept_a slope_b
##   &amp;lt;chr&amp;gt;           &amp;lt;dbl&amp;gt;   &amp;lt;dbl&amp;gt;
## 1 wellcal       0.00597   0.958
## 2 biased       -0.952     0.958
## 3 overconf      0.00597   0.319
## 4 underconf     0.00597   2.39
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Look at that! Here is another interesting bit, notice how the slope for over and under confident model is reciprocal of the &amp;ldquo;simulated&amp;rdquo; (ok not really simulated, more like specified miscalibration) from the data we generated? If we dwell on the thought process of it, it makes sense, because for overconfident model, the way we miscalibrated is by multipling 3x to the logit and then we simulate it with binomial distribution. So we&amp;rsquo;re pushing the logits closer to positive and negative infinity which makes the predicted probabilities closer to 0 and 1. When we fit a logistic regression model to the predicted probabilities and the true labels, we&amp;rsquo;re essentially trying to find the best fit line that maps the predicted probabilities to the true labels. Since the predicted probabilities are pushed closer to 0 and 1, the slope of the fitted line will be less than 1, which is what we see in the output. Similarly, for the underconfident model, we&amp;rsquo;re pushing the logits closer to 0, which makes the predicted probabilities closer to 0.5. When we fit a logistic regression model to the predicted probabilities and the true labels, we&amp;rsquo;re essentially trying to find the best fit line that maps the predicted probabilities to the true labels. Since the predicted probabilities are pushed closer to 0.5, the slope of the fitted line will be greater than 1, which is what we see in the output. Let&amp;rsquo;s visualize the logit lines and the curves&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;code&lt;/summary&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;plot_line &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;function&lt;/span&gt;(df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; df, pred_col, model_name) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  form &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;as.formula&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;paste0&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;y_true ~ qlogis(&amp;#34;&lt;/span&gt;, pred_col, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;)&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  model &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;glm&lt;/span&gt;(form, data &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; df, family &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; binomial)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      pred_logit_x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;qlogis&lt;/span&gt;(.data[[pred_col]]),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      pred_logit_y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;predict&lt;/span&gt;(model, newdata &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; df, type &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;link&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ggplot&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; pred_logit_x, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; pred_logit_y)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_point&lt;/span&gt;() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_line&lt;/span&gt;(color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;blue&amp;#34;&lt;/span&gt;, linewidth &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_abline&lt;/span&gt;(slope &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;, intercept &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;, linetype &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;dashed&amp;#34;&lt;/span&gt;, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;gray40&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;labs&lt;/span&gt;(title &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;paste&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Calibration plot for&amp;#34;&lt;/span&gt;, model_name),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Logit of predicted probability&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Logit of observed probability&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;xlim&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;-2.5&lt;/span&gt;, &lt;span style=&#34;color:#099&#34;&gt;2.5&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ylim&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;-5&lt;/span&gt;, &lt;span style=&#34;color:#099&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;theme_bw&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;library&lt;/span&gt;(patchwork)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p1 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plot_line&lt;/span&gt;(df, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pred_wellcal&amp;#34;&lt;/span&gt;,   &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Well-calibrated Model&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p2 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plot_line&lt;/span&gt;(df, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pred_biased&amp;#34;&lt;/span&gt;,    &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Biased Model&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p3 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plot_line&lt;/span&gt;(df, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pred_overconf&amp;#34;&lt;/span&gt;,  &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Overconfident Model&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p4 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plot_line&lt;/span&gt;(df, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pred_underconf&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Underconfident Model&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(p1 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; p2) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt; (p3 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; p4)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-13-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;/details&gt;
&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-14-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;p&gt;There you go! Let&amp;rsquo;s look at the curves&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;code&lt;/summary&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;plot_line &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;function&lt;/span&gt;(df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; df, pred_col, model_name) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  form &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;as.formula&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;paste0&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;y_true ~ qlogis(&amp;#34;&lt;/span&gt;, pred_col, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;)&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  model &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;glm&lt;/span&gt;(form, data &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; df, family &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; binomial)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  plot_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      x_val &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; .data[[pred_col]],                            
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      fitted_prob &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;predict&lt;/span&gt;(model, newdata &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; df, type &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;response&amp;#34;&lt;/span&gt;)  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  plot_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ggplot&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; x_val)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_point&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; y_true),alpha&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#099&#34;&gt;0.1&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_line&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; fitted_prob), color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;blue&amp;#34;&lt;/span&gt;, linewidth &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;suppressWarnings&lt;/span&gt;() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_abline&lt;/span&gt;(slope &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;, intercept &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;, linetype &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;dashed&amp;#34;&lt;/span&gt;, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;gray40&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;labs&lt;/span&gt;(title &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;paste&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Calibration curve for&amp;#34;&lt;/span&gt;, model_name),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;paste0&lt;/span&gt;(pred_col, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34; (predicted probability)&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;P(y = 1)&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;xlim&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;theme_bw&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p1 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plot_line&lt;/span&gt;(df, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pred_wellcal&amp;#34;&lt;/span&gt;,   &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Well-calibrated Model&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p2 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plot_line&lt;/span&gt;(df, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pred_biased&amp;#34;&lt;/span&gt;,    &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Biased Model&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p3 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plot_line&lt;/span&gt;(df, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pred_overconf&amp;#34;&lt;/span&gt;,  &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Overconfident Model&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p4 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plot_line&lt;/span&gt;(df, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;pred_underconf&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Underconfident Model&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(p1 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; p2) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt; (p3 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; p4)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-15-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;/details&gt;
&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-16-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;p&gt;Wow, I don&amp;rsquo;t think I&amp;rsquo;ve visualized the curve before. This is interesting! Visualizing the calibration plot is very important to assess the calibration of a model. Now, let&amp;rsquo;s look at &lt;code&gt;brier score = mean((p - y)^2)&lt;/code&gt; which is a metric that is used to assess the calibration of a model. The lower the brier score, the better the calibration of the model. Let&amp;rsquo;s calculate the brier score for each model.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;code&lt;/summary&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 4 × 2
##   model     brier
##   &amp;lt;chr&amp;gt;     &amp;lt;dbl&amp;gt;
## 1 wellcal   0.207
## 2 biased    0.245
## 3 overconf  0.237
## 4 underconf 0.219
&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 4 × 2
##   model     brier
##   &amp;lt;chr&amp;gt;     &amp;lt;dbl&amp;gt;
## 1 wellcal   0.207
## 2 biased    0.245
## 3 overconf  0.237
## 4 underconf 0.219
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The score itself is not very interpretable, but it is a good metric to compare different models. The lower the brier score, the better the calibration of the model.&lt;/p&gt;




&lt;h2 id=&#34;dca&#34;&gt;Decision Curve Analysis
  &lt;a href=&#34;#dca&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;So far we&amp;rsquo;ve seen that ROC-AUC can be identical across models that are wildly different once you look at calibration. But there&amp;rsquo;s still a gap: even a perfect calibration plot doesn&amp;rsquo;t tell you whether using the model to make a decision is actually worth it. That&amp;rsquo;s what Decision Curve Analysis (DCA) is for.
The core idea: every prediction model implies a decision rule — &amp;ldquo;if predicted risk ≥ some threshold pt, act (treat/test/intervene).&amp;rdquo; Different thresholds represent different tolerances for false positives vs. false negatives. DCA calculates a net benefit at each threshold and compares your model against two naive strategies: treat everyone and treat no one. &lt;code&gt;Net Benefit = True positive / n - (False positive / n) * (threshold / (1 - threshold))&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note to self: the threshold/(1-threshold) term is also known as exchange rate — expressed in &amp;ldquo;true-positive-equivalents per patient&amp;rdquo; — a net benefit of 0.30 means &amp;ldquo;using this strategy nets you the equivalent of 30 true cases correctly identified per 100 patients, after subtracting the harm-weighted cost of the false positives it also generates.&amp;rdquo; It&amp;rsquo;s not a percentage and it&amp;rsquo;s not meaningful in isolation — it only means something compared against another curve at the same threshold. It&amp;rsquo;s called true-positive-equivalent because it can either be additional true positive, or less false positive, or a combination of both.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Alright, let&amp;rsquo;s have Claude generate a simulation of non-linear DGP and see if tuned xgboost does better than logistic regression. We will assess the AUCs, calibration curve, brier score, and then we&amp;rsquo;ll DCA this thing comparing xgboost and LR.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s assume that this is some model that predicts a condition which may need to receive some kind of intervention that is not too invasive or too costly.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;code&lt;/summary&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;library&lt;/span&gt;(tidyverse)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;library&lt;/span&gt;(xgboost)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;library&lt;/span&gt;(pROC)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;set.seed&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;n &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# ---- 1. Simulate nonlinear truth ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;x1 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;rnorm&lt;/span&gt;(n)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;x2 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;rnorm&lt;/span&gt;(n)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;true_logit &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.8&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;x1^2 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1.2&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;x2 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1.5&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;sin&lt;/span&gt;(x1&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;x2) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;true_prob  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;plogis&lt;/span&gt;(true_logit)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;y_true     &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;rbinom&lt;/span&gt;(n, &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;, true_prob)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(y_true, x1, x2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# ---- 2. Train/test split ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;idx &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;sample&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;n, &lt;span style=&#34;color:#099&#34;&gt;0.7&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt;n)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;train &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; df[idx, ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;test  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; df[&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;idx, ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# ---- 3. Logistic regression (misspecified: linear terms only) ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;log_model &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;glm&lt;/span&gt;(y_true &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;~&lt;/span&gt; x1 &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; x2, data &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; train, family &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; binomial)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_logit &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;predict&lt;/span&gt;(log_model, newdata &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; test, type &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;response&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# ---- 4. Tuned XGBoost ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dtrain &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;xgb.DMatrix&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;as.matrix&lt;/span&gt;(train[, &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;x1&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;x2&amp;#34;&lt;/span&gt;)]), label &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; train&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dtest  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;xgb.DMatrix&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;as.matrix&lt;/span&gt;(test[,  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;x1&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;x2&amp;#34;&lt;/span&gt;)]))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cv &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;xgb.cv&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  params &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;list&lt;/span&gt;(objective &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;binary:logistic&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                max_depth &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt;, eta &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.05&lt;/span&gt;, subsample &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.8&lt;/span&gt;, colsample_bytree &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.8&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  data &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; dtrain,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  nrounds &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;500&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  nfold &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;5&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  metrics &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;logloss&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  early_stopping_rounds &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;20&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  maximize &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;FALSE&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  verbose &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;best_nrounds &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; cv&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;best_iteration
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# Fallback: manually find best round from the CV log if best_iteration is missing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;best_nrounds &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; cv&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;evaluation_log &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;slice_min&lt;/span&gt;(test_logloss_mean, n &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;pull&lt;/span&gt;(iter)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;print&lt;/span&gt;(best_nrounds)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## [1] 110
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;xgb_model &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;xgb.train&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  params &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;list&lt;/span&gt;(objective &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;binary:logistic&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                max_depth &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;4&lt;/span&gt;, eta &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.05&lt;/span&gt;, subsample &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.8&lt;/span&gt;, colsample_bytree &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.8&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  data &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; dtrain,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  nrounds &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; best_nrounds,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  verbose &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_xgb &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;predict&lt;/span&gt;(xgb_model, dtest)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# ---- 5. AUC ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;auc_tbl &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  model &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;logistic&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;xgboost&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  auc &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;auc&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;roc&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_logit, quiet &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;TRUE&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;auc&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;roc&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_xgb,   quiet &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;TRUE&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;print&lt;/span&gt;(auc_tbl)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 2 × 2
##   model      auc
##   &amp;lt;chr&amp;gt;    &amp;lt;dbl&amp;gt;
## 1 logistic 0.710
## 2 xgboost  0.762
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# ---- 6. Brier score ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brier &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;function&lt;/span&gt;(y, p) &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mean&lt;/span&gt;((p &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; y)^2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brier_tbl &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  model &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;logistic&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;xgboost&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  brier &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;brier&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_logit), &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;brier&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_xgb))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;print&lt;/span&gt;(brier_tbl)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 2 × 2
##   model    brier
##   &amp;lt;chr&amp;gt;    &amp;lt;dbl&amp;gt;
## 1 logistic 0.216
## 2 xgboost  0.198
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# ---- 7. Calibration slope (Cox) ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cox_calib &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;function&lt;/span&gt;(y, p) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  lp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;qlogis&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;pmin&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;pmax&lt;/span&gt;(p, &lt;span style=&#34;color:#099&#34;&gt;1e-6&lt;/span&gt;), &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1e-6&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fit &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;glm&lt;/span&gt;(y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;~&lt;/span&gt; lp, family &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; binomial)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(intercept_a &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;coef&lt;/span&gt;(fit)[1], slope_b &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;coef&lt;/span&gt;(fit)[2])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cox_tbl &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;bind_rows&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  logistic &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;cox_calib&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_logit),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  xgboost  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;cox_calib&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_xgb),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  .id &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;model&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;print&lt;/span&gt;(cox_tbl)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 2 × 3
##   model    intercept_a slope_b
##   &amp;lt;chr&amp;gt;          &amp;lt;dbl&amp;gt;   &amp;lt;dbl&amp;gt;
## 1 logistic     -0.0142   0.860
## 2 xgboost      -0.0189   0.909
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;calibration_data &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;function&lt;/span&gt;(pred, y, model_name, n_bins &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;10&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(pred &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; pred, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; y) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(bin &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ntile&lt;/span&gt;(pred, n_bins)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;group_by&lt;/span&gt;(bin) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;summarise&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      mean_pred &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mean&lt;/span&gt;(pred),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      observed_rate &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mean&lt;/span&gt;(y),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      n &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;n&lt;/span&gt;(), .groups &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;drop&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(model &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; model_name)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cal_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;bind_rows&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;calibration_data&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_logit, test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;logistic&amp;#34;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;calibration_data&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_xgb,   test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;xgboost&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cal_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ggplot&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; mean_pred, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; observed_rate, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; model)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_point&lt;/span&gt;(size &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_line&lt;/span&gt;() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_abline&lt;/span&gt;(slope &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;, intercept &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;, linetype &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;dashed&amp;#34;&lt;/span&gt;, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;gray40&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;coord_equal&lt;/span&gt;(xlim &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;), ylim &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;labs&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Mean predicted probability&amp;#34;&lt;/span&gt;, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Observed event rate&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       title &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Calibration: logistic vs tuned XGBoost (nonlinear truth)&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;theme_bw&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-19-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#998;font-style:italic&#34;&gt;# ---- 8. Decision curve analysis ----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net_benefit &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;function&lt;/span&gt;(y, p, pt) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  treat &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; p &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;=&lt;/span&gt; pt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  tp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;sum&lt;/span&gt;(treat &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt; y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;); fp &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;sum&lt;/span&gt;(treat &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt; y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;); n &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;length&lt;/span&gt;(y)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (tp&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;n) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; (fp&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;n) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt; (pt&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;pt))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;thresholds &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;seq&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;0.01&lt;/span&gt;, &lt;span style=&#34;color:#099&#34;&gt;0.7&lt;/span&gt;, by &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.01&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dca_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;tibble&lt;/span&gt;(pt &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; thresholds) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mutate&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nb_logistic  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;map_dbl&lt;/span&gt;(pt, &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;~&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;net_benefit&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_logit, .x)),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nb_xgboost   &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;map_dbl&lt;/span&gt;(pt, &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;~&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;net_benefit&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true, test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;pred_xgb, .x)),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nb_treatall  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mean&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; (&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;mean&lt;/span&gt;(test&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;y_true)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;*&lt;/span&gt; (pt&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;/&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;pt)),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nb_treatnone &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dca_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;pivot_longer&lt;/span&gt;(&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;pt, names_to &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;strategy&amp;#34;&lt;/span&gt;, values_to &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;net_benefit&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ggplot&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(pt, net_benefit, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; strategy)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_line&lt;/span&gt;(linewidth &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;coord_cartesian&lt;/span&gt;(ylim &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;-0.05&lt;/span&gt;, &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;max&lt;/span&gt;(dca_df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;nb_treatall, na.rm&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;TRUE&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.05&lt;/span&gt;)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;labs&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Threshold probability&amp;#34;&lt;/span&gt;, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Net benefit&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       title &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;DCA: nonlinear truth, logistic vs tuned XGBoost&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;theme_bw&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-19-2.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;/details&gt;




&lt;h3 id=&#34;auc&#34;&gt;AUC for both models
  &lt;a href=&#34;#auc&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;print&lt;/span&gt;(auc_tbl)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 2 × 2
##   model      auc
##   &amp;lt;chr&amp;gt;    &amp;lt;dbl&amp;gt;
## 1 logistic 0.710
## 2 xgboost  0.762
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here our simulated data contains nonlinear relationships between the predictors and the outcome, so we expect XGBoost to outperform logistic regression. The AUC for logistic regression is 0.71, while the AUC for XGBoost is 0.762. This is a significant difference, and it shows that XGBoost is able to capture the nonlinear relationships in the data.&lt;/p&gt;




&lt;h3 id=&#34;brier&#34;&gt;Brier Score
  &lt;a href=&#34;#brier&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;print&lt;/span&gt;(brier_tbl)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 2 × 2
##   model    brier
##   &amp;lt;chr&amp;gt;    &amp;lt;dbl&amp;gt;
## 1 logistic 0.216
## 2 xgboost  0.198
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As we looked at before, higher or same AUC doesn&amp;rsquo;t mean better. Let&amp;rsquo;s look at brier, a heuristic to assess calibration. This shows that XGBoost is better calibrated than logistic regression. Lower == better.&lt;/p&gt;




&lt;h3 id=&#34;cox&#34;&gt;Cox calibration
  &lt;a href=&#34;#cox&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Next let&amp;rsquo;s look at Cox calibration, which is a method to assess the calibration of a model by fitting a logistic regression model with the predicted probabilities as the independent variable and the true labels as the dependent variable. The intercept and slope of the fitted model will give us an idea of how well-calibrated the model is. A well-calibrated model will have an intercept close to 0 and a slope close to 1. A biased model will have an intercept that is not close to 0, and a miscalibrated model will have a slope that is not close to 1.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;print&lt;/span&gt;(cox_tbl)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;## # A tibble: 2 × 3
##   model    intercept_a slope_b
##   &amp;lt;chr&amp;gt;          &amp;lt;dbl&amp;gt;   &amp;lt;dbl&amp;gt;
## 1 logistic     -0.0142   0.860
## 2 xgboost      -0.0189   0.909
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cal_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ggplot&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; mean_pred, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; observed_rate, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; model)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_point&lt;/span&gt;(size &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_line&lt;/span&gt;() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_abline&lt;/span&gt;(slope &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;, intercept &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;, linetype &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;dashed&amp;#34;&lt;/span&gt;, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;gray40&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;coord_equal&lt;/span&gt;(xlim &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;), ylim &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;labs&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Mean predicted probability&amp;#34;&lt;/span&gt;, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Observed event rate&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       title &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Calibration: logistic vs tuned XGBoost (nonlinear truth)&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;theme_bw&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-22-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;p&gt;both look pretty well calibrated. Close to straight diagonal line with well balanced. Now, let&amp;rsquo;s dive in DCA.&lt;/p&gt;




&lt;h3 id=&#34;dca2&#34;&gt;Decision Curve Analysis
  &lt;a href=&#34;#dca2&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dca_df &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;pivot_longer&lt;/span&gt;(&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;-&lt;/span&gt;pt, names_to &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;strategy&amp;#34;&lt;/span&gt;, values_to &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;net_benefit&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;ggplot&lt;/span&gt;(&lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;aes&lt;/span&gt;(pt, net_benefit, color &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; strategy)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;geom_line&lt;/span&gt;(linewidth &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;coord_cartesian&lt;/span&gt;(ylim &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;c&lt;/span&gt;(&lt;span style=&#34;color:#099&#34;&gt;-0.05&lt;/span&gt;, &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;max&lt;/span&gt;(dca_df&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;$&lt;/span&gt;nb_treatall, na.rm&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;TRUE&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#099&#34;&gt;0.05&lt;/span&gt;)) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;labs&lt;/span&gt;(x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Threshold probability&amp;#34;&lt;/span&gt;, y &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;Net benefit&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       title &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d14&#34;&gt;&amp;#34;DCA: nonlinear truth, logistic vs tuned XGBoost&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#900;font-weight:bold&#34;&gt;theme_bw&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src=&#34;https://www.kenkoonwong.com/blog/roc-auc-dca/index_files/figure-html/unnamed-chunk-23-1.png&#34; alt=&#34;&#34; width=&#34;672&#34; /&gt;
&lt;p&gt;My interpretation is that XGBoost consistently has a higher net benefit compared to logistic regression from threshold ≥0.25. If I&amp;rsquo;m comfortable screening 10 people to get at least 4 positives — which means a threshold of 0.4, since it&amp;rsquo;s not too invasive and not too costly — then the net benefit of using XGBoost is about 0.28. That means I&amp;rsquo;d gain 28 true-positive-equivalents for every 100 people screened, and about 3 more true-positive-equivalents than logistic regression at that same threshold.&lt;/p&gt;
&lt;p&gt;
&lt;a href=&#34;https://link.springer.com/article/10.1186/s41512-019-0064-7&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;This article by Vickers et al&lt;/a&gt; is really helpful in turning the &lt;code&gt;threshold&lt;/code&gt; verbage to &lt;code&gt;preference&lt;/code&gt;. Making the threshold as &amp;ldquo;If I screen/intervene x amount of samples, I get y amount of true positive&amp;rdquo; and making it how concerned I am to miss something vs how concerned I am that it&amp;rsquo;s more harmful getting more screened/intervened on. Another great reference is 
&lt;a href=&#34;https://www.fharrell.com/post/addmarkerdca/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A note for myself, while reading all these I was a bit confused on the term &amp;ldquo;treat all&amp;rdquo; and &amp;ldquo;treat none&amp;rdquo;. But essentially treat all is to set sensitivity to 100% and specificity to 0%, and treat none would be to set sensitivity 0% and specificity to 100%. And with the formula &lt;code&gt;net benefit = tp /n - fp * exchange_rate / n&lt;/code&gt; which is also &lt;code&gt;net benefit = sensitivity . prevalence - (1 - specificity) . (1-prevalence) . exchange_rate&lt;/code&gt;.&lt;/p&gt;




&lt;h2 id=&#34;opportunities&#34;&gt;Opportunities For Improvement
  &lt;a href=&#34;#opportunities&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Apply DCA next time when we have a model that is well calibrated and has good AUC, but we want to see if it&amp;rsquo;s worth using the model to make a decision.&lt;/li&gt;
&lt;li&gt;Find a few models in literature and do a simulation and interpret the DCA and rationale behind certain threshold&lt;/li&gt;
&lt;li&gt;Find other studies that used DCA and look at their interpretation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2 id=&#34;lessons&#34;&gt;Lessons learnt
  &lt;a href=&#34;#lessons&#34;&gt;&lt;svg class=&#34;anchor-symbol&#34; aria-hidden=&#34;true&#34; height=&#34;26&#34; width=&#34;26&#34; viewBox=&#34;0 0 22 22&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
      &lt;path d=&#34;M0 0h24v24H0z&#34; fill=&#34;currentColor&#34;&gt;&lt;/path&gt;
      &lt;path d=&#34;M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z&#34;&gt;&lt;/path&gt;
    &lt;/svg&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;When building a classification model, AUC is not enough, we need to look at calibration + DCA&lt;/li&gt;
&lt;li&gt;learnt youden index and how it works by calculating 
&lt;a href=&#34;#procedure&#34;&gt;J score&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;bias is a shift in the intercept, miscalibration is a shift in the slope&lt;/li&gt;
&lt;li&gt;learnt brier, cox calibration, DCA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you like this article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;please feel free to send me a 
&lt;a href=&#34;https://www.kenkoonwong.com/blog/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;comment or visit my other blogs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;please feel free to follow me on 
&lt;a href=&#34;https://bsky.app/profile/kenkoonwong.bsky.social&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;BlueSky&lt;/a&gt;, 
&lt;a href=&#34;https://twitter.com/kenkoonwong/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;twitter&lt;/a&gt;, 
&lt;a href=&#34;https://github.com/kenkoonwong/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub&lt;/a&gt; or 
&lt;a href=&#34;https://rstats.me/@kenkoonwong&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;if you would like collaborate please feel free to 
&lt;a href=&#34;https://www.kenkoonwong.com/contact/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;contact me&lt;/a&gt;
a&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>