<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://thierrymoudiki.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://thierrymoudiki.github.io/" rel="alternate" type="text/html" /><updated>2026-07-16T04:49:43+00:00</updated><id>https://thierrymoudiki.github.io/feed.xml</id><title type="html">Thierry Moudiki’s webpage</title><subtitle>Personal webpage: </subtitle><entry><title type="html">My last R posts: How conformalization helps weak models, fast conformal prediction with jackknife+ (and no refitting), and sklearn in R</title><link href="https://thierrymoudiki.github.io/blog/2026/07/13/r/my-last-R-posts" rel="alternate" type="text/html" title="My last R posts: How conformalization helps weak models, fast conformal prediction with jackknife+ (and no refitting), and sklearn in R" /><published>2026-07-13T00:00:00+00:00</published><updated>2026-07-13T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/07/13/r/my-last-R-posts</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/07/13/r/my-last-R-posts"><![CDATA[<p>This post is mainly (but not only) a test, because I had a broken xml feed for my R posts, and I wanted to see if it was fixed.</p>

<p>It’s about my last R posts from june and july, which are:</p>

<ul>
  <li>Using scikit-learn models in R easily with the <code class="language-plaintext highlighter-rouge">tisthemachinelearner</code> R package</li>
  <li>How conformalization helps weak models</li>
  <li>Fast Conformal Prediction for Some Machine Learning Models (jackknife+ and no refitting)</li>
</ul>

<h1 id="using-scikit-learn-models-in-r-easily-with-the-tisthemachinelearner-r-package">Using scikit-learn models in R easily with the <code class="language-plaintext highlighter-rouge">tisthemachinelearner</code> R package</h1>

<p>This post is about the <a href="https://github.com/Techtonique/tisthemachinelearner_r/tree/main"><code class="language-plaintext highlighter-rouge">tisthemachinelearner</code> R package</a>, that allows to use scikit-learn models in R. It is a wrapper around the <a href="https://github.com/Techtonique/tisthemachinelearner/tree/main">tisthemachinelearner Python package</a>. Prediction intervals can be computed using either split conformal prediction, surrogate methods or the bootstrap.</p>

<p>Read: <a href="https://thierrymoudiki.github.io/blog/2026/06/21/r/tisthemllearner">https://thierrymoudiki.github.io/blog/2026/06/21/r/tisthemllearner</a></p>

<h1 id="how-conformalization-helps-weak-models">How conformalization helps weak models</h1>

<p>In this post, we compare <a href="https://en.wikipedia.org/wiki/Conformal_prediction">split conformal prediction</a>
across several predictive models, using <a href="https://cran.r-project.org/web/packages/mlS3/index.html">R package mlS3</a>.</p>

<p>Read: <a href="https://thierrymoudiki.github.io/blog/2026/06/07/r/conformalization-helps-weak-models">https://thierrymoudiki.github.io/blog/2026/06/07/r/conformalization-helps-weak-models</a></p>

<h1 id="fast-conformal-prediction-for-some-machine-learning-models-jackknife-and-no-refitting">Fast Conformal Prediction for Some Machine Learning Models (jackknife+ and no refitting)</h1>

<p>It’s surprisingly fast to obtain conformal <a href="https://projecteuclid.org/journalArticle/Download?urlId=10.1214%2F20-AOS1965">jackknife+</a> prediction intervals for Machine Learning models of the form \(\hat{y} = Sy\) (including Ordinary
Least Squares, Ridge Regression, Random Vector Functional Link Networks,
Kernel Ridge Regression, smoothing splines, and local polynomial regression). <strong>No refitting involved, just Linear Algebra</strong>. Read <a href="https://www.researchgate.net/publication/408161842_Fast_Conformal_Prediction_for_Some_Machine_Learning_Models_via_Closed-Form_Jackknife">https://www.researchgate.net/publication/408161842_Fast_Conformal_Prediction_for_Some_Machine_Learning_Models_via_Closed-Form_Jackknife</a>.</p>

<p><img src="/images/2026-06-27/2026-06-27-jackknife-plus-smoothers_6_1.png" alt="image-title-here" class="img-responsive" /></p>

<p><a target="_blank" href="https://colab.research.google.com/github/Techtonique/mlsauce/blob/master/mlsauce/demo/thierrymoudiki-2026-06-27_jackknife_plus_smoothers.ipynb">
  <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" style="max-width: 100%; height: auto; width: 120px;" />
</a></p>]]></content><author><name></name></author><category term="R" /><summary type="html"><![CDATA[My last R posts: How conformalization helps weak models, fast conformal prediction with jackknife+ (and no refitting), and sklearn in R.]]></summary></entry><entry><title type="html">Natively Interpretable Boosting</title><link href="https://thierrymoudiki.github.io/blog/2026/07/12/python/Natively-Interpretable-Boosting" rel="alternate" type="text/html" title="Natively Interpretable Boosting" /><published>2026-07-12T00:00:00+00:00</published><updated>2026-07-12T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/07/12/python/Natively-Interpretable-Boosting</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/07/12/python/Natively-Interpretable-Boosting"><![CDATA[<h1 id="natively-interpretable-boosting">Natively Interpretable Boosting</h1>

<p>Gradient boosted decision trees are accurate but usually opaque: to explain a prediction you rely on a <em>post hoc</em> method (SHAP, LIME, permutation importance) that approximates the model after the fact. This blog post works with a booster (<code class="language-plaintext highlighter-rouge">cybooster</code>) that is interpretable <em>by construction</em> instead. Because of the choice of weak learners.</p>

<p>Each boosting round fits a randomized-neural-network “weak learner”: a random projection of a column-subsample of the features through a nonlinear activation (ReLU, tanh, sigmoid, …), optionally concatenated with the raw features via a direct link, with a linear model (e.g. Ridge) fit on the current residuals (could be any regressor, but the natively interpretable one is a linear one). Because every hidden unit’s transformation is known in closed form, so is its derivative – which means feature attributions don’t need to be estimated numerically:</p>

<ul>
  <li><strong>Sensitivities</strong> (<code class="language-plaintext highlighter-rouge">dF/dx</code>) – the pointwise gradient of the ensemble’s output with respect to each input, summed analytically across boosting rounds.</li>
  <li><strong>Integrated Gradients</strong> – exact, closed-form, baseline-relative attributions (no numerical quadrature), obtained via the secant/mean-value form of each activation so that attributions sum exactly to <code class="language-plaintext highlighter-rouge">F(x) - F(baseline)</code>.</li>
</ul>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="n">cybooster</span>
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">"""
examples.py
============

Self-contained worked examples for the closed-form Integrated Gradients
methodology; `cybooster.SkBoosterRegressor` already exposes:

    .fit(X, y)                                   -&gt; self
    .predict(X)                                  -&gt; np.ndarray
    .get_sensitivities(X, columns=...)           -&gt; DataFrame  (pointwise dF/dx_j, heterogenous)
    .get_feature_importances(X, columns=...)     -&gt; DataFrame  (mean |sensitivity|)
    .get_summary(X, columns=...)                 -&gt; DataFrame  (mean/std/CI/p-value)
    .get_integrated_gradients(X, X_baseline=None, columns=...) -&gt; DataFrame  (closed-form IG)
    .plot_importance(X, columns=..., kind=...)               -&gt; Figure
    .plot_beeswarm(X, columns=..., kind=...)                 -&gt; Figure
    .plot_heterogeneity(X, columns=..., kind=..., smooth=..., frac=..., n_boot=..., ci=...) -&gt; Figure

Two worked examples:
  1. Diabetes (sklearn built-in, no network dependency) -- the main case.
  2. Boston housing (classic benchmark, GitHub CSV mirror) -- kept for
     continuity with prior work, with an explicit caveat on its `b`
     variable (see the docstring of `run_boston`).

Each example: fits the model, runs a completeness check on the closed-form
IG (sum of attributions should equal F(x) - F(baseline) to numerical
precision), and produces three figures: global importance, beeswarm
(attribution + heterogeneity), and LOWESS-smoothed local heterogeneity for
the top features.
"""</span>

<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="n">pd</span>
<span class="kn">from</span> <span class="nn">sklearn.linear_model</span> <span class="kn">import</span> <span class="n">Ridge</span>
<span class="kn">from</span> <span class="nn">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">train_test_split</span>
<span class="kn">from</span> <span class="nn">sklearn.metrics</span> <span class="kn">import</span> <span class="n">r2_score</span><span class="p">,</span> <span class="n">mean_absolute_error</span>
<span class="kn">from</span> <span class="nn">sklearn.datasets</span> <span class="kn">import</span> <span class="n">load_diabetes</span>

<span class="kn">from</span> <span class="nn">cybooster</span> <span class="kn">import</span> <span class="n">SkBoosterRegressor</span>

<span class="n">OUTDIR</span> <span class="o">=</span> <span class="s">"."</span>  <span class="c1"># change if you want figures written elsewhere
</span>

<span class="c1"># ----------------------------------------------------------------------------
# shared fit / diagnostics / figure-generation routine
# ----------------------------------------------------------------------------
</span><span class="k">def</span> <span class="nf">run_example</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">cols</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">top_k_features</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span>
                 <span class="n">n_estimators</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">learning_rate</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span> <span class="n">n_hidden_features</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span>
                 <span class="n">activation</span><span class="o">=</span><span class="s">"relu"</span><span class="p">,</span> <span class="n">reg_alpha</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.25</span><span class="p">,</span> <span class="n">seed</span><span class="o">=</span><span class="mi">123</span><span class="p">):</span>
    <span class="s">"""Fit, sanity-check, and plot one dataset. Returns the fitted model
    and the test split, in case further ad hoc inspection is wanted."""</span>

    <span class="n">Xtr</span><span class="p">,</span> <span class="n">Xte</span><span class="p">,</span> <span class="n">ytr</span><span class="p">,</span> <span class="n">yte</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="n">test_size</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">42</span><span class="p">)</span>

    <span class="n">model</span> <span class="o">=</span> <span class="n">SkBoosterRegressor</span><span class="p">(</span>
        <span class="n">obj</span><span class="o">=</span><span class="n">Ridge</span><span class="p">(</span><span class="n">alpha</span><span class="o">=</span><span class="n">reg_alpha</span><span class="p">,</span> <span class="n">fit_intercept</span><span class="o">=</span><span class="bp">False</span><span class="p">),</span>
        <span class="n">n_estimators</span><span class="o">=</span><span class="n">n_estimators</span><span class="p">,</span> <span class="n">learning_rate</span><span class="o">=</span><span class="n">learning_rate</span><span class="p">,</span>
        <span class="n">n_hidden_features</span><span class="o">=</span><span class="n">n_hidden_features</span><span class="p">,</span> <span class="n">activation</span><span class="o">=</span><span class="n">activation</span><span class="p">,</span>
        <span class="n">col_sample</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">row_sample</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">direct_link</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">seed</span><span class="o">=</span><span class="n">seed</span><span class="p">,</span>
    <span class="p">)</span>
    <span class="n">model</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">Xtr</span><span class="p">,</span> <span class="n">ytr</span><span class="p">)</span>

    <span class="n">pred</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">Xte</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n\n\n</span><span class="s">=== </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s"> ==="</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n\n</span><span class="s"> Test R2:  </span><span class="si">{</span><span class="n">r2_score</span><span class="p">(</span><span class="n">yte</span><span class="p">,</span> <span class="n">pred</span><span class="p">)</span><span class="si">:</span><span class="p">.</span><span class="mi">4</span><span class="n">f</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n\n</span><span class="s"> Test MAE: </span><span class="si">{</span><span class="n">mean_absolute_error</span><span class="p">(</span><span class="n">yte</span><span class="p">,</span> <span class="n">pred</span><span class="p">)</span><span class="si">:</span><span class="p">.</span><span class="mi">4</span><span class="n">f</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
    <span class="n">sensitivities</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">get_sensitivities</span><span class="p">(</span><span class="n">Xte</span><span class="p">,</span> <span class="n">columns</span><span class="o">=</span><span class="n">cols</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n\n</span><span class="s"> Get sensitivities: </span><span class="se">\n</span><span class="s"> </span><span class="si">{</span><span class="n">sensitivities</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n\n</span><span class="s"> Probability of sensitivity &gt; 0: </span><span class="se">\n</span><span class="s"> </span><span class="si">{</span> <span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">(</span><span class="n">sensitivities</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> <span class="si">}</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n\n</span><span class="s"> Get importance: </span><span class="se">\n</span><span class="s"> </span><span class="si">{</span><span class="n">model</span><span class="p">.</span><span class="n">get_feature_importances</span><span class="p">(</span><span class="n">Xte</span><span class="p">,</span> <span class="n">columns</span><span class="o">=</span><span class="n">cols</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n\n</span><span class="s"> Get summary: </span><span class="se">\n</span><span class="s"> </span><span class="si">{</span><span class="n">model</span><span class="p">.</span><span class="n">get_summary</span><span class="p">(</span><span class="n">Xte</span><span class="p">,</span> <span class="n">columns</span><span class="o">=</span><span class="n">cols</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

    <span class="c1"># --- closed-form Integrated Gradients + completeness check ---
</span>    <span class="n">ig</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">get_integrated_gradients</span><span class="p">(</span><span class="n">Xte</span><span class="p">,</span> <span class="n">columns</span><span class="o">=</span><span class="n">cols</span><span class="p">)</span>
    <span class="n">baseline</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">tile</span><span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">fit_obj_</span><span class="p">[</span><span class="s">"xm"</span><span class="p">],</span> <span class="p">(</span><span class="n">Xte</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="mi">1</span><span class="p">))</span>
    <span class="n">baseline_pred</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">baseline</span><span class="p">)</span>
    <span class="n">completeness_err</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nb">max</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nb">abs</span><span class="p">(</span><span class="n">ig</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">).</span><span class="n">values</span> <span class="o">-</span> <span class="p">(</span><span class="n">pred</span> <span class="o">-</span> <span class="n">baseline_pred</span><span class="p">)))</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n</span><span class="s"> IG completeness max abs error: </span><span class="si">{</span><span class="n">completeness_err</span><span class="si">:</span><span class="p">.</span><span class="mi">2</span><span class="n">e</span><span class="si">}</span><span class="s">  (should be ~machine eps)"</span><span class="p">)</span>

    <span class="c1"># --- global importance (mean |IG|) ---
</span>    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n\n</span><span class="s"> Mean |IG| per feature:"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="n">ig</span><span class="p">.</span><span class="nb">abs</span><span class="p">().</span><span class="n">mean</span><span class="p">().</span><span class="n">sort_values</span><span class="p">(</span><span class="n">ascending</span><span class="o">=</span><span class="bp">False</span><span class="p">).</span><span class="nb">round</span><span class="p">(</span><span class="mi">3</span><span class="p">))</span>

    <span class="c1"># --- figures ---
</span>    <span class="n">fig_bee</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">plot_beeswarm</span><span class="p">(</span><span class="n">Xte</span><span class="p">,</span> <span class="n">columns</span><span class="o">=</span><span class="n">cols</span><span class="p">,</span> <span class="n">kind</span><span class="o">=</span><span class="s">"ig"</span><span class="p">)</span>
    <span class="n">fig_bee</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">OUTDIR</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s">_beeswarm.png"</span><span class="p">,</span> <span class="n">bbox_inches</span><span class="o">=</span><span class="s">"tight"</span><span class="p">)</span>

    <span class="n">fig_imp</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">plot_importance</span><span class="p">(</span><span class="n">Xte</span><span class="p">,</span> <span class="n">columns</span><span class="o">=</span><span class="n">cols</span><span class="p">,</span> <span class="n">kind</span><span class="o">=</span><span class="s">"ig"</span><span class="p">)</span>
    <span class="n">fig_imp</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">OUTDIR</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s">_importance.png"</span><span class="p">,</span> <span class="n">bbox_inches</span><span class="o">=</span><span class="s">"tight"</span><span class="p">)</span>

    <span class="n">fig_het</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">plot_heterogeneity</span><span class="p">(</span><span class="n">Xte</span><span class="p">,</span> <span class="n">columns</span><span class="o">=</span><span class="n">cols</span><span class="p">,</span> <span class="n">kind</span><span class="o">=</span><span class="s">"ig"</span><span class="p">,</span>
                                        <span class="n">top_k</span><span class="o">=</span><span class="n">top_k_features</span><span class="p">,</span> <span class="n">smooth</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
                                        <span class="n">frac</span><span class="o">=</span><span class="mf">0.4</span><span class="p">,</span> <span class="n">n_boot</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">ci</span><span class="o">=</span><span class="mf">0.90</span><span class="p">)</span>
    <span class="n">fig_het</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">OUTDIR</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s">_heterogeneity.png"</span><span class="p">,</span> <span class="n">bbox_inches</span><span class="o">=</span><span class="s">"tight"</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Saved: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s">_importance.png, </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s">_beeswarm.png, </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s">_heterogeneity.png"</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">model</span><span class="p">,</span> <span class="p">(</span><span class="n">Xtr</span><span class="p">,</span> <span class="n">Xte</span><span class="p">,</span> <span class="n">ytr</span><span class="p">,</span> <span class="n">yte</span><span class="p">)</span>


<span class="c1"># ----------------------------------------------------------------------------
# example 1: diabetes (main case -- no network dependency, no ethical baggage)
# ----------------------------------------------------------------------------
</span><span class="k">def</span> <span class="nf">run_diabetes</span><span class="p">():</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">load_diabetes</span><span class="p">(</span><span class="n">as_frame</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">X</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">values</span><span class="p">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">float64</span><span class="p">)</span>
    <span class="n">y</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">target</span><span class="p">.</span><span class="n">values</span><span class="p">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">float64</span><span class="p">)</span>
    <span class="n">cols</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">columns</span><span class="p">.</span><span class="n">tolist</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">run_example</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">cols</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">"diabetes"</span><span class="p">,</span> <span class="n">top_k_features</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>


<span class="c1"># ----------------------------------------------------------------------------
# example 2: Boston housing (continuity case)
#
# Kept here for comparability with earlier results in this line of work, not
# as an endorsement of the dataset. The `b` column is 1000*(Bk-0.63)^2, a
# variable constructed around an assumption that racial composition affects
# property values non-monotonically; scikit-learn removed `load_boston` over
# this and related issues (see Carlisle, "Racist data destruction?", 2019).
# Results below should be read purely as a demonstration of the attribution
# method, not as a claim about the housing market.
# ----------------------------------------------------------------------------
</span><span class="k">def</span> <span class="nf">run_boston</span><span class="p">():</span>
    <span class="n">url</span> <span class="o">=</span> <span class="s">"https://raw.githubusercontent.com/selva86/datasets/master/BostonHousing.csv"</span>
    <span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">read_csv</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
    <span class="n">df</span><span class="p">[</span><span class="s">"chas"</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s">"chas"</span><span class="p">].</span><span class="n">astype</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
    <span class="n">y</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s">"medv"</span><span class="p">].</span><span class="n">values</span><span class="p">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">float64</span><span class="p">)</span>
    <span class="n">X</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="n">drop</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="s">"medv"</span><span class="p">]).</span><span class="n">values</span><span class="p">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">float64</span><span class="p">)</span>
    <span class="n">cols</span> <span class="o">=</span> <span class="n">df</span><span class="p">.</span><span class="n">drop</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="p">[</span><span class="s">"medv"</span><span class="p">]).</span><span class="n">columns</span><span class="p">.</span><span class="n">tolist</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">run_example</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">cols</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">"boston"</span><span class="p">,</span> <span class="n">top_k_features</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>


<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">run_diabetes</span><span class="p">()</span>
    <span class="n">run_boston</span><span class="p">()</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>=== diabetes ===


 Test R2:  0.5246


 Test MAE: 39.6518


100%|██████████| 100/100 [00:01&lt;00:00, 95.28it/s]




 Get sensitivities: 
        age     sex    bmi     bp      s1     s2     s3     s4     s5     s6
0   140.25 -135.75 599.50 360.89 -904.42 426.03 197.63 322.09 659.40  98.09
1    29.26 -114.81 492.63 410.05 -725.05 397.51 -41.97 248.65 706.47 -29.27
2   142.60 -130.74 605.98 363.81 -904.33 426.11 203.03 324.27 660.64 102.55
3   142.60 -130.74 605.98 363.81 -904.33 426.11 203.03 324.27 660.64 102.55
4   134.84 -129.38 551.47 362.20 -906.51 391.45 154.09 318.14 612.25  73.00
..     ...     ...    ...    ...     ...    ...    ...    ...    ...    ...
106 204.97 -220.27 546.19 492.93 -584.90 337.61 -43.53 229.42 760.56 -39.01
107 219.03  -92.42 682.84 357.55 -748.84 368.26 267.01 410.04 718.87  37.63
108 142.60 -130.74 605.98 363.81 -904.33 426.11 203.03 324.27 660.64 102.55
109   5.61 -332.33 459.52 385.59 -596.72 355.77 -85.85 133.13 668.86 -90.40
110 276.88 -172.84 632.56 611.12 -555.77 457.64 163.86 492.19 817.12 192.99

[111 rows x 10 columns]


 Probability of sensitivity &gt; 0: 
 age   0.90
sex   0.00
bmi   1.00
bp    1.00
s1    0.00
s2    1.00
s3    0.46
s4    1.00
s5    1.00
s6    0.45
dtype: float64


100%|██████████| 100/100 [00:01&lt;00:00, 94.89it/s]




 Get importance: 
     age    sex    bmi     bp     s1     s2     s3     s4     s5    s6
0 78.31 246.15 523.84 383.15 728.83 380.95 131.86 220.51 663.86 94.07


 Get summary: 
        Mean  Std. Dev.     Min     Max  Median    SE  Lower CI  Upper CI  \
s5   663.86      47.07  464.44  817.12  668.53  4.47    655.00    672.71   
bmi  523.84      87.28  236.09  700.71  492.63  8.28    507.42    540.25   
bp   383.15      46.52  256.74  611.12  387.71  4.42    374.40    391.90   
s2   380.95      56.86  153.32  517.01  359.42  5.40    370.25    391.65   
s4   220.51     107.11   10.34  492.19  168.27 10.17    200.36    240.66   
age   72.64      79.56  -86.64  276.88   29.26  7.55     57.67     87.60   
s3    32.75     143.40 -196.34  267.01  -63.61 13.61      5.78     59.73   
s6    -6.13      98.95 -164.75  211.34  -77.04  9.39    -24.74     12.48   
sex -246.15     105.55 -457.02  -62.21 -296.30 10.02   -266.01   -226.30   
s1  -728.83     141.80 -944.88 -532.40 -672.97 13.46   -755.50   -702.15   

     t-statistic  p-value Signif. Code  
s5        148.59     0.00          ***  
bmi        63.23     0.00          ***  
bp         86.77     0.00          ***  
s2         70.58     0.00          ***  
s4         21.69     0.00          ***  
age         9.62     0.00          ***  
s3          2.41     0.02            *  
s6         -0.65     0.52            -  
sex       -24.57     0.00          ***  
s1        -54.15     0.00          ***  

 IG completeness max abs error: 9.24e-14  (should be ~machine eps)


 Mean |IG| per feature:
s1    26.54
s5    25.83
bmi   21.63
bp    15.38
s2    13.81
sex   11.56
s4     7.71
s3     5.05
s6     3.53
age    3.07
dtype: float64
Saved: diabetes_importance.png, diabetes_beeswarm.png, diabetes_heterogeneity.png



=== boston ===


 Test R2:  0.7982


 Test MAE: 2.5683


100%|██████████| 100/100 [00:00&lt;00:00, 120.65it/s]




 Get sensitivities: 
      crim    zn  indus  chas    nox    rm   age   dis  rad   tax  ptratio  \
0    0.01 -0.04   0.02 -4.88 -10.01  9.30 -0.06 -1.23 0.43 -0.02    -0.77   
1    0.22  0.09   0.26  4.14 -13.17 10.85 -0.01  0.04 0.67 -0.01    -0.24   
2   -0.14  0.03   0.00  6.38 -33.67 -1.01  0.01 -2.28 0.19 -0.00    -1.20   
3    0.01 -0.04   0.02 -4.88 -10.01  9.30 -0.06 -1.23 0.43 -0.02    -0.77   
4   -0.14  0.03   0.00  6.47 -33.57 -0.98  0.01 -2.27 0.19 -0.00    -1.20   
..    ...   ...    ...   ...    ...   ...   ...   ...  ...   ...      ...   
122 -0.14  0.03  -0.00  5.97 -33.86 -1.12  0.01 -2.29 0.19 -0.00    -1.18   
123  0.01 -0.04   0.02 -4.88 -10.01  9.30 -0.06 -1.23 0.43 -0.02    -0.77   
124  0.01 -0.04   0.02 -4.88 -10.01  9.30 -0.06 -1.23 0.43 -0.02    -0.77   
125  0.01 -0.04   0.02 -4.88 -10.01  9.30 -0.06 -1.23 0.43 -0.02    -0.77   
126 -0.23 -0.01  -0.05  4.39 -24.72  5.06 -0.05 -1.12 0.28 -0.01    -1.01   

       b  lstat  
0   0.01  -0.06  
1   0.02  -0.20  
2   0.01  -0.81  
3   0.01  -0.06  
4   0.01  -0.81  
..   ...    ...  
122 0.01  -0.82  
123 0.01  -0.06  
124 0.01  -0.06  
125 0.01  -0.06  
126 0.00  -0.51  

[127 rows x 13 columns]


 Probability of sensitivity &gt; 0: 
 crim      0.56
zn        0.48
indus     0.76
chas      0.51
nox       0.05
rm        0.67
age       0.42
dis       0.02
rad       1.00
tax       0.04
ptratio   0.06
b         0.94
lstat     0.05
dtype: float64


100%|██████████| 100/100 [00:00&lt;00:00, 119.59it/s]




 Get importance: 
    crim   zn  indus  chas   nox   rm  age  dis  rad  tax  ptratio    b  lstat
0  0.10 0.04   0.06  4.81 18.27 6.04 0.04 1.54 0.36 0.01     0.88 0.01   0.35


 Get summary: 
           Mean  Std. Dev.    Min   Max  Median   SE  Lower CI  Upper CI  \
rm        5.27       4.81  -2.05 11.37    7.85 0.43      4.43      6.12   
chas      0.52       5.13  -5.69 11.17    1.00 0.46     -0.38      1.42   
rad       0.36       0.14   0.09  0.72    0.43 0.01      0.33      0.38   
indus     0.04       0.11  -0.23  0.56    0.02 0.01      0.02      0.06   
b         0.01       0.01  -0.02  0.04    0.01 0.00      0.01      0.01   
zn        0.00       0.05  -0.06  0.17   -0.01 0.00     -0.01      0.01   
tax      -0.01       0.01  -0.03  0.02   -0.01 0.00     -0.01     -0.01   
age      -0.03       0.05  -0.14  0.16   -0.04 0.00     -0.03     -0.02   
crim     -0.03       0.13  -0.29  0.38    0.01 0.01     -0.05     -0.01   
lstat    -0.34       0.35  -0.85  0.27   -0.16 0.03     -0.40     -0.28   
ptratio  -0.83       0.42  -1.68  0.79   -0.78 0.04     -0.91     -0.76   
dis      -1.53       0.69  -2.64  0.48   -1.25 0.06     -1.65     -1.41   
nox     -17.78      12.03 -37.83 10.03  -10.79 1.07    -19.90    -15.67   

         t-statistic  p-value Signif. Code  
rm             12.36     0.00          ***  
chas            1.14     0.26            -  
rad            27.96     0.00          ***  
indus           3.83     0.00          ***  
b              13.15     0.00          ***  
zn              0.37     0.71            -  
tax           -13.81     0.00          ***  
age            -6.36     0.00          ***  
crim           -2.42     0.02            *  
lstat         -11.08     0.00          ***  
ptratio       -22.16     0.00          ***  
dis           -25.11     0.00          ***  
nox           -16.66     0.00          ***  

 IG completeness max abs error: 1.78e-14  (should be ~machine eps)


 Mean |IG| per feature:
rm        2.80
dis       2.53
lstat     2.51
rad       2.35
nox       1.75
ptratio   1.49
tax       1.32
age       1.12
zn        0.67
chas      0.61
crim      0.60
b         0.55
indus     0.28
dtype: float64
Saved: boston_importance.png, boston_beeswarm.png, boston_heterogeneity.png
</code></pre></div></div>

<p><img src="/images/2026-07-12/2026-07-12-Natively-Interpretable-Boosting_2_9.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-07-12/2026-07-12-Natively-Interpretable-Boosting_2_10.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-07-12/2026-07-12-Natively-Interpretable-Boosting_2_11.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-07-12/2026-07-12-Natively-Interpretable-Boosting_2_12.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-07-12/2026-07-12-Natively-Interpretable-Boosting_2_13.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-07-12/2026-07-12-Natively-Interpretable-Boosting_2_14.png" alt="image-title-here" class="img-responsive" /></p>

<h2 id="takeaways">Takeaways</h2>

<p>The completeness check above confirms the core claim: summing the closed-form Integrated Gradients across features reproduces <code class="language-plaintext highlighter-rouge">F(x) - F(baseline)</code> to numerical precision, with no sampling or quadrature error. That’s the payoff of building interpretability into the weak learners themselves – every attribution is exact and essentially free to compute, rather than an approximation layered on top of a black box.</p>

<p>The importance, beeswarm, and heterogeneity plots turn those attributions into something readable: which features matter on average, how their effects vary across observations, and whether that variation follows a discernible shape (via the LOWESS trend). Together <strong>they give a boosted ensemble the same kind of transparency usually reserved for much simpler models, without giving up predictive performance</strong>.</p>

<p>Natural next steps: try other activations (<code class="language-plaintext highlighter-rouge">tanh</code>, <code class="language-plaintext highlighter-rouge">sigmoid</code>, <code class="language-plaintext highlighter-rouge">relu6</code>) and compare how attribution shapes change, or swap in a different base learner (<code class="language-plaintext highlighter-rouge">Lasso</code>, <code class="language-plaintext highlighter-rouge">ElasticNet</code>) for the boosting rounds. Tune the model.</p>]]></content><author><name></name></author><category term="Python" /><summary type="html"><![CDATA[This notebook works with a booster, cybooster, that is interpretable by construction instead of relying on post hoc methods like SHAP or LIME.]]></summary></entry><entry><title type="html">Fast conformal prediction (no refitting) for some Machine Learning models via closed-form jackknife plus</title><link href="https://thierrymoudiki.github.io/blog/2026/06/27/r/python/jackknife-plus-smoothers" rel="alternate" type="text/html" title="Fast conformal prediction (no refitting) for some Machine Learning models via closed-form jackknife plus" /><published>2026-06-27T00:00:00+00:00</published><updated>2026-06-27T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/06/27/r/python/jackknife-plus-smoothers</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/06/27/r/python/jackknife-plus-smoothers"><![CDATA[<p>It’s surprisingly fast to obtain conformal <a href="https://projecteuclid.org/journalArticle/Download?urlId=10.1214%2F20-AOS1965">jackknife+</a> prediction intervals for Machine Learning models of the form \(\hat{y} = Sy\) (including Ordinary
Least Squares, Ridge Regression, Random Vector Functional Link Networks,
Kernel Ridge Regression, smoothing splines, and local polynomial regression). <strong>No refitting involved, just Linear Algebra</strong>. Read <a href="https://www.researchgate.net/publication/408161842_Fast_Conformal_Prediction_for_Some_Machine_Learning_Models_via_Closed-Form_Jackknife">https://www.researchgate.net/publication/408161842_Fast_Conformal_Prediction_for_Some_Machine_Learning_Models_via_Closed-Form_Jackknife</a>.</p>

<p>Here are Python and R examples (the link to the notebook is at the bottom of the page):</p>

<h1 id="1---r-version">1 - R version</h1>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%</span><span class="n">load_ext</span> <span class="n">rpy2</span><span class="p">.</span><span class="n">ipython</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>The rpy2.ipython extension is already loaded. To reload it, use:
  %reload_ext rpy2.ipython
</code></pre></div></div>

<div class="language-r highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%%</span><span class="n">R</span><span class="w">

</span><span class="n">library</span><span class="p">(</span><span class="n">MASS</span><span class="p">)</span><span class="w">

</span><span class="n">jackknife_plus</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span><span class="w"> </span><span class="n">y_train</span><span class="p">,</span><span class="w"> </span><span class="n">X_test</span><span class="p">,</span><span class="w"> </span><span class="n">lambda</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w">
                           </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.1</span><span class="p">,</span><span class="w"> </span><span class="n">symmetric</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">FALSE</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="c1"># Center response (intercept not penalized)</span><span class="w">
  </span><span class="n">ybar</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">y_train</span><span class="p">)</span><span class="w">
  </span><span class="n">yc</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y_train</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">ybar</span><span class="w">

  </span><span class="c1"># Ridge solution</span><span class="w">
  </span><span class="n">A</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">t</span><span class="p">(</span><span class="n">X_train</span><span class="p">)</span><span class="w"> </span><span class="o">%*%</span><span class="w"> </span><span class="n">X_train</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">lambda</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">diag</span><span class="p">(</span><span class="n">ncol</span><span class="p">(</span><span class="n">X_train</span><span class="p">))</span><span class="w">
  </span><span class="n">A_inv</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">solve</span><span class="p">(</span><span class="n">A</span><span class="p">)</span><span class="w">
  </span><span class="n">beta</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">A_inv</span><span class="w"> </span><span class="o">%*%</span><span class="w"> </span><span class="n">t</span><span class="p">(</span><span class="n">X_train</span><span class="p">)</span><span class="w"> </span><span class="o">%*%</span><span class="w"> </span><span class="n">yc</span><span class="w">

  </span><span class="c1"># Closed-form LOO residuals (memory efficient)</span><span class="w">
  </span><span class="n">h</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">rowSums</span><span class="p">((</span><span class="n">X_train</span><span class="w"> </span><span class="o">%*%</span><span class="w"> </span><span class="n">A_inv</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">X_train</span><span class="p">)</span><span class="w">  </span><span class="c1"># diag(X_train %*% A_inv %*% t(X_train))</span><span class="w">
  </span><span class="n">e</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">yc</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">X_train</span><span class="w"> </span><span class="o">%*%</span><span class="w"> </span><span class="n">beta</span><span class="p">)</span><span class="w">       </span><span class="c1"># in-sample residuals</span><span class="w">
  </span><span class="n">r</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">pmax</span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">h</span><span class="p">,</span><span class="w"> </span><span class="m">1e-10</span><span class="p">)</span><span class="w">                  </span><span class="c1"># LOO residuals</span><span class="w">

  </span><span class="c1"># Full-data predictions on test set</span><span class="w">
  </span><span class="n">yhat_test</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">X_test</span><span class="w"> </span><span class="o">%*%</span><span class="w"> </span><span class="n">beta</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ybar</span><span class="w">

  </span><span class="c1"># Cross-term: n_test x n_train</span><span class="w">
  </span><span class="n">G</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">X_test</span><span class="w"> </span><span class="o">%*%</span><span class="w"> </span><span class="n">A_inv</span><span class="w"> </span><span class="o">%*%</span><span class="w"> </span><span class="n">t</span><span class="p">(</span><span class="n">X_train</span><span class="p">)</span><span class="w">

  </span><span class="c1"># f^{-i}(x_j) = f(x_j) - G[j,i] * r_i (Sherman-Morrison)</span><span class="w">
  </span><span class="n">loo_pred</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">yhat_test</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">sweep</span><span class="p">(</span><span class="n">G</span><span class="p">,</span><span class="w"> </span><span class="m">2</span><span class="p">,</span><span class="w"> </span><span class="n">r</span><span class="p">,</span><span class="w"> </span><span class="n">`*`</span><span class="p">)</span><span class="w">

  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">symmetric</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="c1"># Symmetric version: use absolute residuals</span><span class="w">
    </span><span class="n">scores</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">abs</span><span class="p">(</span><span class="n">loo_pred</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">yhat_test</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nf">abs</span><span class="p">(</span><span class="nf">rep</span><span class="p">(</span><span class="n">r</span><span class="p">,</span><span class="w"> </span><span class="n">each</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nrow</span><span class="p">(</span><span class="n">X_test</span><span class="p">)))</span><span class="w">
    </span><span class="n">q</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">apply</span><span class="p">(</span><span class="n">scores</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="n">quantile</span><span class="p">,</span><span class="w"> </span><span class="n">probs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha</span><span class="p">)</span><span class="w">
    </span><span class="n">lo</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">yhat_test</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">q</span><span class="w">
    </span><span class="n">hi</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">yhat_test</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">q</span><span class="w">
  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="c1"># Asymmetric version: use signed residuals</span><span class="w">
    </span><span class="n">scores</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">loo_pred</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nf">rep</span><span class="p">(</span><span class="n">r</span><span class="p">,</span><span class="w"> </span><span class="n">each</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nrow</span><span class="p">(</span><span class="n">X_test</span><span class="p">))</span><span class="w">
    </span><span class="n">lo</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">apply</span><span class="p">(</span><span class="n">scores</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="n">quantile</span><span class="p">,</span><span class="w"> </span><span class="n">probs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="m">2</span><span class="p">)</span><span class="w">
    </span><span class="n">hi</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">apply</span><span class="p">(</span><span class="n">scores</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="n">quantile</span><span class="p">,</span><span class="w"> </span><span class="n">probs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="m">2</span><span class="p">)</span><span class="w">
  </span><span class="p">}</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">pred</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">yhat_test</span><span class="p">,</span><span class="w"> </span><span class="n">lo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lo</span><span class="p">,</span><span class="w"> </span><span class="n">hi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hi</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="c1"># Boston Housing example</span><span class="w">
</span><span class="n">set.seed</span><span class="p">(</span><span class="m">1</span><span class="p">)</span><span class="w">
</span><span class="n">data</span><span class="p">(</span><span class="n">Boston</span><span class="p">)</span><span class="w">
</span><span class="n">X</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">scale</span><span class="p">(</span><span class="n">as.matrix</span><span class="p">(</span><span class="n">Boston</span><span class="p">[,</span><span class="w"> </span><span class="m">-14</span><span class="p">]))</span><span class="w">
</span><span class="n">y</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">Boston</span><span class="o">$</span><span class="n">medv</span><span class="w">
</span><span class="n">n</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">nrow</span><span class="p">(</span><span class="n">X</span><span class="p">)</span><span class="w">

</span><span class="n">idx</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sample</span><span class="p">(</span><span class="nf">seq_len</span><span class="p">(</span><span class="n">n</span><span class="p">))</span><span class="w">
</span><span class="n">n_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">floor</span><span class="p">(</span><span class="m">0.7</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w">
</span><span class="n">train_i</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">idx</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="n">n_train</span><span class="p">]</span><span class="w">
</span><span class="n">test_i</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">idx</span><span class="p">[(</span><span class="n">n_train</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="o">:</span><span class="n">n</span><span class="p">]</span><span class="w">

</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">lambda</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="m">10</span><span class="p">,</span><span class="w"> </span><span class="m">50</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\nLambda ="</span><span class="p">,</span><span class="w"> </span><span class="n">lambda</span><span class="p">,</span><span class="w"> </span><span class="s2">"\n"</span><span class="p">)</span><span class="w">

  </span><span class="c1"># Asymmetric version</span><span class="w">
  </span><span class="n">res</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">jackknife_plus</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="n">train_i</span><span class="p">,</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="n">train_i</span><span class="p">],</span><span class="w"> </span><span class="n">X</span><span class="p">[</span><span class="n">test_i</span><span class="p">,</span><span class="w"> </span><span class="p">],</span><span class="w">
                        </span><span class="n">lambda</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lambda</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.1</span><span class="p">,</span><span class="w"> </span><span class="n">symmetric</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">FALSE</span><span class="p">)</span><span class="w">
  </span><span class="n">cov</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">y</span><span class="p">[</span><span class="n">test_i</span><span class="p">]</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">res</span><span class="o">$</span><span class="n">lo</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="n">test_i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">res</span><span class="o">$</span><span class="n">hi</span><span class="p">)</span><span class="w">
  </span><span class="n">width</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">res</span><span class="o">$</span><span class="n">hi</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">res</span><span class="o">$</span><span class="n">lo</span><span class="p">)</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"  Asymmetric: coverage=%.3f (target 0.90), width=%.2f\n"</span><span class="p">,</span><span class="w"> </span><span class="n">cov</span><span class="p">,</span><span class="w"> </span><span class="n">width</span><span class="p">))</span><span class="w">

  </span><span class="c1"># Symmetric version</span><span class="w">
  </span><span class="n">res_sym</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">jackknife_plus</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="n">train_i</span><span class="p">,</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="n">train_i</span><span class="p">],</span><span class="w"> </span><span class="n">X</span><span class="p">[</span><span class="n">test_i</span><span class="p">,</span><span class="w"> </span><span class="p">],</span><span class="w">
                            </span><span class="n">lambda</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lambda</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.1</span><span class="p">,</span><span class="w"> </span><span class="n">symmetric</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">)</span><span class="w">
  </span><span class="n">cov_sym</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">y</span><span class="p">[</span><span class="n">test_i</span><span class="p">]</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">res_sym</span><span class="o">$</span><span class="n">lo</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="n">test_i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">res_sym</span><span class="o">$</span><span class="n">hi</span><span class="p">)</span><span class="w">
  </span><span class="n">width_sym</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">res_sym</span><span class="o">$</span><span class="n">hi</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">res_sym</span><span class="o">$</span><span class="n">lo</span><span class="p">)</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"  Symmetric:   coverage=%.3f (target 0.90), width=%.2f\n"</span><span class="p">,</span><span class="w"> </span><span class="n">cov_sym</span><span class="p">,</span><span class="w"> </span><span class="n">width_sym</span><span class="p">))</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="c1"># Best performing model (lambda=10) for visualization</span><span class="w">
</span><span class="n">res_best</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">jackknife_plus</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="n">train_i</span><span class="p">,</span><span class="w"> </span><span class="p">],</span><span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="n">train_i</span><span class="p">],</span><span class="w"> </span><span class="n">X</span><span class="p">[</span><span class="n">test_i</span><span class="p">,</span><span class="w"> </span><span class="p">],</span><span class="w">
                           </span><span class="n">lambda</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">10</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.1</span><span class="p">,</span><span class="w"> </span><span class="n">symmetric</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">FALSE</span><span class="p">)</span><span class="w">

</span><span class="n">ord</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">order</span><span class="p">(</span><span class="n">res_best</span><span class="o">$</span><span class="n">pred</span><span class="p">)</span><span class="w">
</span><span class="n">y_test_ord</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="n">test_i</span><span class="p">][</span><span class="n">ord</span><span class="p">]</span><span class="w">
</span><span class="n">x_axis</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">seq_along</span><span class="p">(</span><span class="n">ord</span><span class="p">)</span><span class="w">

</span><span class="n">plot</span><span class="p">(</span><span class="n">x_axis</span><span class="p">,</span><span class="w"> </span><span class="n">res_best</span><span class="o">$</span><span class="n">pred</span><span class="p">[</span><span class="n">ord</span><span class="p">],</span><span class="w">
     </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"l"</span><span class="p">,</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"steelblue"</span><span class="p">,</span><span class="w"> </span><span class="n">lwd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">2</span><span class="p">,</span><span class="w">
     </span><span class="n">ylim</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">range</span><span class="p">(</span><span class="nf">c</span><span class="p">(</span><span class="n">res_best</span><span class="o">$</span><span class="n">lo</span><span class="p">,</span><span class="w"> </span><span class="n">res_best</span><span class="o">$</span><span class="n">hi</span><span class="p">,</span><span class="w"> </span><span class="n">y_test_ord</span><span class="p">)),</span><span class="w">
     </span><span class="n">xlab</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Test points (ordered by predicted value)"</span><span class="p">,</span><span class="w">
     </span><span class="n">ylab</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Median value (MEDV)"</span><span class="p">,</span><span class="w">
     </span><span class="n">main</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Boston Housing: out-of-sample jackknife+ intervals"</span><span class="p">)</span><span class="w">

</span><span class="n">polygon</span><span class="p">(</span><span class="nf">c</span><span class="p">(</span><span class="n">x_axis</span><span class="p">,</span><span class="w"> </span><span class="n">rev</span><span class="p">(</span><span class="n">x_axis</span><span class="p">)),</span><span class="w">
        </span><span class="nf">c</span><span class="p">(</span><span class="n">res_best</span><span class="o">$</span><span class="n">hi</span><span class="p">[</span><span class="n">ord</span><span class="p">],</span><span class="w"> </span><span class="n">rev</span><span class="p">(</span><span class="n">res_best</span><span class="o">$</span><span class="n">lo</span><span class="p">[</span><span class="n">ord</span><span class="p">])),</span><span class="w">
        </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rgb</span><span class="p">(</span><span class="m">0.2</span><span class="p">,</span><span class="w"> </span><span class="m">0.4</span><span class="p">,</span><span class="w"> </span><span class="m">0.8</span><span class="p">,</span><span class="w"> </span><span class="m">0.25</span><span class="p">),</span><span class="w"> </span><span class="n">border</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NA</span><span class="p">)</span><span class="w">

</span><span class="n">points</span><span class="p">(</span><span class="n">x_axis</span><span class="p">,</span><span class="w"> </span><span class="n">y_test_ord</span><span class="p">,</span><span class="w"> </span><span class="n">pch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">16</span><span class="p">,</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rgb</span><span class="p">(</span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="m">0.55</span><span class="p">))</span><span class="w">

</span><span class="n">legend</span><span class="p">(</span><span class="s2">"topleft"</span><span class="p">,</span><span class="w">
       </span><span class="n">legend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="s2">"Prediction"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Jackknife+ interval"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Held-out observations"</span><span class="p">),</span><span class="w">
       </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="s2">"steelblue"</span><span class="p">,</span><span class="w"> </span><span class="n">rgb</span><span class="p">(</span><span class="m">0.2</span><span class="p">,</span><span class="w"> </span><span class="m">0.4</span><span class="p">,</span><span class="w"> </span><span class="m">0.8</span><span class="p">,</span><span class="w"> </span><span class="m">0.4</span><span class="p">),</span><span class="w"> </span><span class="n">rgb</span><span class="p">(</span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="m">0.55</span><span class="p">)),</span><span class="w">
       </span><span class="n">lty</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="kc">NA</span><span class="p">,</span><span class="w"> </span><span class="kc">NA</span><span class="p">),</span><span class="w"> </span><span class="n">pch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="kc">NA</span><span class="p">,</span><span class="w"> </span><span class="m">15</span><span class="p">,</span><span class="w"> </span><span class="m">16</span><span class="p">),</span><span class="w"> </span><span class="n">bty</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"n"</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Lambda = 1 
  Asymmetric: coverage=0.914 (target 0.90), width=14.89
  Symmetric:   coverage=0.928 (target 0.90), width=14.78

Lambda = 10 
  Asymmetric: coverage=0.914 (target 0.90), width=14.99
  Symmetric:   coverage=0.934 (target 0.90), width=14.93

Lambda = 50 
  Asymmetric: coverage=0.947 (target 0.90), width=16.07
  Symmetric:   coverage=0.914 (target 0.90), width=14.89
</code></pre></div></div>

<p><img src="/images/2026-06-27/2026-06-27-jackknife-plus-smoothers_3_1.png" alt="image-title-here" class="img-responsive" /></p>

<h1 id="2---python-version">2 - Python version</h1>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="n">mlsauce</span>
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">import</span> <span class="nn">mlsauce</span> <span class="k">as</span> <span class="n">ms</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">from</span> <span class="nn">sklearn.datasets</span> <span class="kn">import</span> <span class="n">load_diabetes</span>
<span class="kn">from</span> <span class="nn">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">train_test_split</span>
<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">StandardScaler</span>
<span class="kn">from</span> <span class="nn">sklearn.metrics</span> <span class="kn">import</span> <span class="n">mean_squared_error</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">time</span>

<span class="n">X</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">load_diabetes</span><span class="p">(</span><span class="n">return_X_y</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">X_train</span><span class="p">,</span> <span class="n">X_test</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">y_test</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span>
    <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.3</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">123</span>
<span class="p">)</span>

<span class="n">scaler</span> <span class="o">=</span> <span class="n">StandardScaler</span><span class="p">().</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">)</span>
<span class="n">X_train</span> <span class="o">=</span> <span class="n">scaler</span><span class="p">.</span><span class="n">transform</span><span class="p">(</span><span class="n">X_train</span><span class="p">)</span>
<span class="n">X_test</span> <span class="o">=</span> <span class="n">scaler</span><span class="p">.</span><span class="n">transform</span><span class="p">(</span><span class="n">X_test</span><span class="p">)</span>

<span class="n">alpha</span> <span class="o">=</span> <span class="mf">0.10</span>

<span class="k">print</span><span class="p">(</span><span class="s">"="</span> <span class="o">*</span> <span class="mi">70</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="s">'Model'</span><span class="si">:</span><span class="mi">25</span><span class="n">s</span><span class="si">}</span><span class="s"> </span><span class="si">{</span><span class="s">'Coverage'</span><span class="si">:</span><span class="o">&gt;</span><span class="mi">10</span><span class="n">s</span><span class="si">}</span><span class="s"> </span><span class="si">{</span><span class="s">'Width'</span><span class="si">:</span><span class="o">&gt;</span><span class="mi">10</span><span class="n">s</span><span class="si">}</span><span class="s"> </span><span class="si">{</span><span class="s">'RMSE'</span><span class="si">:</span><span class="o">&gt;</span><span class="mi">10</span><span class="n">s</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">"-"</span> <span class="o">*</span> <span class="mi">70</span><span class="p">)</span>

<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">model</span> <span class="ow">in</span> <span class="p">[</span>
    <span class="p">(</span><span class="s">"Plain Ridge"</span><span class="p">,</span> <span class="n">ms</span><span class="p">.</span><span class="n">RVFLJackknifePlus</span><span class="p">(</span><span class="n">n_hidden</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">lambda_</span><span class="o">=</span><span class="mf">50.0</span><span class="p">)),</span>
    <span class="p">(</span><span class="s">"RVFL (asymmetric)"</span><span class="p">,</span> <span class="n">ms</span><span class="p">.</span><span class="n">RVFLJackknifePlus</span><span class="p">(</span><span class="n">n_hidden</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">lambda_</span><span class="o">=</span><span class="mf">50.0</span><span class="p">,</span> <span class="n">symmetric</span><span class="o">=</span><span class="bp">False</span><span class="p">)),</span>
    <span class="p">(</span><span class="s">"RVFL (symmetric)"</span><span class="p">,</span> <span class="n">ms</span><span class="p">.</span><span class="n">RVFLJackknifePlus</span><span class="p">(</span><span class="n">n_hidden</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">lambda_</span><span class="o">=</span><span class="mf">50.0</span><span class="p">,</span> <span class="n">symmetric</span><span class="o">=</span><span class="bp">True</span><span class="p">)),</span>
<span class="p">]:</span>
    <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
    <span class="n">model</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
    <span class="n">pred</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="n">alpha</span><span class="p">,</span> <span class="n">return_pi</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Elapsed: </span><span class="si">{</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

    <span class="n">cov</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">((</span><span class="n">y_test</span> <span class="o">&gt;=</span> <span class="n">pred</span><span class="p">.</span><span class="n">lower</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">y_test</span> <span class="o">&lt;=</span> <span class="n">pred</span><span class="p">.</span><span class="n">upper</span><span class="p">))</span>
    <span class="n">width</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">(</span><span class="n">pred</span><span class="p">.</span><span class="n">upper</span> <span class="o">-</span> <span class="n">pred</span><span class="p">.</span><span class="n">lower</span><span class="p">)</span>
    <span class="n">rmse</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">mean_squared_error</span><span class="p">(</span><span class="n">y_test</span><span class="p">,</span> <span class="n">pred</span><span class="p">.</span><span class="n">mean</span><span class="p">))</span>

    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">name</span><span class="si">:</span><span class="mi">25</span><span class="n">s</span><span class="si">}</span><span class="s"> </span><span class="si">{</span><span class="n">cov</span><span class="si">:</span><span class="mf">9.3</span><span class="n">f</span><span class="si">}</span><span class="s">  </span><span class="si">{</span><span class="n">width</span><span class="si">:</span><span class="mf">9.2</span><span class="n">f</span><span class="si">}</span><span class="s">  </span><span class="si">{</span><span class="n">rmse</span><span class="si">:</span><span class="mf">9.2</span><span class="n">f</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="c1"># ---- Plot: RVFL out-of-sample jackknife+ band ----
# Use the asymmetric RVFL model for visualization
</span><span class="n">model_best</span> <span class="o">=</span> <span class="n">ms</span><span class="p">.</span><span class="n">RVFLJackknifePlus</span><span class="p">(</span><span class="n">n_hidden</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">lambda_</span><span class="o">=</span><span class="mf">50.0</span><span class="p">,</span> <span class="n">symmetric</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">model_best</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
<span class="n">pred_rvfl</span> <span class="o">=</span> <span class="n">model_best</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="n">alpha</span><span class="p">,</span> <span class="n">return_pi</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

<span class="n">order</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">argsort</span><span class="p">(</span><span class="n">pred_rvfl</span><span class="p">.</span><span class="n">mean</span><span class="p">)</span>
<span class="n">x_axis</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">arange</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">order</span><span class="p">))</span>

<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">5</span><span class="p">))</span>
<span class="n">ax</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x_axis</span><span class="p">,</span> <span class="n">pred_rvfl</span><span class="p">.</span><span class="n">mean</span><span class="p">[</span><span class="n">order</span><span class="p">],</span> <span class="n">color</span><span class="o">=</span><span class="s">"darkorange"</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">"RVFL prediction"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">fill_between</span><span class="p">(</span>
    <span class="n">x_axis</span><span class="p">,</span> <span class="n">pred_rvfl</span><span class="p">.</span><span class="n">lower</span><span class="p">[</span><span class="n">order</span><span class="p">],</span> <span class="n">pred_rvfl</span><span class="p">.</span><span class="n">upper</span><span class="p">[</span><span class="n">order</span><span class="p">],</span>
    <span class="n">color</span><span class="o">=</span><span class="s">"darkorange"</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.20</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">"Jackknife+ interval"</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">scatter</span><span class="p">(</span>
    <span class="n">x_axis</span><span class="p">,</span> <span class="n">y_test</span><span class="p">[</span><span class="n">order</span><span class="p">],</span> <span class="n">color</span><span class="o">=</span><span class="s">"black"</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.55</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mi">25</span><span class="p">,</span>
    <span class="n">label</span><span class="o">=</span><span class="s">"Held-out observations"</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s">"Test points (ordered by predicted value)"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s">"Diabetes progression score"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">set_title</span><span class="p">(</span><span class="s">"RVFL + ridge read-out: out-of-sample jackknife+ intervals"</span><span class="p">)</span>
<span class="n">ax</span><span class="p">.</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="s">"upper left"</span><span class="p">,</span> <span class="n">frameon</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">fig</span><span class="p">.</span><span class="n">tight_layout</span><span class="p">()</span>
<span class="n">plt</span><span class="p">.</span><span class="n">savefig</span><span class="p">(</span><span class="s">"rvfl_jackknife_plus.png"</span><span class="p">,</span> <span class="n">dpi</span><span class="o">=</span><span class="mi">150</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Saved plot to rvfl_jackknife_plus.png"</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>======================================================================
Model                       Coverage      Width       RMSE
----------------------------------------------------------------------
Elapsed: 0.003574848175048828
Plain Ridge                   0.902     182.00      54.56
Elapsed: 0.01886749267578125
RVFL (asymmetric)             0.880     176.86      53.91
Elapsed: 0.01717209815979004
RVFL (symmetric)              0.895     182.16      53.91
</code></pre></div></div>

<p><img src="/images/2026-06-27/2026-06-27-jackknife-plus-smoothers_6_1.png" alt="image-title-here" class="img-responsive" /></p>

<p><a target="_blank" href="https://colab.research.google.com/github/Techtonique/mlsauce/blob/master/mlsauce/demo/thierrymoudiki-2026-06-27_jackknife_plus_smoothers.ipynb">
  <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" style="max-width: 100%; height: auto; width: 120px;" />
</a></p>]]></content><author><name></name></author><category term="R" /><category term="Python" /><summary type="html"><![CDATA[Fast conformal prediction for some Machine Learning models via closed-form jackknife plus (no refitting involved, just Linear Algebra).]]></summary></entry><entry><title type="html">Using scikit-learn models in R easily with the tisthemachinelearner package</title><link href="https://thierrymoudiki.github.io/blog/2026/06/21/r/tisthemllearner" rel="alternate" type="text/html" title="Using scikit-learn models in R easily with the tisthemachinelearner package" /><published>2026-06-21T00:00:00+00:00</published><updated>2026-06-21T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/06/21/r/tisthemllearner</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/06/21/r/tisthemllearner"><![CDATA[<p>This post is about the <a href="https://github.com/Techtonique/tisthemachinelearner_r/tree/main"><code class="language-plaintext highlighter-rouge">tisthemachinelearner</code> R package</a>, that allows to use scikit-learn models in R. It is a wrapper around the <a href="https://github.com/Techtonique/tisthemachinelearner/tree/main">tisthemachinelearner Python package</a>. Prediction intervals can be computed using either split conformal prediction, surrogate methods or the bootstrap.</p>

<p>First, you need to create a virtual environment and install the required packages in it. In R, you can use <code class="language-plaintext highlighter-rouge">system()</code> to run shell commands. At the command line:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># pip install uv # if necessary</span>
uv venv venv
<span class="nb">source </span>venv/bin/activate
uv pip <span class="nb">install </span>pip scikit-learn
</code></pre></div></div>

<p>In R, try:</p>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># create venv</span><span class="w">
</span><span class="n">system</span><span class="p">(</span><span class="s2">"uv venv venv"</span><span class="p">)</span><span class="w">
</span><span class="c1"># install directly into that venv</span><span class="w">
</span><span class="n">system</span><span class="p">(</span><span class="s2">"venv/bin/uv pip install pip scikit-learn"</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p>Now, the code below shows how to use <code class="language-plaintext highlighter-rouge">tisthemachinelearner</code> to train a Gradient Boosting Regressor on the <code class="language-plaintext highlighter-rouge">mtcars</code> dataset and compute prediction intervals using both the split conformal and surrogate methods. <strong>Remark</strong>: the package is also available from the <a href="https://techtonique.r-universe.dev/builds">R-universe</a>.</p>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#install.packages("remotes")</span><span class="w">
</span><span class="c1">#remotes::install_github("Techtonique/tisthemachinelearner_r")</span><span class="w">
</span><span class="c1">#install.packages("tseries")</span><span class="w">

</span><span class="n">library</span><span class="p">(</span><span class="n">tisthemachinelearner</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">tseries</span><span class="p">)</span><span class="w">

</span><span class="c1"># Data</span><span class="w">
</span><span class="n">data</span><span class="p">(</span><span class="n">mtcars</span><span class="p">)</span><span class="w">

</span><span class="c1"># Features and target</span><span class="w">
</span><span class="n">X</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">subset</span><span class="p">(</span><span class="n">mtcars</span><span class="p">,</span><span class="w">
            </span><span class="n">select</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="n">cyl</span><span class="p">,</span><span class="w"> </span><span class="n">disp</span><span class="p">,</span><span class="w"> </span><span class="n">hp</span><span class="p">,</span><span class="w"> </span><span class="n">drat</span><span class="p">,</span><span class="w"> </span><span class="n">wt</span><span class="p">,</span><span class="w"> </span><span class="n">qsec</span><span class="p">,</span><span class="w"> </span><span class="n">vs</span><span class="p">,</span><span class="w"> </span><span class="n">am</span><span class="p">,</span><span class="w"> </span><span class="n">gear</span><span class="p">,</span><span class="w"> </span><span class="n">carb</span><span class="p">))</span><span class="w">

</span><span class="n">y</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mtcars</span><span class="o">$</span><span class="n">mpg</span><span class="w">

</span><span class="c1"># Split features and target</span><span class="w">
</span><span class="n">X</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">as.matrix</span><span class="p">(</span><span class="n">mtcars</span><span class="p">[,</span><span class="w"> </span><span class="m">-1</span><span class="p">])</span><span class="w">  </span><span class="c1"># all columns except mpg</span><span class="w">
</span><span class="n">y</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mtcars</span><span class="p">[,</span><span class="w"> </span><span class="m">1</span><span class="p">]</span><span class="w">              </span><span class="c1"># mpg column</span><span class="w">

</span><span class="c1"># Create train/test split</span><span class="w">
</span><span class="n">set.seed</span><span class="p">(</span><span class="m">123</span><span class="p">)</span><span class="w">
</span><span class="n">train_idx</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sample</span><span class="p">(</span><span class="n">nrow</span><span class="p">(</span><span class="n">mtcars</span><span class="p">),</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">floor</span><span class="p">(</span><span class="m">0.7</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">nrow</span><span class="p">(</span><span class="n">mtcars</span><span class="p">)))</span><span class="w">
</span><span class="n">X_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">X</span><span class="p">[</span><span class="n">train_idx</span><span class="p">,</span><span class="w"> </span><span class="p">]</span><span class="w">
</span><span class="n">X_test</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">X</span><span class="p">[</span><span class="o">-</span><span class="n">train_idx</span><span class="p">,</span><span class="w"> </span><span class="p">]</span><span class="w">
</span><span class="n">y_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="n">train_idx</span><span class="p">]</span><span class="w">
</span><span class="n">y_test</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y</span><span class="p">[</span><span class="o">-</span><span class="n">train_idx</span><span class="p">]</span><span class="w">

</span><span class="c1"># Train a Gradient Boosting Regressor</span><span class="w">
</span><span class="n">gbr_01</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">Regressor</span><span class="o">$</span><span class="n">new</span><span class="p">(</span><span class="w">
  </span><span class="n">model_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"GradientBoostingRegressor"</span><span class="p">,</span><span class="w">
  </span><span class="n">learning_rate</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.1</span><span class="p">,</span><span class="w">
  </span><span class="n">n_estimators</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">200L</span><span class="p">,</span><span class="w">
  </span><span class="n">max_depth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3L</span><span class="p">,</span><span class="w">
  </span><span class="n">random_state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">123L</span><span class="p">,</span><span class="w">
  </span><span class="n">venv_path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"./venv"</span><span class="w"> </span><span class="c1"># this is crucial: the path to the virtual environment where scikit-learn is installed</span><span class="w">
</span><span class="p">)</span><span class="w">

</span><span class="n">gbr_01</span><span class="o">$</span><span class="n">fit</span><span class="p">(</span><span class="n">as.matrix</span><span class="p">(</span><span class="n">X_train</span><span class="p">),</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">y_train</span><span class="p">))</span><span class="w">

</span><span class="n">pred_01</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">gbr_01</span><span class="o">$</span><span class="n">predict</span><span class="p">(</span><span class="n">as.matrix</span><span class="p">(</span><span class="n">X_test</span><span class="p">))</span><span class="w">

</span><span class="c1"># Training RMSE</span><span class="w">
</span><span class="n">rmse_01</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">sqrt</span><span class="p">(</span><span class="n">mean</span><span class="p">((</span><span class="n">pred_01</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">y_test</span><span class="p">)</span><span class="o">^</span><span class="m">2</span><span class="p">))</span><span class="w">

</span><span class="n">cat</span><span class="p">(</span><span class="s2">"RMSE (learning_rate = 0.1):"</span><span class="p">,</span><span class="w"> </span><span class="n">rmse_01</span><span class="p">,</span><span class="w"> </span><span class="s2">"\n"</span><span class="p">)</span><span class="w">

</span><span class="n">gbr_001</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">Regressor</span><span class="o">$</span><span class="n">new</span><span class="p">(</span><span class="w">
  </span><span class="n">model_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"GradientBoostingRegressor"</span><span class="p">,</span><span class="w">
  </span><span class="n">learning_rate</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.01</span><span class="p">,</span><span class="w">
  </span><span class="n">n_estimators</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">200L</span><span class="p">,</span><span class="w">
  </span><span class="n">max_depth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3L</span><span class="p">,</span><span class="w">
  </span><span class="n">random_state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">123L</span><span class="p">,</span><span class="w">
  </span><span class="n">venv_path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"./venv"</span><span class="w">
</span><span class="p">)</span><span class="w">

</span><span class="n">gbr_001</span><span class="o">$</span><span class="n">fit</span><span class="p">(</span><span class="n">as.matrix</span><span class="p">(</span><span class="n">X_train</span><span class="p">),</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">y_train</span><span class="p">))</span><span class="w">

</span><span class="n">pred_001</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">gbr_001</span><span class="o">$</span><span class="n">predict</span><span class="p">(</span><span class="n">as.matrix</span><span class="p">(</span><span class="n">X_test</span><span class="p">))</span><span class="w">

</span><span class="n">rmse_001</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">sqrt</span><span class="p">(</span><span class="n">mean</span><span class="p">((</span><span class="n">pred_001</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">y_test</span><span class="p">)</span><span class="o">^</span><span class="m">2</span><span class="p">))</span><span class="w">

</span><span class="n">cat</span><span class="p">(</span><span class="s2">"RMSE (learning_rate = 0.01):"</span><span class="p">,</span><span class="w"> </span><span class="n">rmse_001</span><span class="p">,</span><span class="w"> </span><span class="s2">"\n"</span><span class="p">)</span><span class="w">

</span><span class="p">(</span><span class="n">pred_001_scp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">gbr_001</span><span class="o">$</span><span class="n">predict</span><span class="p">(</span><span class="n">as.matrix</span><span class="p">(</span><span class="n">X_test</span><span class="p">),</span><span class="w"> </span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"splitconformal"</span><span class="p">))</span><span class="w">
</span><span class="p">(</span><span class="n">pred_001_surr</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">gbr_001</span><span class="o">$</span><span class="n">predict</span><span class="p">(</span><span class="n">as.matrix</span><span class="p">(</span><span class="n">X_test</span><span class="p">),</span><span class="w"> </span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"surrogate"</span><span class="p">))</span><span class="w">


</span><span class="c1"># Test index</span><span class="w">
</span><span class="n">idx</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">seq_along</span><span class="p">(</span><span class="n">y_test</span><span class="p">)</span><span class="w">

</span><span class="c1"># Convert outputs to data frames</span><span class="w">
</span><span class="n">scp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">as.data.frame</span><span class="p">(</span><span class="n">pred_001_scp</span><span class="p">)</span><span class="w">
</span><span class="n">surr</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">as.data.frame</span><span class="p">(</span><span class="n">pred_001_surr</span><span class="p">)</span><span class="w">

</span><span class="c1"># --- Plot setup ---</span><span class="w">
</span><span class="n">plot</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span><span class="w"> </span><span class="n">y_test</span><span class="p">,</span><span class="w">
     </span><span class="n">pch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">19</span><span class="p">,</span><span class="w">
     </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"black"</span><span class="p">,</span><span class="w">
     </span><span class="n">ylim</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">range</span><span class="p">(</span><span class="nf">c</span><span class="p">(</span><span class="n">scp</span><span class="o">$</span><span class="n">lwr</span><span class="p">,</span><span class="w"> </span><span class="n">scp</span><span class="o">$</span><span class="n">upr</span><span class="p">,</span><span class="w"> </span><span class="n">surr</span><span class="o">$</span><span class="n">lwr</span><span class="p">,</span><span class="w"> </span><span class="n">surr</span><span class="o">$</span><span class="n">upr</span><span class="p">,</span><span class="w"> </span><span class="n">y_test</span><span class="p">)),</span><span class="w">
     </span><span class="n">xlab</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Test sample index"</span><span class="p">,</span><span class="w">
     </span><span class="n">ylab</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"MPG"</span><span class="p">,</span><span class="w">
     </span><span class="n">main</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Prediction intervals: Split conformal vs Surrogate"</span><span class="p">)</span><span class="w">

</span><span class="c1"># Split conformal intervals</span><span class="w">
</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">idx</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">segments</span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">scp</span><span class="o">$</span><span class="n">lwr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">scp</span><span class="o">$</span><span class="n">upr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"blue"</span><span class="p">,</span><span class="w"> </span><span class="n">lwd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">2</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="c1"># Surrogate intervals (slightly shifted for visibility)</span><span class="w">
</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">idx</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">segments</span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">surr</span><span class="o">$</span><span class="n">lwr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">surr</span><span class="o">$</span><span class="n">upr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"red"</span><span class="p">,</span><span class="w"> </span><span class="n">lwd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">2</span><span class="p">,</span><span class="w"> </span><span class="n">lty</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">2</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="c1"># Point predictions (split conformal)</span><span class="w">
</span><span class="n">points</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span><span class="w"> </span><span class="n">scp</span><span class="o">$</span><span class="n">fit</span><span class="p">,</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"blue"</span><span class="p">,</span><span class="w"> </span><span class="n">pch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">16</span><span class="p">)</span><span class="w">

</span><span class="c1"># Point predictions (surrogate)</span><span class="w">
</span><span class="n">points</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span><span class="w"> </span><span class="n">surr</span><span class="o">$</span><span class="n">fit</span><span class="p">,</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"red"</span><span class="p">,</span><span class="w"> </span><span class="n">pch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">17</span><span class="p">)</span><span class="w">

</span><span class="c1"># True values</span><span class="w">
</span><span class="n">points</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span><span class="w"> </span><span class="n">y_test</span><span class="p">,</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"black"</span><span class="p">,</span><span class="w"> </span><span class="n">pch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">19</span><span class="p">)</span><span class="w">

</span><span class="n">legend</span><span class="p">(</span><span class="s2">"bottomleft"</span><span class="p">,</span><span class="w">
       </span><span class="n">legend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="s2">"True values"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Split conformal"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Surrogate"</span><span class="p">),</span><span class="w">
       </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="s2">"black"</span><span class="p">,</span><span class="w"> </span><span class="s2">"blue"</span><span class="p">,</span><span class="w"> </span><span class="s2">"red"</span><span class="p">),</span><span class="w">
       </span><span class="n">pch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="m">19</span><span class="p">,</span><span class="w"> </span><span class="m">16</span><span class="p">,</span><span class="w"> </span><span class="m">17</span><span class="p">),</span><span class="w">
       </span><span class="n">lty</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="kc">NA</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="m">2</span><span class="p">),</span><span class="w">
       </span><span class="n">bty</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"n"</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p><img src="/images/2026-06-21/2026-06-21-image1.png" alt="image-title-here" class="img-responsive" /></p>]]></content><author><name></name></author><category term="R" /><summary type="html"><![CDATA[Using the tisthemachinelearner R package to train scikit-learn models and compute prediction intervals]]></summary></entry><entry><title type="html">No-Code Machine Learning in Excel with the Techtonique API</title><link href="https://thierrymoudiki.github.io/blog/2026/06/14/techtonique/excel-techtonique" rel="alternate" type="text/html" title="No-Code Machine Learning in Excel with the Techtonique API" /><published>2026-06-14T00:00:00+00:00</published><updated>2026-06-14T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/06/14/techtonique/excel-techtonique</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/06/14/techtonique/excel-techtonique"><![CDATA[<p><a href="https://thierrymoudiki.github.io/blog/2026/05/31/r/python/techtonique/techtonique-dot-net-is-back">Many newcomers</a> in the <a href="https://www.techtonique.net/">Techtonique API</a> these days (10x more subscribers in one month). Hope you are enjoying it.</p>

<p>The occasion for me to write (again) a short post about how to use the Techtonique API in Excel, without writing any code. A lot of people are indeed familiar with Excel, but not everyone is comfortable writing Python or R code (or <a href="https://curlconverter.com/">else</a>).</p>

<p>Under the hood, the <a href="https://lite.xlwings.org/installation">xlwings lite</a> Excel add-in (that you can install from the link) exposes <a href="https://www.techtonique.net/">Techtonique API’s</a> forecasting, regression, classification, reserving, and survival analysis functions as native worksheet functions – type a formula, select a data range, get results. That’s it.</p>

<hr />

<h2 id="setup">Setup</h2>

<p><strong>Step 1 — Get a token from Techtonique API</strong></p>

<p>Go to <a href="https://www.techtonique.net/token">https://www.techtonique.net/token</a>, sign up or log in, and copy your token. Valid for one hour. Then you can renew it as many times as you want.</p>

<p><strong>Step 2 — Store the token in Excel</strong></p>

<p>In xlwings lite, open the <strong>dropdown menu</strong> → <strong>Environment variables</strong> (see a detailed example file at <a href="https://github.com/Techtonique/techtonique-apis/blob/main/examples/excel_formulas.xlsx">https://github.com/Techtonique/techtonique-apis/blob/main/examples/excel_formulas.xlsx</a>), and add:</p>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">TECHTONIQUE_TOKEN</code></td>
      <td><em>(paste your token here)</em></td>
    </tr>
  </tbody>
</table>

<p><strong>Step 3 — Restart</strong></p>

<p>Click <strong>Restart</strong> in the dropdown menu. The token is not active until after a restart. You only need to do this once, for one hour.</p>

<hr />

<h2 id="using-the-functions">Using the functions</h2>

<p>In any cell, type <code class="language-plaintext highlighter-rouge">=TECHTO_</code> — Excel autocomplete lists everything available. The main functions are:</p>

<table>
  <thead>
    <tr>
      <th>Function</th>
      <th>Task</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">=TECHTO_FORECAST(...)</code></td>
      <td>Probabilistic time series forecasting</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">=TECHTO_MLREGRESSION(...)</code></td>
      <td>Regression with prediction intervals</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">=TECHTO_MLCLASSIFICATION(...)</code></td>
      <td>Classification</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">=TECHTO_MLRESERVING(...)</code></td>
      <td>Claims reserving (loss triangles)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">=TECHTO_SURVIVAL(...)</code></td>
      <td>Survival analysis</td>
    </tr>
  </tbody>
</table>

<p>Each function takes a <strong>data range</strong> as its first argument — just select your data in the sheet — followed by optional parameters such as the model, forecast horizon, or number of hidden features. Results are returned as a table directly in the spreadsheet.</p>

<p>If something goes wrong, the error message from the API is displayed in the cell, which makes debugging straightforward without leaving Excel.</p>

<hr />

<h2 id="help">Help</h2>

<ul>
  <li><strong>In Excel</strong>: click the function name in the formula bar to open the built-in help for that function.</li>
  <li><strong>Online reference</strong>: <a href="https://docs.techtonique.net/techtonique_api_py/techtonique_apis.html">https://docs.techtonique.net/techtonique_api_py/techtonique_apis.html</a></li>
  <li><strong>Example workbook</strong> with pre-filled formulas: <a href="https://github.com/Techtonique/techtonique-apis/blob/main/examples/excel_formulas.xlsx">https://github.com/Techtonique/techtonique-apis/blob/main/examples/excel_formulas.xlsx</a></li>
</ul>

<p><img src="/images/2025-07-07/2025-07-07-image1.gif" alt="image-title-here" class="img-responsive" /></p>]]></content><author><name></name></author><category term="Techtonique" /><summary type="html"><![CDATA[Using the Techtonique API in Excel without writing any code]]></summary></entry><entry><title type="html">How Conformal Prediction Makes Linear Models Good Enough — An Example Using R Package mlS3</title><link href="https://thierrymoudiki.github.io/blog/2026/06/07/r/conformalization-helps-weak-models" rel="alternate" type="text/html" title="How Conformal Prediction Makes Linear Models Good Enough — An Example Using R Package mlS3" /><published>2026-06-07T00:00:00+00:00</published><updated>2026-06-07T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/06/07/r/conformalization-helps-weak-models</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/06/07/r/conformalization-helps-weak-models"><![CDATA[<p>In this post, we compare <a href="https://en.wikipedia.org/wiki/Conformal_prediction">split conformal prediction</a>
across several predictive models, using <a href="https://cran.r-project.org/web/packages/mlS3/index.html">R package mlS3</a>.</p>

<p><strong>The results are deliberately thought-provoking</strong>, though limited to one dataset, so treat them
as a starting point rather than a general verdict (I <a href="https://thierrymoudiki.github.io/blog/2026/05/21/r/python/Conformalized-TabICL-nnetsauce">noticed something similar before</a>…):
Linear regression, albeit generally misspecified, requires no hyperparameter search, produces
a fully interpretable white-box model, and under split conformal prediction achieves coverage
<em>statistically indistinguishable</em> from that of gradient boosting ensembles. The residual gap in
<a href="https://otexts.com/fpp3/distaccuracy.html#winkler-score">Winkler score</a> — approximately 5 units, or 19% relative to LightGBM (see Section 2) — reflects
the cost of a wider predictive interval, not a coverage failure. In enterprise settings where
auditability, regulatory traceability, speed, and operational reproducibility carry weight
alongside predictive performance, this trade-off would’nt be a concession but indeed, a considered
engineering choice.</p>

<p>We start by installing the necessary packages, then run a single-seed experiment to illustrate the process and results. In the second part, we run a multi-seed stability analysis.</p>

<h1 id="0---installing-packages">0 - Installing packages</h1>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># --- 0. Install / load packages ----------------------------------------------</span><span class="w">

</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">requireNamespace</span><span class="p">(</span><span class="s2">"pak"</span><span class="p">,</span><span class="w"> </span><span class="n">quietly</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">))</span><span class="w"> </span><span class="n">install.packages</span><span class="p">(</span><span class="s2">"pak"</span><span class="p">)</span><span class="w">

</span><span class="n">pak</span><span class="o">::</span><span class="n">pak</span><span class="p">(</span><span class="nf">c</span><span class="p">(</span><span class="w">
  </span><span class="s2">"mlbench"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"mlS3"</span><span class="p">,</span><span class="w">          </span><span class="c1"># on CRAN — pak handles it cleanly</span><span class="w">
  </span><span class="s2">"glmnet"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"ranger"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"e1071"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"lightgbm"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"caret"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"randomForest"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"gbm"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"kknn"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"nnet"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"ggplot2"</span><span class="p">,</span><span class="w">
  </span><span class="s2">"tidyr"</span><span class="w">
</span><span class="p">))</span><span class="w">
</span></code></pre></div></div>

<h1 id="1---with-one-seed-not-stable">1 - With one seed (not stable)</h1>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># =============================================================================</span><span class="w">
</span><span class="c1"># Split Conformal Prediction as a field-leveler for tabular regression</span><span class="w">
</span><span class="c1"># Models: wrap_glmnet, wrap_ranger, wrap_svm, wrap_lightgbm, wrap_caret (x4)</span><span class="w">
</span><span class="c1"># Dataset: BostonHousing (mlbench)</span><span class="w">
</span><span class="c1"># Coverage target: 95%</span><span class="w">
</span><span class="c1"># No tuning — all default hyperparameters</span><span class="w">
</span><span class="c1"># Metrics: empirical coverage, mean interval length, Winkler score</span><span class="w">
</span><span class="c1"># =============================================================================</span><span class="w">

</span><span class="c1"># --- 0. Install / load packages ----------------------------------------------</span><span class="w">

</span><span class="n">library</span><span class="p">(</span><span class="n">mlS3</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">mlbench</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">ggplot2</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">scales</span><span class="p">)</span><span class="w">

</span><span class="c1"># --- 1. Data -----------------------------------------------------------------</span><span class="w">

</span><span class="n">data</span><span class="p">(</span><span class="n">BostonHousing</span><span class="p">)</span><span class="w">
</span><span class="n">df</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">BostonHousing</span><span class="w">
</span><span class="n">df</span><span class="o">$</span><span class="n">chas</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">df</span><span class="o">$</span><span class="n">chas</span><span class="p">)</span><span class="w">

</span><span class="n">set.seed</span><span class="p">(</span><span class="m">42</span><span class="p">)</span><span class="w"> </span><span class="c1"># in the next section, we run multiple seeds to stabilize the results</span><span class="w">
</span><span class="n">n</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">nrow</span><span class="p">(</span><span class="n">df</span><span class="p">)</span><span class="w">
</span><span class="n">y_all</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">df</span><span class="o">$</span><span class="n">medv</span><span class="w">
</span><span class="n">X_all</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">as.data.frame</span><span class="p">(</span><span class="n">df</span><span class="p">[,</span><span class="w"> </span><span class="nf">names</span><span class="p">(</span><span class="n">df</span><span class="p">)</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="s2">"medv"</span><span class="p">])</span><span class="w">

</span><span class="c1"># 50% train | 30% calibration | 20% test</span><span class="w">
</span><span class="c1"># larger calibration set → stable quantile estimate</span><span class="w">
</span><span class="n">idx_test</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sample</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="m">0.20</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="p">))</span><span class="w">
</span><span class="n">rest</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">setdiff</span><span class="p">(</span><span class="nf">seq_len</span><span class="p">(</span><span class="n">n</span><span class="p">),</span><span class="w"> </span><span class="n">idx_test</span><span class="p">)</span><span class="w">
</span><span class="n">idx_cal</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sample</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="m">0.30</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="p">))</span><span class="w">
</span><span class="n">idx_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">setdiff</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span><span class="w"> </span><span class="n">idx_cal</span><span class="p">)</span><span class="w">

</span><span class="n">X_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">X_all</span><span class="p">[</span><span class="n">idx_train</span><span class="p">,</span><span class="w"> </span><span class="p">];</span><span class="w"> </span><span class="n">y_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y_all</span><span class="p">[</span><span class="n">idx_train</span><span class="p">]</span><span class="w">
</span><span class="n">X_cal</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">X_all</span><span class="p">[</span><span class="n">idx_cal</span><span class="p">,</span><span class="w">   </span><span class="p">];</span><span class="w"> </span><span class="n">y_cal</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y_all</span><span class="p">[</span><span class="n">idx_cal</span><span class="p">]</span><span class="w">
</span><span class="n">X_test</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">X_all</span><span class="p">[</span><span class="n">idx_test</span><span class="p">,</span><span class="w">  </span><span class="p">];</span><span class="w"> </span><span class="n">y_test</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y_all</span><span class="p">[</span><span class="n">idx_test</span><span class="p">]</span><span class="w">

</span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"Train: %d | Cal: %d | Test: %d\n"</span><span class="p">,</span><span class="w">
            </span><span class="nf">length</span><span class="p">(</span><span class="n">idx_train</span><span class="p">),</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">idx_cal</span><span class="p">),</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">idx_test</span><span class="p">)))</span><span class="w">

</span><span class="c1"># --- 2. Model zoo ------------------------------------------------------------</span><span class="w">

</span><span class="n">models</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"glmnet (ridge)"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_glmnet</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"glmnet (lasso)"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_glmnet</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"ranger (RF)"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_ranger</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">num.trees</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">500L</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"SVM (radial)"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_svm</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">kernel</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"radial"</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"LightGBM"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_lightgbm</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="w">
         </span><span class="n">params</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">objective</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"regression"</span><span class="p">,</span><span class="w"> </span><span class="n">verbose</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">-1</span><span class="p">),</span><span class="w">
         </span><span class="n">nrounds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">100</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"caret: lm"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_caret</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"lm"</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"caret: knn"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_caret</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"kknn"</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"caret: rf"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_caret</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"rf"</span><span class="p">,</span><span class="w"> </span><span class="n">mtry</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3L</span><span class="p">))</span><span class="w">
</span><span class="p">)</span><span class="w">

</span><span class="c1"># --- 3. Run ------------------------------------------------------------------</span><span class="w">
</span><span class="c1"># Stores: results (summary metrics), cal_residuals_all, test_preds_all</span><span class="w">

</span><span class="n">alpha_main</span><span class="w">        </span><span class="o">&lt;-</span><span class="w"> </span><span class="m">0.05</span><span class="w">
</span><span class="n">results</span><span class="w">           </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">vector</span><span class="p">(</span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">models</span><span class="p">))</span><span class="w">
</span><span class="n">cal_residuals_all</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">list</span><span class="p">()</span><span class="w">
</span><span class="n">test_preds_all</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">list</span><span class="p">()</span><span class="w">

</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="nf">seq_along</span><span class="p">(</span><span class="n">models</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">m</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">models</span><span class="p">[[</span><span class="n">i</span><span class="p">]]</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"\n[%d/%d] Fitting: %s ...\n"</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">models</span><span class="p">),</span><span class="w"> </span><span class="n">m</span><span class="o">$</span><span class="n">label</span><span class="p">))</span><span class="w">

  </span><span class="n">res</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">tryCatch</span><span class="p">({</span><span class="w">

    </span><span class="n">mod</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">do.call</span><span class="p">(</span><span class="n">m</span><span class="o">$</span><span class="n">fit_fn</span><span class="p">,</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="nf">list</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span><span class="w"> </span><span class="n">y_train</span><span class="p">),</span><span class="w"> </span><span class="n">m</span><span class="o">$</span><span class="n">fit_args</span><span class="p">))</span><span class="w">

    </span><span class="c1"># calibration nonconformity scores</span><span class="w">
    </span><span class="n">cal_preds</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">predict</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span><span class="w"> </span><span class="n">newx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">X_cal</span><span class="p">)</span><span class="w">
    </span><span class="n">scores</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="nf">abs</span><span class="p">(</span><span class="n">cal_preds</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">y_cal</span><span class="p">))</span><span class="w">

    </span><span class="c1"># finite-sample corrected conformal quantile</span><span class="w">
    </span><span class="n">n_cal</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">scores</span><span class="p">)</span><span class="w">
    </span><span class="n">q_level</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">min</span><span class="p">(</span><span class="nf">ceiling</span><span class="p">((</span><span class="n">n_cal</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">))</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">n_cal</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w">
    </span><span class="n">q_hat</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">quantile</span><span class="p">(</span><span class="n">scores</span><span class="p">,</span><span class="w"> </span><span class="n">probs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">q_level</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">))</span><span class="w">

    </span><span class="c1"># test predictions and intervals</span><span class="w">
    </span><span class="n">test_preds</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">predict</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span><span class="w"> </span><span class="n">newx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">X_test</span><span class="p">))</span><span class="w">
    </span><span class="n">lower</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">test_preds</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">q_hat</span><span class="w">
    </span><span class="n">upper</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">test_preds</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">q_hat</span><span class="w">
    </span><span class="n">covered</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="p">(</span><span class="n">y_test</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">lower</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="p">(</span><span class="n">y_test</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">upper</span><span class="p">)</span><span class="w">
    </span><span class="n">width</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">upper</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower</span><span class="w">

    </span><span class="c1"># Winkler score — penalty is distance to nearest bound, always positive</span><span class="w">
    </span><span class="n">penalty</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ifelse</span><span class="p">(</span><span class="o">!</span><span class="n">covered</span><span class="p">,</span><span class="w">
                      </span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ifelse</span><span class="p">(</span><span class="n">y_test</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">lower</span><span class="p">,</span><span class="w">
                                                </span><span class="n">lower</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">y_test</span><span class="p">,</span><span class="w">
                                                </span><span class="n">y_test</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">upper</span><span class="p">),</span><span class="w">
                      </span><span class="m">0</span><span class="p">)</span><span class="w">

    </span><span class="nf">list</span><span class="p">(</span><span class="w">
      </span><span class="n">scores</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="n">scores</span><span class="p">,</span><span class="w">
      </span><span class="n">test_preds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">test_preds</span><span class="p">,</span><span class="w">
      </span><span class="n">q_hat</span><span class="w">      </span><span class="o">=</span><span class="w"> </span><span class="n">q_hat</span><span class="p">,</span><span class="w">
      </span><span class="n">coverage</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">covered</span><span class="p">),</span><span class="w">
      </span><span class="n">mean_len</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">width</span><span class="p">),</span><span class="w">
      </span><span class="n">winkler</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">width</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">penalty</span><span class="p">)</span><span class="w">
    </span><span class="p">)</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="n">error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">cat</span><span class="p">(</span><span class="s2">"  ERROR:"</span><span class="p">,</span><span class="w"> </span><span class="n">conditionMessage</span><span class="p">(</span><span class="n">e</span><span class="p">),</span><span class="w"> </span><span class="s2">"\n"</span><span class="p">);</span><span class="w"> </span><span class="kc">NULL</span><span class="w"> </span><span class="p">})</span><span class="w">

  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nf">is.null</span><span class="p">(</span><span class="n">res</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="n">results</span><span class="p">[[</span><span class="n">i</span><span class="p">]]</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">data.frame</span><span class="p">(</span><span class="w">
      </span><span class="n">Model</span><span class="w">       </span><span class="o">=</span><span class="w"> </span><span class="n">m</span><span class="o">$</span><span class="n">label</span><span class="p">,</span><span class="w">
      </span><span class="n">Coverage</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="n">res</span><span class="o">$</span><span class="n">coverage</span><span class="p">,</span><span class="w"> </span><span class="m">3</span><span class="p">),</span><span class="w">
      </span><span class="n">Mean_Length</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="n">res</span><span class="o">$</span><span class="n">mean_len</span><span class="p">,</span><span class="w"> </span><span class="m">3</span><span class="p">),</span><span class="w">
      </span><span class="n">Winkler</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="n">res</span><span class="o">$</span><span class="n">winkler</span><span class="p">,</span><span class="w">  </span><span class="m">3</span><span class="p">),</span><span class="w">
      </span><span class="n">q_hat</span><span class="w">       </span><span class="o">=</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="n">res</span><span class="o">$</span><span class="n">q_hat</span><span class="p">,</span><span class="w">    </span><span class="m">3</span><span class="p">),</span><span class="w">
      </span><span class="n">stringsAsFactors</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">FALSE</span><span class="w">
    </span><span class="p">)</span><span class="w">
    </span><span class="n">cal_residuals_all</span><span class="p">[[</span><span class="n">m</span><span class="o">$</span><span class="n">label</span><span class="p">]]</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">data.frame</span><span class="p">(</span><span class="w">
      </span><span class="n">Model</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">m</span><span class="o">$</span><span class="n">label</span><span class="p">,</span><span class="w">
      </span><span class="n">resid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">res</span><span class="o">$</span><span class="n">scores</span><span class="p">,</span><span class="w">
      </span><span class="n">q_hat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">res</span><span class="o">$</span><span class="n">q_hat</span><span class="p">,</span><span class="w">
      </span><span class="n">row.names</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="w">
    </span><span class="p">)</span><span class="w">
    </span><span class="n">test_preds_all</span><span class="p">[[</span><span class="n">m</span><span class="o">$</span><span class="n">label</span><span class="p">]]</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">res</span><span class="o">$</span><span class="n">test_preds</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="c1"># --- 4. Summary table --------------------------------------------------------</span><span class="w">

</span><span class="n">summary_df</span><span class="w">         </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">do.call</span><span class="p">(</span><span class="n">rbind</span><span class="p">,</span><span class="w"> </span><span class="n">Filter</span><span class="p">(</span><span class="n">Negate</span><span class="p">(</span><span class="n">is.null</span><span class="p">),</span><span class="w"> </span><span class="n">results</span><span class="p">))</span><span class="w">
</span><span class="n">summary_df</span><span class="o">$</span><span class="n">Cov_Dev</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="n">summary_df</span><span class="o">$</span><span class="n">Coverage</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">),</span><span class="w"> </span><span class="m">3</span><span class="p">)</span><span class="w">
</span><span class="n">summary_df</span><span class="w">         </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">summary_df</span><span class="p">[</span><span class="n">order</span><span class="p">(</span><span class="n">summary_df</span><span class="o">$</span><span class="n">Winkler</span><span class="p">),</span><span class="w"> </span><span class="p">]</span><span class="w">
</span><span class="n">rownames</span><span class="p">(</span><span class="n">summary_df</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="kc">NULL</span><span class="w">

</span><span class="n">cat</span><span class="p">(</span><span class="s2">"\n\n========== Split Conformal Prediction — BostonHousing ==========\n"</span><span class="p">)</span><span class="w">
</span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"Nominal coverage: %.0f%%  |  alpha = %.2f\n\n"</span><span class="p">,</span><span class="w">
            </span><span class="m">100</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">),</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">))</span><span class="w">
</span><span class="n">print</span><span class="p">(</span><span class="n">summary_df</span><span class="p">,</span><span class="w"> </span><span class="n">row.names</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">FALSE</span><span class="p">)</span><span class="w">
</span><span class="n">cat</span><span class="p">(</span><span class="s2">"=================================================================\n\n"</span><span class="p">)</span><span class="w">

</span><span class="c1"># --- 5. Plots — main metrics -------------------------------------------------</span><span class="w">

</span><span class="c1"># 5a. Coverage with deviation annotation</span><span class="w">
</span><span class="n">p_cov</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">summary_df</span><span class="p">,</span><span class="w">
                </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reorder</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">Coverage</span><span class="p">),</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Coverage</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_col</span><span class="p">(</span><span class="n">fill</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#4C72B0"</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.85</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_hline</span><span class="p">(</span><span class="n">yintercept</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">,</span><span class="w"> </span><span class="n">linetype</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"dashed"</span><span class="p">,</span><span class="w">
             </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"firebrick"</span><span class="p">,</span><span class="w"> </span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.8</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_text</span><span class="p">(</span><span class="n">aes</span><span class="p">(</span><span class="n">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"%+.1f%%"</span><span class="p">,</span><span class="w"> </span><span class="n">Cov_Dev</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="m">100</span><span class="p">)),</span><span class="w">
            </span><span class="n">hjust</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">-0.15</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3.2</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"grey30"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">annotate</span><span class="p">(</span><span class="s2">"text"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.6</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">0.005</span><span class="p">,</span><span class="w">
           </span><span class="n">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"95% target"</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"firebrick"</span><span class="p">,</span><span class="w"> </span><span class="n">hjust</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3.5</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">coord_flip</span><span class="p">(</span><span class="n">ylim</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="m">0.80</span><span class="p">,</span><span class="w"> </span><span class="m">1.02</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Empirical Coverage — the leveled field"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"All conformalized models should hover near 95%\nAnnotation = deviation from nominal coverage"</span><span class="p">,</span><span class="w">
       </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Empirical coverage"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_cov</span><span class="p">)</span><span class="w">

</span><span class="c1"># 5b. Mean interval length</span><span class="w">
</span><span class="n">p_len</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">summary_df</span><span class="p">,</span><span class="w">
                </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reorder</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="n">Mean_Length</span><span class="p">),</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Mean_Length</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_col</span><span class="p">(</span><span class="n">fill</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#55A868"</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.85</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">coord_flip</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Mean Interval Length — where models diverge"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Sharper (shorter) intervals → better-calibrated base model"</span><span class="p">,</span><span class="w">
       </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Mean interval length (same units as medv)"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_len</span><span class="p">)</span><span class="w">

</span><span class="c1"># 5c. Winkler score</span><span class="w">
</span><span class="n">p_wink</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">summary_df</span><span class="p">,</span><span class="w">
                 </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reorder</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="n">Winkler</span><span class="p">),</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Winkler</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_col</span><span class="p">(</span><span class="n">fill</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#C44E52"</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.85</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">coord_flip</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Winkler Score — the composite verdict"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Lower is better (penalises width and coverage failures)"</span><span class="p">,</span><span class="w">
       </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Winkler score"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_wink</span><span class="p">)</span><span class="w">

</span><span class="c1"># 5d. Coverage vs interval length scatter</span><span class="w">
</span><span class="n">p_scatter</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">summary_df</span><span class="p">,</span><span class="w">
                    </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Mean_Length</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Coverage</span><span class="p">,</span><span class="w"> </span><span class="n">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Model</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_point</span><span class="p">(</span><span class="n">aes</span><span class="p">(</span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Winkler</span><span class="p">),</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">4</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_text</span><span class="p">(</span><span class="n">vjust</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">-0.8</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3</span><span class="p">,</span><span class="w"> </span><span class="n">check_overlap</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_hline</span><span class="p">(</span><span class="n">yintercept</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">,</span><span class="w"> </span><span class="n">linetype</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"dashed"</span><span class="p">,</span><span class="w">
             </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"firebrick"</span><span class="p">,</span><span class="w"> </span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.7</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">scale_colour_gradient</span><span class="p">(</span><span class="n">low</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#55A868"</span><span class="p">,</span><span class="w"> </span><span class="n">high</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#C44E52"</span><span class="p">,</span><span class="w">
                        </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Winkler\nscore"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Coverage vs Interval Length"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Coverage converges; length is where quality shows"</span><span class="p">,</span><span class="w">
       </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Mean interval length"</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Empirical coverage"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_scatter</span><span class="p">)</span><span class="w">

</span><span class="c1"># 5e. Winkler lollipop coloured by coverage</span><span class="w">
</span><span class="n">p_tradeoff</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">summary_df</span><span class="p">,</span><span class="w">
                     </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reorder</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">Winkler</span><span class="p">)))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_segment</span><span class="p">(</span><span class="n">aes</span><span class="p">(</span><span class="n">xend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reorder</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">Winkler</span><span class="p">),</span><span class="w">
                   </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="n">yend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Winkler</span><span class="p">),</span><span class="w">
               </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"grey70"</span><span class="p">,</span><span class="w"> </span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.8</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_point</span><span class="p">(</span><span class="n">aes</span><span class="p">(</span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Winkler</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Coverage</span><span class="p">),</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">5</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">scale_colour_gradient2</span><span class="p">(</span><span class="w">
    </span><span class="n">low</span><span class="w">      </span><span class="o">=</span><span class="w"> </span><span class="s2">"#C44E52"</span><span class="p">,</span><span class="w">
    </span><span class="n">mid</span><span class="w">      </span><span class="o">=</span><span class="w"> </span><span class="s2">"#f7f7f7"</span><span class="p">,</span><span class="w">
    </span><span class="n">high</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="s2">"#4C72B0"</span><span class="p">,</span><span class="w">
    </span><span class="n">midpoint</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">,</span><span class="w">
    </span><span class="n">name</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="s2">"Empirical\ncoverage"</span><span class="w">
  </span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">coord_flip</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Winkler Score vs Coverage — the lm surprise"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="w">
         </span><span class="s2">"lm hits exactly 95% coverage; tree ensembles are sharper but under-cover,\n"</span><span class="p">,</span><span class="w">
         </span><span class="s2">"which the Winkler penalty exposes"</span><span class="p">),</span><span class="w">
       </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Winkler score (lower = better)"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_tradeoff</span><span class="p">)</span><span class="w">

</span><span class="c1"># --- 6. Calibration residual distributions -----------------------------------</span><span class="w">

</span><span class="n">cal_df</span><span class="w">       </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">do.call</span><span class="p">(</span><span class="n">rbind</span><span class="p">,</span><span class="w"> </span><span class="n">cal_residuals_all</span><span class="p">)</span><span class="w">
</span><span class="n">rownames</span><span class="p">(</span><span class="n">cal_df</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="kc">NULL</span><span class="w">
</span><span class="n">cal_df</span><span class="o">$</span><span class="n">Model</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">factor</span><span class="p">(</span><span class="n">cal_df</span><span class="o">$</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">levels</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rev</span><span class="p">(</span><span class="n">summary_df</span><span class="o">$</span><span class="n">Model</span><span class="p">))</span><span class="w">
</span><span class="n">q_hat_df</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">unique</span><span class="p">(</span><span class="n">cal_df</span><span class="p">[,</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="s2">"Model"</span><span class="p">,</span><span class="w"> </span><span class="s2">"q_hat"</span><span class="p">)])</span><span class="w">

</span><span class="n">p_resid</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">cal_df</span><span class="p">,</span><span class="w"> </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">resid</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_histogram</span><span class="p">(</span><span class="n">aes</span><span class="p">(</span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">after_stat</span><span class="p">(</span><span class="n">density</span><span class="p">)),</span><span class="w">
                 </span><span class="n">bins</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">30</span><span class="p">,</span><span class="w"> </span><span class="n">fill</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#4C72B0"</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.6</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_density</span><span class="p">(</span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#4C72B0"</span><span class="p">,</span><span class="w"> </span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.7</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_vline</span><span class="p">(</span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">q_hat_df</span><span class="p">,</span><span class="w">
             </span><span class="n">aes</span><span class="p">(</span><span class="n">xintercept</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">q_hat</span><span class="p">),</span><span class="w">
             </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"firebrick"</span><span class="p">,</span><span class="w"> </span><span class="n">linetype</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"dashed"</span><span class="p">,</span><span class="w"> </span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.8</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">facet_wrap</span><span class="p">(</span><span class="o">~</span><span class="w"> </span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">scales</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"free_y"</span><span class="p">,</span><span class="w"> </span><span class="n">ncol</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="w">
    </span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Calibration absolute residuals per model"</span><span class="p">,</span><span class="w">
    </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="w">
      </span><span class="s2">"Red dashed line = q̂ (conformal quantile = half interval width)\n"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"lm residuals are compact and well-concentrated → small q̂ relative to its coverage\n"</span><span class="p">,</span><span class="w">
      </span><span class="s2">"Tree ensembles: tight residuals but right-tail outliers push q̂ enough to under-cover"</span><span class="p">),</span><span class="w">
    </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"| y_cal − ŷ_cal |"</span><span class="p">,</span><span class="w">
    </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Density"</span><span class="w">
  </span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">11</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme</span><span class="p">(</span><span class="n">strip.text</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">element_text</span><span class="p">(</span><span class="n">face</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"bold"</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">9</span><span class="p">))</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_resid</span><span class="p">)</span><span class="w">

</span><span class="c1"># --- 7. Winkler vs alpha sweep -----------------------------------------------</span><span class="w">
</span><span class="c1"># No refitting: reuses cal_residuals_all and test_preds_all from section 3</span><span class="w">

</span><span class="n">alpha_grid</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="m">0.01</span><span class="p">,</span><span class="w"> </span><span class="m">0.05</span><span class="p">,</span><span class="w"> </span><span class="m">0.10</span><span class="p">,</span><span class="w"> </span><span class="m">0.15</span><span class="p">,</span><span class="w"> </span><span class="m">0.20</span><span class="p">,</span><span class="w"> </span><span class="m">0.25</span><span class="p">,</span><span class="w"> </span><span class="m">0.30</span><span class="p">)</span><span class="w">
</span><span class="n">model_labels</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">names</span><span class="p">(</span><span class="n">test_preds_all</span><span class="p">)</span><span class="w">

</span><span class="n">sweep_rows</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">vector</span><span class="p">(</span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">alpha_grid</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">model_labels</span><span class="p">))</span><span class="w">
</span><span class="n">k</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="m">1L</span><span class="w">

</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">a</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">alpha_grid</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">lab</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">model_labels</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">

    </span><span class="n">scores</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">cal_residuals_all</span><span class="p">[[</span><span class="n">lab</span><span class="p">]]</span><span class="o">$</span><span class="n">resid</span><span class="p">)</span><span class="w">
    </span><span class="n">test_preds</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">test_preds_all</span><span class="p">[[</span><span class="n">lab</span><span class="p">]])</span><span class="w">
    </span><span class="n">y</span><span class="w">          </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">y_test</span><span class="p">)</span><span class="w">

    </span><span class="n">n_cal</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">scores</span><span class="p">)</span><span class="w">
    </span><span class="n">q_level</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">min</span><span class="p">(</span><span class="nf">ceiling</span><span class="p">((</span><span class="n">n_cal</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">a</span><span class="p">))</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">n_cal</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w">
    </span><span class="n">q_hat</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">quantile</span><span class="p">(</span><span class="n">scores</span><span class="p">,</span><span class="w"> </span><span class="n">probs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">q_level</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">))</span><span class="w">

    </span><span class="n">lower</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">test_preds</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">q_hat</span><span class="w">
    </span><span class="n">upper</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">test_preds</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">q_hat</span><span class="w">
    </span><span class="n">covered</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="p">(</span><span class="n">y</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">lower</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="p">(</span><span class="n">y</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">upper</span><span class="p">)</span><span class="w">
    </span><span class="n">width</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">upper</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower</span><span class="w">
    </span><span class="n">penalty</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ifelse</span><span class="p">(</span><span class="o">!</span><span class="n">covered</span><span class="p">,</span><span class="w">
                      </span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">a</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ifelse</span><span class="p">(</span><span class="n">y</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">lower</span><span class="p">,</span><span class="w"> </span><span class="n">lower</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">upper</span><span class="p">),</span><span class="w">
                      </span><span class="m">0</span><span class="p">)</span><span class="w">

    </span><span class="n">sweep_rows</span><span class="p">[[</span><span class="n">k</span><span class="p">]]</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">data.frame</span><span class="p">(</span><span class="w">
      </span><span class="n">Model</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="nf">as.character</span><span class="p">(</span><span class="n">lab</span><span class="p">),</span><span class="w">
      </span><span class="n">alpha</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">a</span><span class="p">),</span><span class="w">
      </span><span class="n">nominal</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">a</span><span class="p">),</span><span class="w">
      </span><span class="n">Coverage</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">mean</span><span class="p">(</span><span class="n">covered</span><span class="p">)),</span><span class="w">
      </span><span class="n">Winkler</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">mean</span><span class="p">(</span><span class="n">width</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">penalty</span><span class="p">)),</span><span class="w">
      </span><span class="n">stringsAsFactors</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">FALSE</span><span class="p">,</span><span class="w">
      </span><span class="n">row.names</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="w">
    </span><span class="p">)</span><span class="w">
    </span><span class="n">k</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1L</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">sweep_df</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">do.call</span><span class="p">(</span><span class="n">rbind.data.frame</span><span class="p">,</span><span class="w"> </span><span class="n">sweep_rows</span><span class="p">)</span><span class="w">
</span><span class="n">rownames</span><span class="p">(</span><span class="n">sweep_df</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="kc">NULL</span><span class="w">
</span><span class="n">sweep_df</span><span class="o">$</span><span class="n">Model</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">factor</span><span class="p">(</span><span class="n">sweep_df</span><span class="o">$</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">levels</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rev</span><span class="p">(</span><span class="nf">as.character</span><span class="p">(</span><span class="n">summary_df</span><span class="o">$</span><span class="n">Model</span><span class="p">)))</span><span class="w">

</span><span class="c1"># 7a. Winkler score vs nominal coverage level</span><span class="w">
</span><span class="n">p7a</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">sweep_df</span><span class="p">,</span><span class="w">
              </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nominal</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Winkler</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">group</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Model</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_line</span><span class="p">(</span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.9</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.85</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_point</span><span class="p">(</span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">2.5</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_vline</span><span class="p">(</span><span class="n">xintercept</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">,</span><span class="w">
             </span><span class="n">linetype</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"dashed"</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"grey40"</span><span class="p">,</span><span class="w"> </span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.6</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">annotate</span><span class="p">(</span><span class="s2">"text"</span><span class="p">,</span><span class="w">
           </span><span class="n">x</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">0.004</span><span class="p">,</span><span class="w">
           </span><span class="n">y</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="nf">max</span><span class="p">(</span><span class="n">sweep_df</span><span class="o">$</span><span class="n">Winkler</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="m">0.98</span><span class="p">,</span><span class="w">
           </span><span class="n">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"main α (%.0f%%)"</span><span class="p">,</span><span class="w"> </span><span class="m">100</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">)),</span><span class="w">
           </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"grey40"</span><span class="p">,</span><span class="w"> </span><span class="n">hjust</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3.2</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">scale_x_continuous</span><span class="p">(</span><span class="n">name</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="s2">"Nominal coverage (1 − α)"</span><span class="p">,</span><span class="w">
                     </span><span class="n">breaks</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_grid</span><span class="p">,</span><span class="w">
                     </span><span class="n">labels</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">percent_format</span><span class="p">(</span><span class="n">accuracy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">scale_y_continuous</span><span class="p">(</span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Winkler score (lower = better)"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">scale_colour_brewer</span><span class="p">(</span><span class="n">palette</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Dark2"</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Winkler score across coverage targets"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="w">
         </span><span class="s2">"Tight targets (99%): miss penalty 2/α = 200 → calibration dominates, lm wins\n"</span><span class="p">,</span><span class="w">
         </span><span class="s2">"Loose targets (70%): penalty shrinks to 6.7 → sharpness dominates, ensembles win"</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme</span><span class="p">(</span><span class="n">legend.position</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="s2">"right"</span><span class="p">,</span><span class="w">
        </span><span class="n">legend.key.width</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">unit</span><span class="p">(</span><span class="m">1.5</span><span class="p">,</span><span class="w"> </span><span class="s2">"lines"</span><span class="p">))</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p7a</span><span class="p">)</span><span class="w">

</span><span class="c1"># 7b. Empirical vs nominal coverage — conformal guarantee check</span><span class="w">
</span><span class="n">p7b</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">sweep_df</span><span class="p">,</span><span class="w">
              </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nominal</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Coverage</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">group</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Model</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_abline</span><span class="p">(</span><span class="n">slope</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="n">intercept</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">,</span><span class="w">
              </span><span class="n">linetype</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"dashed"</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"firebrick"</span><span class="p">,</span><span class="w"> </span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.8</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_line</span><span class="p">(</span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.9</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.85</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_point</span><span class="p">(</span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">2.5</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">annotate</span><span class="p">(</span><span class="s2">"text"</span><span class="p">,</span><span class="w">
           </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.715</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.745</span><span class="p">,</span><span class="w">
           </span><span class="n">label</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="s2">"perfect calibration"</span><span class="p">,</span><span class="w">
           </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"firebrick"</span><span class="p">,</span><span class="w"> </span><span class="n">angle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">34</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3.2</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">scale_x_continuous</span><span class="p">(</span><span class="n">name</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="s2">"Nominal coverage (1 − α)"</span><span class="p">,</span><span class="w">
                     </span><span class="n">breaks</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_grid</span><span class="p">,</span><span class="w">
                     </span><span class="n">labels</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">percent_format</span><span class="p">(</span><span class="n">accuracy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">),</span><span class="w">
                     </span><span class="n">limits</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="m">0.68</span><span class="p">,</span><span class="w"> </span><span class="m">1.00</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">scale_y_continuous</span><span class="p">(</span><span class="n">name</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="s2">"Empirical coverage"</span><span class="p">,</span><span class="w">
                     </span><span class="n">labels</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">percent_format</span><span class="p">(</span><span class="n">accuracy</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">),</span><span class="w">
                     </span><span class="n">limits</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="m">0.68</span><span class="p">,</span><span class="w"> </span><span class="m">1.00</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">scale_colour_brewer</span><span class="p">(</span><span class="n">palette</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Dark2"</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Empirical vs nominal coverage across α values"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="w">
         </span><span class="s2">"All models should track or exceed the diagonal — the marginal conformal guarantee\n"</span><span class="p">,</span><span class="w">
         </span><span class="s2">"Dipping below the line would indicate a violation"</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme</span><span class="p">(</span><span class="n">legend.position</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="s2">"right"</span><span class="p">,</span><span class="w">
        </span><span class="n">legend.key.width</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">unit</span><span class="p">(</span><span class="m">1.5</span><span class="p">,</span><span class="w"> </span><span class="s2">"lines"</span><span class="p">))</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p7b</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Train: 253 | Cal: 152 | Test: 101

[1/8] Fitting: glmnet (ridge) ...

[2/8] Fitting: glmnet (lasso) ...

[3/8] Fitting: ranger (RF) ...

[4/8] Fitting: SVM (radial) ...

[5/8] Fitting: LightGBM ...

[6/8] Fitting: caret: lm ...

[7/8] Fitting: caret: knn ...

[8/8] Fitting: caret: rf ...


========== Split Conformal Prediction — BostonHousing ==========
Nominal coverage: 95%  |  alpha = 0.05

          Model Coverage Mean_Length Winkler  q_hat Cov_Dev
       LightGBM    0.901      13.708  37.531  6.854  -0.049
      caret: lm    0.950      21.305  38.969 10.653   0.000
 glmnet (lasso)    0.931      20.519  41.052 10.260  -0.019
    ranger (RF)    0.881      13.430  48.011  6.715  -0.069
   SVM (radial)    0.901      15.894  48.032  7.947  -0.049
      caret: rf    0.881      13.306  48.354  6.653  -0.069
     caret: knn    0.871      16.127  50.213  8.063  -0.079
 glmnet (ridge)    0.921      32.728  55.507 16.364  -0.029
=================================================================
</code></pre></div></div>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_4_1.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_4_2.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_4_3.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_4_4.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_4_5.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_4_6.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_4_8.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_4_9.png" alt="image-title-here" class="img-responsive" /></p>

<h1 id="2---with-multiple-seeds-more-stable-results">2 - With multiple seeds (more stable results)</h1>

<p>The previous section used only one seed, which could make the result fragile. This section uses 10 different data splits to measure coverages and Winkler scores.</p>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># =============================================================================</span><span class="w">
</span><span class="c1"># Split Conformal Prediction — multi-seed stability analysis</span><span class="w">
</span><span class="c1"># Wraps the single-seed loop in an outer seed loop.</span><span class="w">
</span><span class="c1"># Reports mean ± sd of Coverage and Winkler per model across seeds,</span><span class="w">
</span><span class="c1"># so that single-split variance doesn't drive the ranking.</span><span class="w">
</span><span class="c1"># =============================================================================</span><span class="w">

</span><span class="c1"># --- 0. Load packages --------------------------------------------------------</span><span class="w">

</span><span class="n">library</span><span class="p">(</span><span class="n">mlS3</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">mlbench</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">ggplot2</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">scales</span><span class="p">)</span><span class="w">

</span><span class="c1"># --- 1. Data -----------------------------------------------------------------</span><span class="w">

</span><span class="n">data</span><span class="p">(</span><span class="n">BostonHousing</span><span class="p">)</span><span class="w">
</span><span class="n">df</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">BostonHousing</span><span class="w">
</span><span class="n">df</span><span class="o">$</span><span class="n">chas</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">df</span><span class="o">$</span><span class="n">chas</span><span class="p">)</span><span class="w">   </span><span class="c1"># coerce factor so all models see numeric input</span><span class="w">

</span><span class="n">n</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">nrow</span><span class="p">(</span><span class="n">df</span><span class="p">)</span><span class="w">
</span><span class="n">y_all</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">df</span><span class="o">$</span><span class="n">medv</span><span class="w">
</span><span class="n">X_all</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">as.data.frame</span><span class="p">(</span><span class="n">df</span><span class="p">[,</span><span class="w"> </span><span class="nf">names</span><span class="p">(</span><span class="n">df</span><span class="p">)</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="s2">"medv"</span><span class="p">])</span><span class="w">

</span><span class="c1"># --- 2. Model zoo ------------------------------------------------------------</span><span class="w">

</span><span class="n">models</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"glmnet (ridge)"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_glmnet</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"glmnet (lasso)"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_glmnet</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"ranger (RF)"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_ranger</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">num.trees</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">500L</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"SVM (radial)"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_svm</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">kernel</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"radial"</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"LightGBM"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_lightgbm</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="w">
         </span><span class="n">params</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">objective</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"regression"</span><span class="p">,</span><span class="w"> </span><span class="n">verbose</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">-1</span><span class="p">),</span><span class="w">
         </span><span class="n">nrounds</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">100</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"caret: lm"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_caret</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"lm"</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"caret: knn"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_caret</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"kknn"</span><span class="p">)),</span><span class="w">

  </span><span class="nf">list</span><span class="p">(</span><span class="n">label</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"caret: rf"</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_fn</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">wrap_caret</span><span class="p">,</span><span class="w">
       </span><span class="n">fit_args</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"rf"</span><span class="p">,</span><span class="w"> </span><span class="n">mtry</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3L</span><span class="p">))</span><span class="w">
</span><span class="p">)</span><span class="w">

</span><span class="c1"># --- 3. Multi-seed conformal loop --------------------------------------------</span><span class="w">
</span><span class="c1"># Each seed produces an independent 50/30/20 split; we refit every model and</span><span class="w">
</span><span class="c1"># record Coverage and Winkler. Aggregating over seeds averages out the ~±5pp</span><span class="w">
</span><span class="c1"># sampling noise that dominates single-split comparisons (n_test ≈ 100).</span><span class="w">

</span><span class="n">alpha_main</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="m">0.05</span><span class="w">
</span><span class="n">seeds</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="m">42</span><span class="p">,</span><span class="w"> </span><span class="m">123</span><span class="p">,</span><span class="w"> </span><span class="m">2024</span><span class="p">,</span><span class="w"> </span><span class="m">314</span><span class="p">,</span><span class="w"> </span><span class="m">999</span><span class="p">,</span><span class="w"> </span><span class="m">7</span><span class="p">,</span><span class="w"> </span><span class="m">2025</span><span class="p">,</span><span class="w"> </span><span class="m">1234</span><span class="p">,</span><span class="w"> </span><span class="m">77</span><span class="p">,</span><span class="w"> </span><span class="m">42000</span><span class="p">)</span><span class="w">

</span><span class="c1"># all_runs: one row per (seed × model)</span><span class="w">
</span><span class="n">all_runs</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">vector</span><span class="p">(</span><span class="s2">"list"</span><span class="p">,</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">seeds</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">models</span><span class="p">))</span><span class="w">
</span><span class="n">k</span><span class="w">        </span><span class="o">&lt;-</span><span class="w"> </span><span class="m">1L</span><span class="w">

</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">s</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">seeds</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">

  </span><span class="n">set.seed</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w">
  </span><span class="n">idx_test</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sample</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="m">0.20</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="p">))</span><span class="w">
  </span><span class="n">rest</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">setdiff</span><span class="p">(</span><span class="nf">seq_len</span><span class="p">(</span><span class="n">n</span><span class="p">),</span><span class="w"> </span><span class="n">idx_test</span><span class="p">)</span><span class="w">
  </span><span class="n">idx_cal</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sample</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="m">0.30</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="p">))</span><span class="w">
  </span><span class="n">idx_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">setdiff</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span><span class="w"> </span><span class="n">idx_cal</span><span class="p">)</span><span class="w">

  </span><span class="n">X_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">X_all</span><span class="p">[</span><span class="n">idx_train</span><span class="p">,</span><span class="w"> </span><span class="p">];</span><span class="w"> </span><span class="n">y_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y_all</span><span class="p">[</span><span class="n">idx_train</span><span class="p">]</span><span class="w">
  </span><span class="n">X_cal</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">X_all</span><span class="p">[</span><span class="n">idx_cal</span><span class="p">,</span><span class="w">   </span><span class="p">];</span><span class="w"> </span><span class="n">y_cal</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y_all</span><span class="p">[</span><span class="n">idx_cal</span><span class="p">]</span><span class="w">
  </span><span class="n">X_test</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">X_all</span><span class="p">[</span><span class="n">idx_test</span><span class="p">,</span><span class="w">  </span><span class="p">];</span><span class="w"> </span><span class="n">y_test</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y_all</span><span class="p">[</span><span class="n">idx_test</span><span class="p">]</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"\nSeed %d — Train: %d | Cal: %d | Test: %d\n"</span><span class="p">,</span><span class="w">
              </span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">idx_train</span><span class="p">),</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">idx_cal</span><span class="p">),</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">idx_test</span><span class="p">)))</span><span class="w">

  </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="nf">seq_along</span><span class="p">(</span><span class="n">models</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="n">m</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">models</span><span class="p">[[</span><span class="n">i</span><span class="p">]]</span><span class="w">

    </span><span class="n">res</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">tryCatch</span><span class="p">({</span><span class="w">

      </span><span class="n">mod</span><span class="w">       </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">do.call</span><span class="p">(</span><span class="n">m</span><span class="o">$</span><span class="n">fit_fn</span><span class="p">,</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="nf">list</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span><span class="w"> </span><span class="n">y_train</span><span class="p">),</span><span class="w"> </span><span class="n">m</span><span class="o">$</span><span class="n">fit_args</span><span class="p">))</span><span class="w">
      </span><span class="n">cal_preds</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">predict</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span><span class="w"> </span><span class="n">newx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">X_cal</span><span class="p">)</span><span class="w">
      </span><span class="n">scores</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="nf">abs</span><span class="p">(</span><span class="n">cal_preds</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">y_cal</span><span class="p">))</span><span class="w">

      </span><span class="c1"># finite-sample corrected conformal quantile (Vovk et al. 2005)</span><span class="w">
      </span><span class="n">n_cal</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">scores</span><span class="p">)</span><span class="w">
      </span><span class="n">q_level</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">min</span><span class="p">(</span><span class="nf">ceiling</span><span class="p">((</span><span class="n">n_cal</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">))</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">n_cal</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w">
      </span><span class="n">q_hat</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">quantile</span><span class="p">(</span><span class="n">scores</span><span class="p">,</span><span class="w"> </span><span class="n">probs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">q_level</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">))</span><span class="w">

      </span><span class="n">test_preds</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">as.numeric</span><span class="p">(</span><span class="n">predict</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span><span class="w"> </span><span class="n">newx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">X_test</span><span class="p">))</span><span class="w">
      </span><span class="n">lower</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">test_preds</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">q_hat</span><span class="w">
      </span><span class="n">upper</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">test_preds</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">q_hat</span><span class="w">
      </span><span class="n">covered</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="p">(</span><span class="n">y_test</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">lower</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="p">(</span><span class="n">y_test</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">upper</span><span class="p">)</span><span class="w">
      </span><span class="n">width</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">upper</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower</span><span class="w">

      </span><span class="n">penalty</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ifelse</span><span class="p">(</span><span class="o">!</span><span class="n">covered</span><span class="p">,</span><span class="w">
                        </span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">ifelse</span><span class="p">(</span><span class="n">y_test</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">lower</span><span class="p">,</span><span class="w">
                                                  </span><span class="n">lower</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">y_test</span><span class="p">,</span><span class="w">
                                                  </span><span class="n">y_test</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">upper</span><span class="p">),</span><span class="w">
                        </span><span class="m">0</span><span class="p">)</span><span class="w">

      </span><span class="n">data.frame</span><span class="p">(</span><span class="w">
        </span><span class="n">Seed</span><span class="w">        </span><span class="o">=</span><span class="w"> </span><span class="n">s</span><span class="p">,</span><span class="w">
        </span><span class="n">Model</span><span class="w">       </span><span class="o">=</span><span class="w"> </span><span class="n">m</span><span class="o">$</span><span class="n">label</span><span class="p">,</span><span class="w">
        </span><span class="n">Coverage</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">covered</span><span class="p">),</span><span class="w">
        </span><span class="n">Mean_Length</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">width</span><span class="p">),</span><span class="w">
        </span><span class="n">Winkler</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">width</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">penalty</span><span class="p">),</span><span class="w">
        </span><span class="n">q_hat</span><span class="w">       </span><span class="o">=</span><span class="w"> </span><span class="n">q_hat</span><span class="p">,</span><span class="w">
        </span><span class="n">stringsAsFactors</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">FALSE</span><span class="w">
      </span><span class="p">)</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="n">error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"  ERROR [%s]: %s\n"</span><span class="p">,</span><span class="w"> </span><span class="n">m</span><span class="o">$</span><span class="n">label</span><span class="p">,</span><span class="w"> </span><span class="n">conditionMessage</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span><span class="w">
      </span><span class="kc">NULL</span><span class="w">
    </span><span class="p">})</span><span class="w">

    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nf">is.null</span><span class="p">(</span><span class="n">res</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">all_runs</span><span class="p">[[</span><span class="n">k</span><span class="p">]]</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="p">}</span><span class="w">
    </span><span class="n">k</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1L</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">runs_df</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">do.call</span><span class="p">(</span><span class="n">rbind</span><span class="p">,</span><span class="w"> </span><span class="n">Filter</span><span class="p">(</span><span class="n">Negate</span><span class="p">(</span><span class="n">is.null</span><span class="p">),</span><span class="w"> </span><span class="n">all_runs</span><span class="p">))</span><span class="w">
</span><span class="n">rownames</span><span class="p">(</span><span class="n">runs_df</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="kc">NULL</span><span class="w">

</span><span class="c1"># --- 4. Aggregate: mean ± sd per model ---------------------------------------</span><span class="w">

</span><span class="n">agg</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">aggregate</span><span class="p">(</span><span class="n">cbind</span><span class="p">(</span><span class="n">Coverage</span><span class="p">,</span><span class="w"> </span><span class="n">Mean_Length</span><span class="p">,</span><span class="w"> </span><span class="n">Winkler</span><span class="p">,</span><span class="w"> </span><span class="n">q_hat</span><span class="p">)</span><span class="w"> </span><span class="o">~</span><span class="w"> </span><span class="n">Model</span><span class="p">,</span><span class="w">
                    </span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">runs_df</span><span class="p">,</span><span class="w"> </span><span class="n">FUN</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">)</span><span class="w">
</span><span class="n">agg_sd</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">aggregate</span><span class="p">(</span><span class="n">cbind</span><span class="p">(</span><span class="n">Coverage</span><span class="p">,</span><span class="w"> </span><span class="n">Mean_Length</span><span class="p">,</span><span class="w"> </span><span class="n">Winkler</span><span class="p">,</span><span class="w"> </span><span class="n">q_hat</span><span class="p">)</span><span class="w"> </span><span class="o">~</span><span class="w"> </span><span class="n">Model</span><span class="p">,</span><span class="w">
                    </span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">runs_df</span><span class="p">,</span><span class="w"> </span><span class="n">FUN</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sd</span><span class="p">)</span><span class="w">

</span><span class="nf">names</span><span class="p">(</span><span class="n">agg_sd</span><span class="p">)[</span><span class="m">-1</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="nf">names</span><span class="p">(</span><span class="n">agg_sd</span><span class="p">)[</span><span class="m">-1</span><span class="p">],</span><span class="w"> </span><span class="s2">"_sd"</span><span class="p">)</span><span class="w">
</span><span class="n">summary_df</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">merge</span><span class="p">(</span><span class="n">agg</span><span class="p">,</span><span class="w"> </span><span class="n">agg_sd</span><span class="p">,</span><span class="w"> </span><span class="n">by</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Model"</span><span class="p">)</span><span class="w">

</span><span class="n">summary_df</span><span class="o">$</span><span class="n">Cov_Dev</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="n">summary_df</span><span class="o">$</span><span class="n">Coverage</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="p">(</span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">),</span><span class="w"> </span><span class="m">3</span><span class="p">)</span><span class="w">

</span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">col</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="nf">names</span><span class="p">(</span><span class="n">summary_df</span><span class="p">)[</span><span class="m">-1</span><span class="p">])</span><span class="w"> </span><span class="n">summary_df</span><span class="p">[[</span><span class="n">col</span><span class="p">]]</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">round</span><span class="p">(</span><span class="n">summary_df</span><span class="p">[[</span><span class="n">col</span><span class="p">]],</span><span class="w"> </span><span class="m">3</span><span class="p">)</span><span class="w">

</span><span class="n">summary_df</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">summary_df</span><span class="p">[</span><span class="n">order</span><span class="p">(</span><span class="n">summary_df</span><span class="o">$</span><span class="n">Winkler</span><span class="p">),</span><span class="w"> </span><span class="p">]</span><span class="w">
</span><span class="n">rownames</span><span class="p">(</span><span class="n">summary_df</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="kc">NULL</span><span class="w">

</span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"\n\n===== Split Conformal — BostonHousing | %d seeds =====\n"</span><span class="p">,</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">seeds</span><span class="p">)))</span><span class="w">
</span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"Nominal coverage: 95%%  |  alpha = %.2f\n\n"</span><span class="p">,</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">))</span><span class="w">
</span><span class="n">print</span><span class="p">(</span><span class="n">summary_df</span><span class="p">[,</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="s2">"Model"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Coverage"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Coverage_sd"</span><span class="p">,</span><span class="w">
                      </span><span class="s2">"Mean_Length"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Mean_Length_sd"</span><span class="p">,</span><span class="w">
                      </span><span class="s2">"Winkler"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Winkler_sd"</span><span class="p">,</span><span class="w"> </span><span class="s2">"Cov_Dev"</span><span class="p">)],</span><span class="w">
      </span><span class="n">row.names</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">FALSE</span><span class="p">)</span><span class="w">
</span><span class="n">cat</span><span class="p">(</span><span class="s2">"=======================================================\n\n"</span><span class="p">)</span><span class="w">

</span><span class="c1"># --- 5. Plots ----------------------------------------------------------------</span><span class="w">

</span><span class="c1"># 5a. Mean coverage ± 1 sd</span><span class="w">
</span><span class="c1"># Models whose bar reliably clips the 95% line meet the guarantee across splits;</span><span class="w">
</span><span class="c1"># those consistently below it have a structural under-coverage problem.</span><span class="w">
</span><span class="n">p_cov</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">summary_df</span><span class="p">,</span><span class="w">
                </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reorder</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">Coverage</span><span class="p">),</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Coverage</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_col</span><span class="p">(</span><span class="n">fill</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#4C72B0"</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.85</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_errorbar</span><span class="p">(</span><span class="n">aes</span><span class="p">(</span><span class="n">ymin</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Coverage</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">Coverage_sd</span><span class="p">,</span><span class="w">
                    </span><span class="n">ymax</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Coverage</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Coverage_sd</span><span class="p">),</span><span class="w">
                </span><span class="n">width</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"grey30"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_hline</span><span class="p">(</span><span class="n">yintercept</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">,</span><span class="w"> </span><span class="n">linetype</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"dashed"</span><span class="p">,</span><span class="w">
             </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"firebrick"</span><span class="p">,</span><span class="w"> </span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.8</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">annotate</span><span class="p">(</span><span class="s2">"text"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.6</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">0.005</span><span class="p">,</span><span class="w">
           </span><span class="n">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"95% target"</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"firebrick"</span><span class="p">,</span><span class="w"> </span><span class="n">hjust</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3.5</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">coord_flip</span><span class="p">(</span><span class="n">ylim</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">c</span><span class="p">(</span><span class="m">0.75</span><span class="p">,</span><span class="w"> </span><span class="m">1.10</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Mean empirical coverage across seeds"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"Error bars = ±1 sd over %d seeds"</span><span class="p">,</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">seeds</span><span class="p">)),</span><span class="w">
       </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Empirical coverage"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_cov</span><span class="p">)</span><span class="w">

</span><span class="c1"># 5b. Mean Winkler ± 1 sd</span><span class="w">
</span><span class="c1"># Overlapping error bars → ranking not stable across splits.</span><span class="w">
</span><span class="c1"># Non-overlapping → difference is robust to split variance.</span><span class="w">
</span><span class="n">p_wink</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">summary_df</span><span class="p">,</span><span class="w">
                 </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reorder</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="n">Winkler</span><span class="p">),</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Winkler</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_col</span><span class="p">(</span><span class="n">fill</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#C44E52"</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.85</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_errorbar</span><span class="p">(</span><span class="n">aes</span><span class="p">(</span><span class="n">ymin</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Winkler</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">Winkler_sd</span><span class="p">,</span><span class="w">
                    </span><span class="n">ymax</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Winkler</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Winkler_sd</span><span class="p">),</span><span class="w">
                </span><span class="n">width</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"grey30"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">coord_flip</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Mean Winkler score across seeds"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"Error bars = ±1 sd over %d seeds | lower = better"</span><span class="p">,</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">seeds</span><span class="p">)),</span><span class="w">
       </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Winkler score"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_wink</span><span class="p">)</span><span class="w">

</span><span class="c1"># 5c. Per-seed coverage jitter</span><span class="w">
</span><span class="c1"># Full distribution across seeds; reveals systematic under-coverage vs. high variance.</span><span class="w">
</span><span class="n">p_jit_cov</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">runs_df</span><span class="p">,</span><span class="w">
                    </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reorder</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">Coverage</span><span class="p">,</span><span class="w"> </span><span class="n">FUN</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">),</span><span class="w">
                        </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Coverage</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_jitter</span><span class="p">(</span><span class="n">width</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.15</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.6</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#4C72B0"</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">2</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">stat_summary</span><span class="p">(</span><span class="n">fun</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">,</span><span class="w"> </span><span class="n">geom</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"point"</span><span class="p">,</span><span class="w"> </span><span class="n">shape</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">18</span><span class="p">,</span><span class="w">
               </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">4</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"black"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_hline</span><span class="p">(</span><span class="n">yintercept</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">alpha_main</span><span class="p">,</span><span class="w"> </span><span class="n">linetype</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"dashed"</span><span class="p">,</span><span class="w">
             </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"firebrick"</span><span class="p">,</span><span class="w"> </span><span class="n">linewidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.8</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">coord_flip</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Per-seed coverage distribution"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Diamond = mean; jitter = individual seeds"</span><span class="p">,</span><span class="w">
       </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Empirical coverage"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_jit_cov</span><span class="p">)</span><span class="w">

</span><span class="c1"># 5d. Per-seed Winkler jitter</span><span class="w">
</span><span class="n">p_jit_wink</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ggplot</span><span class="p">(</span><span class="n">runs_df</span><span class="p">,</span><span class="w">
                     </span><span class="n">aes</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reorder</span><span class="p">(</span><span class="n">Model</span><span class="p">,</span><span class="w"> </span><span class="n">Winkler</span><span class="p">,</span><span class="w"> </span><span class="n">FUN</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">),</span><span class="w">
                         </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Winkler</span><span class="p">))</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">geom_jitter</span><span class="p">(</span><span class="n">width</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.15</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.6</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#C44E52"</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">2</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">stat_summary</span><span class="p">(</span><span class="n">fun</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">,</span><span class="w"> </span><span class="n">geom</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"point"</span><span class="p">,</span><span class="w"> </span><span class="n">shape</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">18</span><span class="p">,</span><span class="w">
               </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">4</span><span class="p">,</span><span class="w"> </span><span class="n">colour</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"black"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">coord_flip</span><span class="p">()</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">labs</span><span class="p">(</span><span class="n">title</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">"Per-seed Winkler score distribution"</span><span class="p">,</span><span class="w">
       </span><span class="n">subtitle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Diamond = mean; jitter = individual seeds | lower = better"</span><span class="p">,</span><span class="w">
       </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Winkler score"</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w">
  </span><span class="n">theme_minimal</span><span class="p">(</span><span class="n">base_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">12</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">p_jit_wink</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Seed 42 — Train: 253 | Cal: 152 | Test: 101

Seed 123 — Train: 253 | Cal: 152 | Test: 101

Seed 2024 — Train: 253 | Cal: 152 | Test: 101

Seed 314 — Train: 253 | Cal: 152 | Test: 101

Seed 999 — Train: 253 | Cal: 152 | Test: 101

Seed 7 — Train: 253 | Cal: 152 | Test: 101

Seed 2025 — Train: 253 | Cal: 152 | Test: 101

Seed 1234 — Train: 253 | Cal: 152 | Test: 101

Seed 77 — Train: 253 | Cal: 152 | Test: 101

Seed 42000 — Train: 253 | Cal: 152 | Test: 101


===== Split Conformal — BostonHousing | 10 seeds =====
Nominal coverage: 95%  |  alpha = 0.05

          Model Coverage Coverage_sd Mean_Length Mean_Length_sd Winkler
       LightGBM    0.944       0.026      16.195          2.047  27.435
      caret: rf    0.940       0.029      15.421          2.723  28.460
    ranger (RF)    0.941       0.032      15.559          2.728  28.672
      caret: lm    0.948       0.033      20.258          3.879  32.668
   SVM (radial)    0.946       0.042      17.808          3.795  34.129
 glmnet (lasso)    0.946       0.030      21.361          3.950  34.222
     caret: knn    0.947       0.038      20.307          4.157  36.279
 glmnet (ridge)    0.948       0.017      35.807          6.309  49.028
 Winkler_sd Cov_Dev
      5.342  -0.006
      9.722  -0.010
      9.922  -0.009
      7.725  -0.002
     11.908  -0.004
      8.640  -0.004
      9.474  -0.003
      5.271  -0.002
=======================================================
</code></pre></div></div>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_7_1.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_7_2.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_7_3.png" alt="image-title-here" class="img-responsive" /></p>

<p><img src="/images/2026-06-07/2026-06-07-conformalization-helps-weak-models_7_4.png" alt="image-title-here" class="img-responsive" /></p>]]></content><author><name></name></author><category term="R" /><summary type="html"><![CDATA[A comparison of split conformal prediction across several predictive models, using R package mlS3, on the BostonHousing dataset]]></summary></entry><entry><title type="html">Techtonique dot net, the Machine Learning web API, is back online (but more like a passion project for now)</title><link href="https://thierrymoudiki.github.io/blog/2026/05/31/r/python/techtonique/techtonique-dot-net-is-back" rel="alternate" type="text/html" title="Techtonique dot net, the Machine Learning web API, is back online (but more like a passion project for now)" /><published>2026-05-31T00:00:00+00:00</published><updated>2026-05-31T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/05/31/r/python/techtonique/techtonique-dot-net-is-back</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/05/31/r/python/techtonique/techtonique-dot-net-is-back"><![CDATA[<p><a href="https://www.techtonique.net">https://www.techtonique.net</a> contains tools for <strong>Exploratory Data Analysis</strong> (EDA), <strong>editors</strong> for R and Python code, tools for <strong>data visualization</strong>, <strong>no-code web interfaces</strong> for various data science tasks, <strong>a language-agnostic API</strong> for machine learning tasks (classification, regression, survival analysis, reserving, forecasting etc.).</p>

<p>I recently noticed a <strong>spike</strong> in sign-ups (not sure how they noticed it was up again, without official announcement…), and I thought it was a good opportunity to share that <strong><a href="https://www.techtonique.net">techtonique.net</a> is back</strong>. More like a passion project, or part of a portfolio (for now). The API is available and evolving. You can use it for free (with rate limiting), but please note that it is slightly slower than it used to be (indeed, I used to have Azure Credits thanks to Microsoft for Startups  =&gt; a faster server). It still serves the responses, in a reasonable time though, and I will try to optimize it as much as possible.</p>

<p>It is worth mentioning that I removed the stochastic simulation API for now, as it required (more technical) to run R in Python, through a Docker container.</p>

<p>Here are some examples of how to use the API for machine learning tasks in R and Python (there are also no-code interfaces for these tasks in the website, and the API is language-agnostic, so you can use it with any programming language that can make HTTP requests):</p>

<p>The starting point is to signup/login (if you’re facing issues, contact support@techtonique.net) and get a token from: <a href="https://www.techtonique.net/token">https://www.techtonique.net/token</a>. Then, you can use the token in API requests for machine learning tasks. Each response is a prediction, as envisaged by the chosen model, and based on the input data.</p>

<h1 id="1---r-example">1 - R example:</h1>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env Rscript</span><span class="w">

</span><span class="c1"># Install httr if needed: install.packages("httr")</span><span class="w">
</span><span class="c1"># All you need is a token from www.techtonique.net/token, then run the script</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">httr</span><span class="p">)</span><span class="w">

</span><span class="n">BASE_URL</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="s2">"https://www.techtonique.net"</span><span class="w">
</span><span class="n">GITHUB_RAW</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="s2">"https://raw.githubusercontent.com/Techtonique/datasets/main"</span><span class="w">

</span><span class="n">DATASETS</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="w">
  </span><span class="n">univariate</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="n">GITHUB_RAW</span><span class="p">,</span><span class="w"> </span><span class="s2">"/time_series/univariate/a10.csv"</span><span class="p">),</span><span class="w">
  </span><span class="n">multivariate</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="n">GITHUB_RAW</span><span class="p">,</span><span class="w"> </span><span class="s2">"/time_series/multivariate/ice_cream_vs_heater.csv"</span><span class="p">),</span><span class="w">
  </span><span class="n">classification</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="n">GITHUB_RAW</span><span class="p">,</span><span class="w"> </span><span class="s2">"/tabular/classification/breast_cancer_dataset2.csv"</span><span class="p">),</span><span class="w">
  </span><span class="n">regression</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="n">GITHUB_RAW</span><span class="p">,</span><span class="w"> </span><span class="s2">"/tabular/regression/boston_dataset2.csv"</span><span class="p">),</span><span class="w">
  </span><span class="n">raa</span><span class="w">            </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="n">GITHUB_RAW</span><span class="p">,</span><span class="w"> </span><span class="s2">"/tabular/triangle/raa.csv"</span><span class="p">),</span><span class="w">
  </span><span class="n">abc</span><span class="w">            </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="n">GITHUB_RAW</span><span class="p">,</span><span class="w"> </span><span class="s2">"/tabular/triangle/abc.csv"</span><span class="p">),</span><span class="w">
  </span><span class="n">km</span><span class="w">             </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="n">GITHUB_RAW</span><span class="p">,</span><span class="w"> </span><span class="s2">"/tabular/survival/kidney.csv"</span><span class="p">),</span><span class="w">
  </span><span class="n">ridge_survival</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="n">GITHUB_RAW</span><span class="p">,</span><span class="w"> </span><span class="s2">"/tabular/survival/gbsg2_2.csv"</span><span class="p">)</span><span class="w">
</span><span class="p">)</span><span class="w">

</span><span class="c1"># ---------------------------------------------------------------------------</span><span class="w">
</span><span class="c1"># Helpers</span><span class="w">
</span><span class="c1"># ---------------------------------------------------------------------------</span><span class="w">

</span><span class="n">get_token</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">args</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">commandArgs</span><span class="p">(</span><span class="n">trailingOnly</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">)</span><span class="w">
  </span><span class="n">idx</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">which</span><span class="p">(</span><span class="n">args</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s2">"--token"</span><span class="p">)</span><span class="w">
  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nf">length</span><span class="p">(</span><span class="n">idx</span><span class="p">)</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="m">0</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">idx</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">args</span><span class="p">))</span><span class="w"> </span><span class="nf">return</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="n">idx</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">])</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"Please enter your JWT token: "</span><span class="p">)</span><span class="w">
  </span><span class="n">readLines</span><span class="p">(</span><span class="n">con</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"stdin"</span><span class="p">,</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="c1"># Download a GitHub dataset to a temp file and return its path.</span><span class="w">
</span><span class="c1"># Using a real file is the only reliable way to do multipart uploads in httr.</span><span class="w">
</span><span class="n">fetch_dataset</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">url</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">DATASETS</span><span class="p">[[</span><span class="n">key</span><span class="p">]]</span><span class="w">
  </span><span class="n">filename</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">basename</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"  Fetching %s from GitHub... "</span><span class="p">,</span><span class="w"> </span><span class="n">filename</span><span class="p">))</span><span class="w">
  </span><span class="n">tmp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">tempfile</span><span class="p">(</span><span class="n">fileext</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">".csv"</span><span class="p">)</span><span class="w">
  </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">GET</span><span class="p">(</span><span class="n">url</span><span class="p">,</span><span class="w"> </span><span class="n">write_disk</span><span class="p">(</span><span class="n">tmp</span><span class="p">,</span><span class="w"> </span><span class="n">overwrite</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">))</span><span class="w">
  </span><span class="n">stop_for_status</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"OK\n"</span><span class="p">)</span><span class="w">
  </span><span class="n">tmp</span><span class="w">   </span><span class="c1"># return the temp file path</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">make_request</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w"> </span><span class="n">dataset_key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">url</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">paste0</span><span class="p">(</span><span class="n">BASE_URL</span><span class="p">,</span><span class="w"> </span><span class="n">endpoint</span><span class="p">)</span><span class="w">
  </span><span class="n">headers</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">add_headers</span><span class="p">(</span><span class="n">Authorization</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">paste</span><span class="p">(</span><span class="s2">"Bearer"</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">))</span><span class="w">

  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nf">is.null</span><span class="p">(</span><span class="n">dataset_key</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="n">tmp_path</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">fetch_dataset</span><span class="p">(</span><span class="n">dataset_key</span><span class="p">)</span><span class="w">
    </span><span class="nf">on.exit</span><span class="p">(</span><span class="n">unlink</span><span class="p">(</span><span class="n">tmp_path</span><span class="p">),</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">)</span><span class="w">   </span><span class="c1"># clean up temp file when done</span><span class="w">
    </span><span class="n">body</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">upload_file</span><span class="p">(</span><span class="n">tmp_path</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"text/csv"</span><span class="p">))</span><span class="w">
    </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">POST</span><span class="p">(</span><span class="n">url</span><span class="p">,</span><span class="w"> </span><span class="n">headers</span><span class="p">,</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">params</span><span class="p">,</span><span class="w"> </span><span class="n">body</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">body</span><span class="p">,</span><span class="w"> </span><span class="n">encode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"multipart"</span><span class="p">)</span><span class="w">
  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">GET</span><span class="p">(</span><span class="n">url</span><span class="p">,</span><span class="w"> </span><span class="n">headers</span><span class="p">,</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">params</span><span class="p">)</span><span class="w">
  </span><span class="p">}</span><span class="w">

  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">http_error</span><span class="p">(</span><span class="n">resp</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"  ERROR %s: %s\n"</span><span class="p">,</span><span class="w"> </span><span class="n">status_code</span><span class="p">(</span><span class="n">resp</span><span class="p">),</span><span class="w">
                </span><span class="n">content</span><span class="p">(</span><span class="n">resp</span><span class="p">,</span><span class="w"> </span><span class="n">as</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"text"</span><span class="p">,</span><span class="w"> </span><span class="n">encoding</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"UTF-8"</span><span class="p">)))</span><span class="w">
    </span><span class="nf">return</span><span class="p">(</span><span class="kc">NULL</span><span class="p">)</span><span class="w">
  </span><span class="p">}</span><span class="w">
  </span><span class="n">content</span><span class="p">(</span><span class="n">resp</span><span class="p">,</span><span class="w"> </span><span class="n">as</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"parsed"</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"application/json"</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">print_response</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nf">is.null</span><span class="p">(</span><span class="n">resp</span><span class="p">))</span><span class="w"> </span><span class="nf">return</span><span class="p">(</span><span class="nf">invisible</span><span class="p">(</span><span class="kc">NULL</span><span class="p">))</span><span class="w">
  </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">key</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="nf">names</span><span class="p">(</span><span class="n">resp</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="n">val</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">resp</span><span class="p">[[</span><span class="n">key</span><span class="p">]]</span><span class="w">
    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nf">is.list</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nf">length</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="m">6</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"  %s: [%s ...]\n"</span><span class="p">,</span><span class="w"> </span><span class="n">key</span><span class="p">,</span><span class="w"> </span><span class="n">paste</span><span class="p">(</span><span class="n">head</span><span class="p">(</span><span class="n">unlist</span><span class="p">(</span><span class="n">val</span><span class="p">),</span><span class="w"> </span><span class="m">6</span><span class="p">),</span><span class="w"> </span><span class="n">collapse</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">", "</span><span class="p">)))</span><span class="w">
    </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"  %s: %s\n"</span><span class="p">,</span><span class="w"> </span><span class="n">key</span><span class="p">,</span><span class="w"> </span><span class="n">paste</span><span class="p">(</span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="n">collapse</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">", "</span><span class="p">)))</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="c1"># ---------------------------------------------------------------------------</span><span class="w">
</span><span class="c1"># Test sections</span><span class="w">
</span><span class="c1"># ---------------------------------------------------------------------------</span><span class="w">

</span><span class="n">test_forecasting</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">token</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\n=== Testing Forecasting Endpoints ===\n"</span><span class="p">)</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\nTesting univariate forecasting...\n"</span><span class="p">)</span><span class="w">
  </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">make_request</span><span class="p">(</span><span class="s2">"/forecasting"</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w">
    </span><span class="n">dataset_key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"univariate"</span><span class="p">,</span><span class="w">
    </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">base_model</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"RidgeCV"</span><span class="p">,</span><span class="w"> </span><span class="n">n_hidden_features</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">5</span><span class="p">,</span><span class="w">
                  </span><span class="n">lags</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">25</span><span class="p">,</span><span class="w"> </span><span class="n">type_pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"kde"</span><span class="p">,</span><span class="w"> </span><span class="n">replications</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">4</span><span class="p">,</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3</span><span class="p">))</span><span class="w">
  </span><span class="n">print_response</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\nTesting multivariate forecasting...\n"</span><span class="p">)</span><span class="w">
  </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">make_request</span><span class="p">(</span><span class="s2">"/forecasting"</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w">
    </span><span class="n">dataset_key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"multivariate"</span><span class="p">,</span><span class="w">
    </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">base_model</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"RidgeCV"</span><span class="p">,</span><span class="w"> </span><span class="n">n_hidden_features</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">5</span><span class="p">,</span><span class="w"> </span><span class="n">lags</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">25</span><span class="p">,</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3</span><span class="p">))</span><span class="w">
  </span><span class="n">print_response</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">test_ml</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">token</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\n=== Testing Machine Learning Endpoints ===\n"</span><span class="p">)</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\nTesting classification...\n"</span><span class="p">)</span><span class="w">
  </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">make_request</span><span class="p">(</span><span class="s2">"/mlclassification"</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w">
    </span><span class="n">dataset_key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"classification"</span><span class="p">,</span><span class="w">
    </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">base_model</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"RandomForestClassifier"</span><span class="p">,</span><span class="w">
                  </span><span class="n">n_hidden_features</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">5</span><span class="p">,</span><span class="w"> </span><span class="n">predict_proba</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">))</span><span class="w">
  </span><span class="n">print_response</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\nTesting regression...\n"</span><span class="p">)</span><span class="w">
  </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">make_request</span><span class="p">(</span><span class="s2">"/mlregression"</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w">
    </span><span class="n">dataset_key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"regression"</span><span class="p">,</span><span class="w">
    </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">base_model</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"RidgeCV"</span><span class="p">,</span><span class="w"> </span><span class="n">n_hidden_features</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">5</span><span class="p">,</span><span class="w"> </span><span class="n">return_pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">))</span><span class="w">
  </span><span class="n">print_response</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">test_reserving</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">token</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\n=== Testing Reserving Endpoints ===\n"</span><span class="p">)</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\nTesting RidgeCV...\n"</span><span class="p">)</span><span class="w">
  </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">make_request</span><span class="p">(</span><span class="s2">"/mlreserving"</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w">
    </span><span class="n">dataset_key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"raa"</span><span class="p">,</span><span class="w">
    </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"RidgeCV"</span><span class="p">))</span><span class="w">
  </span><span class="n">print_response</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\nTesting LassoCV...\n"</span><span class="p">)</span><span class="w">
  </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">make_request</span><span class="p">(</span><span class="s2">"/mlreserving"</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w">
    </span><span class="n">dataset_key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"abc"</span><span class="p">,</span><span class="w">
    </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"LassoCV"</span><span class="p">))</span><span class="w">
  </span><span class="n">print_response</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">test_survival</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">token</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\n=== Testing Survival Analysis Endpoints ===\n"</span><span class="p">)</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\nTesting Kaplan-Meier...\n"</span><span class="p">)</span><span class="w">
  </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">make_request</span><span class="p">(</span><span class="s2">"/survivalcurve"</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w">
    </span><span class="n">dataset_key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"km"</span><span class="p">,</span><span class="w">
    </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"km"</span><span class="p">))</span><span class="w">
  </span><span class="n">print_response</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="s2">"\nTesting Ridge survival...\n"</span><span class="p">)</span><span class="w">
  </span><span class="n">resp</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">make_request</span><span class="p">(</span><span class="s2">"/survivalcurve"</span><span class="p">,</span><span class="w"> </span><span class="n">token</span><span class="p">,</span><span class="w">
    </span><span class="n">dataset_key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"ridge_survival"</span><span class="p">,</span><span class="w">
    </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">method</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"RidgeCV"</span><span class="p">,</span><span class="w"> </span><span class="n">patient_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">))</span><span class="w">
  </span><span class="n">print_response</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="c1"># ---------------------------------------------------------------------------</span><span class="w">
</span><span class="c1"># Main</span><span class="w">
</span><span class="c1"># ---------------------------------------------------------------------------</span><span class="w">

</span><span class="n">main</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">token</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">get_token</span><span class="p">()</span><span class="w">
  </span><span class="n">test_forecasting</span><span class="p">(</span><span class="n">token</span><span class="p">)</span><span class="w">
  </span><span class="n">test_ml</span><span class="p">(</span><span class="n">token</span><span class="p">)</span><span class="w">
  </span><span class="n">test_reserving</span><span class="p">(</span><span class="n">token</span><span class="p">)</span><span class="w">
  </span><span class="n">test_survival</span><span class="p">(</span><span class="n">token</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">main</span><span class="p">()</span><span class="w">
</span></code></pre></div></div>

<h1 id="2---python-example">2 - Python example:</h1>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">argparse</span>
<span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">io</span>
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Any</span>

<span class="c1"># All you need is a token from www.techtonique.net/token, then run the script
</span>
<span class="c1"># Base URL for API endpoints
</span><span class="n">base_url</span> <span class="o">=</span> <span class="s">"https://www.techtonique.net"</span>

<span class="c1"># Base URL for raw GitHub content
</span><span class="n">GITHUB_RAW</span> <span class="o">=</span> <span class="s">"https://raw.githubusercontent.com/Techtonique/datasets/main"</span>

<span class="c1"># Dataset paths within the GitHub repo
</span><span class="n">DATASETS</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">"univariate"</span><span class="p">:</span>       <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">GITHUB_RAW</span><span class="si">}</span><span class="s">/time_series/univariate/a10.csv"</span><span class="p">,</span>
    <span class="s">"multivariate"</span><span class="p">:</span>     <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">GITHUB_RAW</span><span class="si">}</span><span class="s">/time_series/multivariate/ice_cream_vs_heater.csv"</span><span class="p">,</span>
    <span class="s">"classification"</span><span class="p">:</span>   <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">GITHUB_RAW</span><span class="si">}</span><span class="s">/tabular/classification/breast_cancer_dataset2.csv"</span><span class="p">,</span>
    <span class="s">"regression"</span><span class="p">:</span>       <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">GITHUB_RAW</span><span class="si">}</span><span class="s">/tabular/regression/boston_dataset2.csv"</span><span class="p">,</span>
    <span class="s">"raa"</span><span class="p">:</span>              <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">GITHUB_RAW</span><span class="si">}</span><span class="s">/tabular/triangle/raa.csv"</span><span class="p">,</span>
    <span class="s">"abc"</span><span class="p">:</span>              <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">GITHUB_RAW</span><span class="si">}</span><span class="s">/tabular/triangle/abc.csv"</span><span class="p">,</span>
    <span class="s">"km"</span><span class="p">:</span>               <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">GITHUB_RAW</span><span class="si">}</span><span class="s">/tabular/survival/kidney.csv"</span><span class="p">,</span>
    <span class="s">"ridge_survival"</span><span class="p">:</span>   <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">GITHUB_RAW</span><span class="si">}</span><span class="s">/tabular/survival/gbsg2_2.csv"</span><span class="p">,</span>
<span class="p">}</span>


<span class="k">def</span> <span class="nf">get_token</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
    <span class="s">"""Get token from command line argument or prompt"""</span>
    <span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="p">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s">'Test API endpoints'</span><span class="p">)</span>
    <span class="n">parser</span><span class="p">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s">'--token'</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s">'JWT token for authentication'</span><span class="p">)</span>
    <span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="p">.</span><span class="n">parse_args</span><span class="p">()</span>

    <span class="k">if</span> <span class="n">args</span><span class="p">.</span><span class="n">token</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">args</span><span class="p">.</span><span class="n">token</span>

    <span class="k">return</span> <span class="nb">input</span><span class="p">(</span><span class="s">"Please enter your JWT token: "</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">fetch_dataset</span><span class="p">(</span><span class="n">dataset_key</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">io</span><span class="p">.</span><span class="n">BytesIO</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
    <span class="s">"""
    Download a dataset from GitHub and return it as an in-memory bytes buffer
    together with a filename, ready to be passed to requests as a file upload.
    """</span>
    <span class="n">url</span> <span class="o">=</span> <span class="n">DATASETS</span><span class="p">[</span><span class="n">dataset_key</span><span class="p">]</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="n">url</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="s">"/"</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"  Fetching </span><span class="si">{</span><span class="n">filename</span><span class="si">}</span><span class="s"> from GitHub..."</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s">" "</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
    <span class="n">response</span><span class="p">.</span><span class="n">raise_for_status</span><span class="p">()</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"OK"</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">io</span><span class="p">.</span><span class="n">BytesIO</span><span class="p">(</span><span class="n">response</span><span class="p">.</span><span class="n">content</span><span class="p">),</span> <span class="n">filename</span>


<span class="k">def</span> <span class="nf">make_request</span><span class="p">(</span>
    <span class="n">url</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
    <span class="n">token</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
    <span class="n">method</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s">"POST"</span><span class="p">,</span>
    <span class="n">file_tuple</span><span class="p">:</span> <span class="nb">tuple</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span>   <span class="c1"># (BytesIO, filename)
</span>    <span class="n">params</span><span class="p">:</span> <span class="n">Dict</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
    <span class="s">"""Make an API request and return the response."""</span>
    <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s">"Authorization"</span><span class="p">:</span> <span class="sa">f</span><span class="s">"Bearer </span><span class="si">{</span><span class="n">token</span><span class="si">}</span><span class="s">"</span><span class="p">}</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">method</span> <span class="o">==</span> <span class="s">"POST"</span><span class="p">:</span>
            <span class="n">files</span> <span class="o">=</span> <span class="bp">None</span>
            <span class="k">if</span> <span class="n">file_tuple</span><span class="p">:</span>
                <span class="n">buf</span><span class="p">,</span> <span class="n">filename</span> <span class="o">=</span> <span class="n">file_tuple</span>
                <span class="n">files</span> <span class="o">=</span> <span class="p">{</span><span class="s">"file"</span><span class="p">:</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="s">"text/csv"</span><span class="p">)}</span>
            <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">)</span>

        <span class="n">response</span><span class="p">.</span><span class="n">raise_for_status</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">response</span><span class="p">.</span><span class="n">json</span><span class="p">()</span>

    <span class="k">except</span> <span class="n">requests</span><span class="p">.</span><span class="n">exceptions</span><span class="p">.</span><span class="n">RequestException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Error making request to </span><span class="si">{</span><span class="n">url</span><span class="si">}</span><span class="s">:"</span><span class="p">)</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Status code: </span><span class="si">{</span><span class="n">e</span><span class="p">.</span><span class="n">response</span><span class="p">.</span><span class="n">status_code</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="s">'response'</span><span class="p">)</span> <span class="k">else</span> <span class="s">'N/A'</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Response: </span><span class="si">{</span><span class="n">e</span><span class="p">.</span><span class="n">response</span><span class="p">.</span><span class="n">text</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="s">'response'</span><span class="p">)</span> <span class="k">else</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
        <span class="k">return</span> <span class="bp">None</span>


<span class="k">def</span> <span class="nf">test_forecasting</span><span class="p">(</span><span class="n">token</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">=== Testing Forecasting Endpoints ==="</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Testing univariate forecasting..."</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">make_request</span><span class="p">(</span>
        <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">base_url</span><span class="si">}</span><span class="s">/forecasting"</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span>
        <span class="n">file_tuple</span><span class="o">=</span><span class="n">fetch_dataset</span><span class="p">(</span><span class="s">"univariate"</span><span class="p">),</span>
        <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s">"base_model"</span><span class="p">:</span> <span class="s">"RidgeCV"</span><span class="p">,</span> <span class="s">"n_hidden_features"</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span>
                <span class="s">"lags"</span><span class="p">:</span> <span class="mi">25</span><span class="p">,</span> <span class="s">"type_pi"</span><span class="p">:</span> <span class="s">"kde"</span><span class="p">,</span> <span class="s">"replications"</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s">"h"</span><span class="p">:</span> <span class="mi">3</span><span class="p">},</span>
    <span class="p">)</span>
    <span class="k">if</span> <span class="n">response</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Response:"</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Testing multivariate forecasting..."</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">make_request</span><span class="p">(</span>
        <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">base_url</span><span class="si">}</span><span class="s">/forecasting"</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span>
        <span class="n">file_tuple</span><span class="o">=</span><span class="n">fetch_dataset</span><span class="p">(</span><span class="s">"multivariate"</span><span class="p">),</span>
        <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s">"base_model"</span><span class="p">:</span> <span class="s">"RidgeCV"</span><span class="p">,</span> <span class="s">"n_hidden_features"</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">"lags"</span><span class="p">:</span> <span class="mi">25</span><span class="p">,</span> <span class="s">"h"</span><span class="p">:</span> <span class="mi">3</span><span class="p">},</span>
    <span class="p">)</span>
    <span class="k">if</span> <span class="n">response</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Response:"</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">test_ml</span><span class="p">(</span><span class="n">token</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">=== Testing Machine Learning Endpoints ==="</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Testing classification..."</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">make_request</span><span class="p">(</span>
        <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">base_url</span><span class="si">}</span><span class="s">/mlclassification"</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span>
        <span class="n">file_tuple</span><span class="o">=</span><span class="n">fetch_dataset</span><span class="p">(</span><span class="s">"classification"</span><span class="p">),</span>
        <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s">"base_model"</span><span class="p">:</span> <span class="s">"RandomForestClassifier"</span><span class="p">,</span>
                <span class="s">"n_hidden_features"</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">"predict_proba"</span><span class="p">:</span> <span class="bp">True</span><span class="p">},</span>
    <span class="p">)</span>
    <span class="k">if</span> <span class="n">response</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Response:"</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Testing regression..."</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">make_request</span><span class="p">(</span>
        <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">base_url</span><span class="si">}</span><span class="s">/mlregression"</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span>
        <span class="n">file_tuple</span><span class="o">=</span><span class="n">fetch_dataset</span><span class="p">(</span><span class="s">"regression"</span><span class="p">),</span>
        <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s">"base_model"</span><span class="p">:</span> <span class="s">"RidgeCV"</span><span class="p">,</span> <span class="s">"n_hidden_features"</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">"return_pi"</span><span class="p">:</span> <span class="bp">True</span><span class="p">},</span>
    <span class="p">)</span>
    <span class="k">if</span> <span class="n">response</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Response:"</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">test_reserving</span><span class="p">(</span><span class="n">token</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">=== Testing Reserving Endpoints ==="</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Testing RidgeCV..."</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">make_request</span><span class="p">(</span>
        <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">base_url</span><span class="si">}</span><span class="s">/mlreserving"</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span>
        <span class="n">file_tuple</span><span class="o">=</span><span class="n">fetch_dataset</span><span class="p">(</span><span class="s">"raa"</span><span class="p">),</span>
        <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s">"method"</span><span class="p">:</span> <span class="s">"RidgeCV"</span><span class="p">},</span>
    <span class="p">)</span>
    <span class="k">if</span> <span class="n">response</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Response:"</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Testing LassoCV..."</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">make_request</span><span class="p">(</span>
        <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">base_url</span><span class="si">}</span><span class="s">/mlreserving"</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span>
        <span class="n">file_tuple</span><span class="o">=</span><span class="n">fetch_dataset</span><span class="p">(</span><span class="s">"abc"</span><span class="p">),</span>
        <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s">"method"</span><span class="p">:</span> <span class="s">"LassoCV"</span><span class="p">},</span>
    <span class="p">)</span>
    <span class="k">if</span> <span class="n">response</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Response:"</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">test_survival</span><span class="p">(</span><span class="n">token</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">=== Testing Survival Analysis Endpoints ==="</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Testing Kaplan-Meier..."</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">make_request</span><span class="p">(</span>
        <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">base_url</span><span class="si">}</span><span class="s">/survivalcurve"</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span>
        <span class="n">file_tuple</span><span class="o">=</span><span class="n">fetch_dataset</span><span class="p">(</span><span class="s">"km"</span><span class="p">),</span>
        <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s">"method"</span><span class="p">:</span> <span class="s">"km"</span><span class="p">},</span>
    <span class="p">)</span>
    <span class="k">if</span> <span class="n">response</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Response:"</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Testing Ridge survival..."</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">make_request</span><span class="p">(</span>
        <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">base_url</span><span class="si">}</span><span class="s">/survivalcurve"</span><span class="p">,</span> <span class="n">token</span><span class="p">,</span>
        <span class="n">file_tuple</span><span class="o">=</span><span class="n">fetch_dataset</span><span class="p">(</span><span class="s">"ridge_survival"</span><span class="p">),</span>
        <span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s">"method"</span><span class="p">:</span> <span class="s">"RidgeCV"</span><span class="p">,</span> <span class="s">"patient_id"</span><span class="p">:</span> <span class="mi">0</span><span class="p">},</span>
    <span class="p">)</span>
    <span class="k">if</span> <span class="n">response</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Response:"</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">token</span> <span class="o">=</span> <span class="n">get_token</span><span class="p">()</span>
    <span class="n">test_forecasting</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
    <span class="n">test_ml</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
    <span class="n">test_reserving</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
    <span class="n">test_survival</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>


<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</code></pre></div></div>

<p><img src="/images/2025-06-09/2025-06-09-image1.gif" alt="image-title-here" class="img-responsive" /></p>

<p>PS: Do not use models ending with <code class="language-plaintext highlighter-rouge">CV</code> for time series forecasting, as they are not designed for that (they are for tabular data, and use a cross-validation which is not suitable for time series). The API will still run the request, but the results may not be good. For time series forecasting, it is better to use models like <code class="language-plaintext highlighter-rouge">Ridge</code>, <code class="language-plaintext highlighter-rouge">RandomForestRegressor</code>, <code class="language-plaintext highlighter-rouge">GradientBoostingRegressor</code> etc.</p>]]></content><author><name></name></author><category term="R" /><category term="Python" /><category term="Techtonique" /><summary type="html"><![CDATA[Techtonique dot net is back, but more like a passion project, with an API for machine learning tasks (classification, regression, survival analysis, reserving, forecasting etc.). Examples in R, Python are provided in the blog post.]]></summary></entry><entry><title type="html">Conformalized TabICL: Prediction Intervals for a State-Of-The-Art Tabular Foundation Model in Python and R</title><link href="https://thierrymoudiki.github.io/blog/2026/05/21/r/python/Conformalized-TabICL-nnetsauce" rel="alternate" type="text/html" title="Conformalized TabICL: Prediction Intervals for a State-Of-The-Art Tabular Foundation Model in Python and R" /><published>2026-05-21T00:00:00+00:00</published><updated>2026-05-21T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/05/21/r/python/Conformalized-TabICL-nnetsauce</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/05/21/r/python/Conformalized-TabICL-nnetsauce"><![CDATA[<p>A few days ago, I presented <a href="https://thierrymoudiki.github.io/blog/2026/05/17/r/python/conformalized-tabpfn">Conformalized TabPFN: Prediction Intervals for a Pretrained Transformer for Tabular Data in Python and R</a>. Today, it’s about <a href="https://github.com/soda-inria/tabicl">TabICL</a>, another state-of-the-art tabular foundation model. <code class="language-plaintext highlighter-rouge">TabICL</code> requires no token, as you’ll notice in the following Python and R code.</p>

<h1 id="1---python-version">1 - Python version</h1>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="n">tabicl</span> <span class="n">nnetsauce</span> <span class="c1"># scikit-learn matplotlib numpy
</span></code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sklearn.datasets</span> <span class="kn">import</span> <span class="n">load_diabetes</span>
<span class="kn">from</span> <span class="nn">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">train_test_split</span>
<span class="kn">from</span> <span class="nn">sklearn.linear_model</span> <span class="kn">import</span> <span class="n">RidgeCV</span>
<span class="kn">from</span> <span class="nn">sklearn.metrics</span> <span class="kn">import</span> <span class="n">mean_squared_error</span>
<span class="kn">from</span> <span class="nn">tabicl</span> <span class="kn">import</span> <span class="n">TabICLRegressor</span>
<span class="kn">import</span> <span class="nn">nnetsauce</span> <span class="k">as</span> <span class="n">ns</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">time</span>

<span class="c1"># ── data ───────────────────────────────────────────────────
</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">load_diabetes</span><span class="p">(</span><span class="n">return_X_y</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">X_train</span><span class="p">,</span> <span class="n">X_test</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">y_test</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span>
    <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">42</span>
<span class="p">)</span>

<span class="c1"># ── base models ────────────────────────────────────────────
</span><span class="n">models</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">"TabICL"</span><span class="p">:</span> <span class="n">TabICLRegressor</span><span class="p">(),</span>
    <span class="s">"RidgeCV"</span><span class="p">:</span> <span class="n">RidgeCV</span><span class="p">(),</span>
<span class="p">}</span>

<span class="n">results</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">reg</span> <span class="ow">in</span> <span class="n">models</span><span class="p">.</span><span class="n">items</span><span class="p">():</span>
    <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
    <span class="n">conf</span> <span class="o">=</span> <span class="n">ns</span><span class="p">.</span><span class="n">PredictionInterval</span><span class="p">(</span><span class="n">reg</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="mi">95</span><span class="p">)</span>
    <span class="n">conf</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
    <span class="n">pi</span> <span class="o">=</span> <span class="n">conf</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">,</span> <span class="n">return_pi</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">name</span><span class="si">:</span><span class="mi">10</span><span class="n">s</span><span class="si">}</span><span class="s">  time=</span><span class="si">{</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="si">:</span><span class="p">.</span><span class="mi">1</span><span class="n">f</span><span class="si">}</span><span class="s">s"</span><span class="p">)</span>

    <span class="n">coverage</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">((</span><span class="n">pi</span><span class="p">.</span><span class="n">lower</span> <span class="o">&lt;=</span> <span class="n">y_test</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">pi</span><span class="p">.</span><span class="n">upper</span> <span class="o">&gt;=</span> <span class="n">y_test</span><span class="p">))</span>
    <span class="n">width</span>    <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">(</span><span class="n">pi</span><span class="p">.</span><span class="n">upper</span> <span class="o">-</span> <span class="n">pi</span><span class="p">.</span><span class="n">lower</span><span class="p">)</span>
    <span class="n">rmse</span>     <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">mean_squared_error</span><span class="p">(</span><span class="n">y_test</span><span class="p">,</span> <span class="n">pi</span><span class="p">.</span><span class="n">mean</span><span class="p">))</span>

    <span class="n">results</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s">"pi"</span><span class="p">:</span> <span class="n">pi</span><span class="p">,</span> <span class="s">"coverage"</span><span class="p">:</span> <span class="n">coverage</span><span class="p">,</span>
                     <span class="s">"width"</span><span class="p">:</span> <span class="n">width</span><span class="p">,</span> <span class="s">"rmse"</span><span class="p">:</span> <span class="n">rmse</span><span class="p">}</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">name</span><span class="si">:</span><span class="mi">10</span><span class="n">s</span><span class="si">}</span><span class="s">  RMSE=</span><span class="si">{</span><span class="n">rmse</span><span class="si">:</span><span class="p">.</span><span class="mi">1</span><span class="n">f</span><span class="si">}</span><span class="s">  "</span>
          <span class="sa">f</span><span class="s">"coverage=</span><span class="si">{</span><span class="n">coverage</span><span class="si">:</span><span class="p">.</span><span class="mi">3</span><span class="n">f</span><span class="si">}</span><span class="s">  avg_width=</span><span class="si">{</span><span class="n">width</span><span class="si">:</span><span class="p">.</span><span class="mi">1</span><span class="n">f</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="c1"># ── plot side-by-side ──────────────────────────────────────
</span><span class="n">fig</span><span class="p">,</span> <span class="n">axes</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">subplots</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="n">sharey</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">colors</span> <span class="o">=</span> <span class="p">{</span><span class="s">"TabICL"</span><span class="p">:</span> <span class="s">"orange"</span><span class="p">,</span> <span class="s">"RidgeCV"</span><span class="p">:</span> <span class="s">"steelblue"</span><span class="p">}</span>
<span class="n">max_idx</span> <span class="o">=</span> <span class="mi">50</span>

<span class="k">for</span> <span class="n">ax</span><span class="p">,</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">res</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">axes</span><span class="p">,</span> <span class="n">results</span><span class="p">.</span><span class="n">items</span><span class="p">()):</span>
    <span class="n">pi</span> <span class="o">=</span> <span class="n">res</span><span class="p">[</span><span class="s">"pi"</span><span class="p">]</span>
    <span class="n">x</span>  <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_idx</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">fill_between</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">pi</span><span class="p">.</span><span class="n">lower</span><span class="p">[:</span><span class="n">max_idx</span><span class="p">],</span> <span class="n">pi</span><span class="p">.</span><span class="n">upper</span><span class="p">[:</span><span class="n">max_idx</span><span class="p">],</span>
                     <span class="n">alpha</span><span class="o">=</span><span class="mf">0.35</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="n">colors</span><span class="p">[</span><span class="n">name</span><span class="p">],</span> <span class="n">label</span><span class="o">=</span><span class="s">"95% PI"</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">pi</span><span class="p">.</span><span class="n">mean</span><span class="p">[:</span><span class="n">max_idx</span><span class="p">],</span> <span class="s">"k--"</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mf">1.5</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">"predicted"</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y_test</span><span class="p">[:</span><span class="n">max_idx</span><span class="p">],</span> <span class="s">"k."</span><span class="p">,</span> <span class="n">ms</span><span class="o">=</span><span class="mi">6</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.4</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s">"observed"</span><span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">set_title</span><span class="p">(</span>
        <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s">  |  cov=</span><span class="si">{</span><span class="n">res</span><span class="p">[</span><span class="s">'coverage'</span><span class="p">]</span><span class="si">:</span><span class="p">.</span><span class="mi">3</span><span class="n">f</span><span class="si">}</span><span class="s">  width=</span><span class="si">{</span><span class="n">res</span><span class="p">[</span><span class="s">'width'</span><span class="p">]</span><span class="si">:</span><span class="p">.</span><span class="mi">1</span><span class="n">f</span><span class="si">}</span><span class="s">"</span>
    <span class="p">)</span>
    <span class="n">ax</span><span class="p">.</span><span class="n">legend</span><span class="p">(</span><span class="n">fontsize</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>

<span class="n">plt</span><span class="p">.</span><span class="n">suptitle</span><span class="p">(</span><span class="s">"Conformalized TabICL vs RidgeCV — diabetes dataset"</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="n">tight_layout</span><span class="p">()</span>
<span class="n">plt</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Checkpoint 'tabicl-regressor-v2-20260212.ckpt' not cached.
 Downloading from Hugging Face Hub (jingang/TabICL).




tabicl-regressor-v2-20260212.ckpt:   0%|          | 0.00/114M [00:00&lt;?, ?B/s]


TabICL      time=21.8s
TabICL      RMSE=54.4  coverage=0.955  avg_width=226.1
RidgeCV     time=0.0s
RidgeCV     RMSE=53.9  coverage=0.955  avg_width=211.5
</code></pre></div></div>

<p><img src="/images/2026-05-21/2026-05-21-Conformalized-TabICL-nnetsauce_3_3.png" alt="image-title-here" class="img-responsive" /></p>

<h1 id="2---r-version">2 - R version</h1>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="o">%</span><span class="n">load_ext</span> <span class="n">rpy2</span><span class="p">.</span><span class="n">ipython</span> <span class="c1"># in a Colab notebook, use this
</span></code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%</span><span class="n">R</span> <span class="n">install</span><span class="p">.</span><span class="n">packages</span><span class="p">(</span><span class="s">"reticulate"</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-r highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%%</span><span class="n">R</span><span class="w">  </span><span class="c1"># in Colab/Jupyter with rpy2; remove this line for pure R</span><span class="w">

</span><span class="n">library</span><span class="p">(</span><span class="n">reticulate</span><span class="p">)</span><span class="w">

</span><span class="c1"># pip install tabicl nnetsauce scikit-learn matplotlib numpy</span><span class="w">

</span><span class="n">sklearn_ds</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"sklearn.datasets"</span><span class="p">)</span><span class="w">
</span><span class="n">sklearn_ms</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"sklearn.model_selection"</span><span class="p">)</span><span class="w">
</span><span class="n">sklearn_m</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"sklearn.metrics"</span><span class="p">)</span><span class="w">
</span><span class="n">sklearn_lm</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"sklearn.linear_model"</span><span class="p">)</span><span class="w">
</span><span class="n">tabicl</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"tabicl"</span><span class="p">)</span><span class="w">
</span><span class="n">ns</span><span class="w">          </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"nnetsauce"</span><span class="p">)</span><span class="w">
</span><span class="n">np</span><span class="w">          </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"numpy"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="w">         </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"matplotlib.pyplot"</span><span class="p">)</span><span class="w">

</span><span class="c1"># ── data ───────────────────────────────────────────────────</span><span class="w">
</span><span class="n">d</span><span class="w">       </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sklearn_ds</span><span class="o">$</span><span class="n">load_diabetes</span><span class="p">(</span><span class="n">return_X_y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">)</span><span class="w">
</span><span class="n">X</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">d</span><span class="p">[[</span><span class="m">1</span><span class="p">]];</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">d</span><span class="p">[[</span><span class="m">2</span><span class="p">]]</span><span class="w">
</span><span class="n">sp</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sklearn_ms</span><span class="o">$</span><span class="n">train_test_split</span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w">
             </span><span class="n">test_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.2</span><span class="p">,</span><span class="w"> </span><span class="n">random_state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">42L</span><span class="p">)</span><span class="w">
</span><span class="n">X_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sp</span><span class="p">[[</span><span class="m">1</span><span class="p">]];</span><span class="w"> </span><span class="n">X_test</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sp</span><span class="p">[[</span><span class="m">2</span><span class="p">]]</span><span class="w">
</span><span class="n">y_train</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sp</span><span class="p">[[</span><span class="m">3</span><span class="p">]];</span><span class="w"> </span><span class="n">y_test</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sp</span><span class="p">[[</span><span class="m">4</span><span class="p">]]</span><span class="w">

</span><span class="c1"># ── helper: fit + evaluate ─────────────────────────────────</span><span class="w">
</span><span class="n">eval_model</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">reg</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">conf</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ns</span><span class="o">$</span><span class="n">PredictionInterval</span><span class="p">(</span><span class="n">reg</span><span class="p">,</span><span class="w"> </span><span class="n">level</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">95L</span><span class="p">)</span><span class="w">
  </span><span class="n">conf</span><span class="o">$</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span><span class="w"> </span><span class="n">y_train</span><span class="p">)</span><span class="w">
  </span><span class="nb">pi</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">conf</span><span class="o">$</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">,</span><span class="w"> </span><span class="n">return_pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">)</span><span class="w">

  </span><span class="n">cov</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">np</span><span class="o">$</span><span class="n">mean</span><span class="p">((</span><span class="nb">pi</span><span class="o">$</span><span class="n">lower</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">y_test</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="nb">pi</span><span class="o">$</span><span class="n">upper</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">y_test</span><span class="p">))</span><span class="w">
  </span><span class="n">wid</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">np</span><span class="o">$</span><span class="n">mean</span><span class="p">(</span><span class="nb">pi</span><span class="o">$</span><span class="n">upper</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nb">pi</span><span class="o">$</span><span class="n">lower</span><span class="p">)</span><span class="w">
  </span><span class="n">rmse</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">sqrt</span><span class="p">(</span><span class="n">sklearn_m</span><span class="o">$</span><span class="n">mean_squared_error</span><span class="p">(</span><span class="n">y_test</span><span class="p">,</span><span class="w"> </span><span class="nb">pi</span><span class="o">$</span><span class="n">mean</span><span class="p">))</span><span class="w">

  </span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"%-10s  RMSE=%.1f  coverage=%.3f  avg_width=%.1f\n"</span><span class="p">,</span><span class="w">
              </span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="n">rmse</span><span class="p">,</span><span class="w"> </span><span class="n">cov</span><span class="p">,</span><span class="w"> </span><span class="n">wid</span><span class="p">))</span><span class="w">
  </span><span class="nf">invisible</span><span class="p">(</span><span class="nb">pi</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="c1"># ── run both models ────────────────────────────────────────</span><span class="w">
</span><span class="n">pi_tabicl</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">eval_model</span><span class="p">(</span><span class="n">tabicl</span><span class="o">$</span><span class="n">TabICLRegressor</span><span class="p">(),</span><span class="w">  </span><span class="s2">"TabICL"</span><span class="p">)</span><span class="w">
</span><span class="n">pi_ridge</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">eval_model</span><span class="p">(</span><span class="n">sklearn_lm</span><span class="o">$</span><span class="n">RidgeCV</span><span class="p">(),</span><span class="w">       </span><span class="s2">"RidgeCV"</span><span class="p">)</span><span class="w">

</span><span class="c1"># ── plot ───────────────────────────────────────────────────</span><span class="w">
</span><span class="n">max_idx</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="m">50L</span><span class="w">
</span><span class="n">x_range</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">np</span><span class="o">$</span><span class="n">array</span><span class="p">(</span><span class="m">0</span><span class="o">:</span><span class="p">(</span><span class="n">max_idx</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">))</span><span class="w">

</span><span class="n">plot_pi</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="nb">pi</span><span class="p">,</span><span class="w"> </span><span class="n">title</span><span class="p">,</span><span class="w"> </span><span class="n">col</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">x_fill</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">np</span><span class="o">$</span><span class="n">concatenate</span><span class="p">(</span><span class="nf">list</span><span class="p">(</span><span class="n">x_range</span><span class="p">,</span><span class="w"> </span><span class="n">x_range</span><span class="p">[</span><span class="n">max_idx</span><span class="o">:</span><span class="m">1</span><span class="p">]))</span><span class="w">
  </span><span class="n">y_fill</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">np</span><span class="o">$</span><span class="n">concatenate</span><span class="p">(</span><span class="nf">list</span><span class="p">(</span><span class="w">
    </span><span class="nb">pi</span><span class="o">$</span><span class="n">upper</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="n">max_idx</span><span class="p">],</span><span class="w"> </span><span class="nb">pi</span><span class="o">$</span><span class="n">lower</span><span class="p">[</span><span class="n">max_idx</span><span class="o">:</span><span class="m">1</span><span class="p">]))</span><span class="w">
  </span><span class="n">plt</span><span class="o">$</span><span class="n">fill</span><span class="p">(</span><span class="n">x_fill</span><span class="p">,</span><span class="w"> </span><span class="n">y_fill</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="o">=</span><span class="m">0.35</span><span class="p">,</span><span class="w"> </span><span class="n">fc</span><span class="o">=</span><span class="n">col</span><span class="p">,</span><span class="w"> </span><span class="n">ec</span><span class="o">=</span><span class="s2">"None"</span><span class="p">,</span><span class="w"> </span><span class="n">label</span><span class="o">=</span><span class="s2">"95% PI"</span><span class="p">)</span><span class="w">
  </span><span class="n">plt</span><span class="o">$</span><span class="n">plot</span><span class="p">(</span><span class="n">x_range</span><span class="p">,</span><span class="w"> </span><span class="nb">pi</span><span class="o">$</span><span class="n">mean</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="n">max_idx</span><span class="p">],</span><span class="w"> </span><span class="s2">"k--"</span><span class="p">,</span><span class="w"> </span><span class="n">lw</span><span class="o">=</span><span class="m">1.5</span><span class="p">,</span><span class="w"> </span><span class="n">label</span><span class="o">=</span><span class="s2">"predicted"</span><span class="p">)</span><span class="w">
  </span><span class="n">plt</span><span class="o">$</span><span class="n">plot</span><span class="p">(</span><span class="n">x_range</span><span class="p">,</span><span class="w"> </span><span class="n">y_test</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="n">max_idx</span><span class="p">],</span><span class="w"> </span><span class="s2">"k."</span><span class="p">,</span><span class="w"> </span><span class="n">ms</span><span class="o">=</span><span class="m">6L</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="o">=</span><span class="m">0.4</span><span class="p">,</span><span class="w"> </span><span class="n">label</span><span class="o">=</span><span class="s2">"observed"</span><span class="p">)</span><span class="w">
  </span><span class="n">plt</span><span class="o">$</span><span class="n">title</span><span class="p">(</span><span class="n">title</span><span class="p">);</span><span class="w"> </span><span class="n">plt</span><span class="o">$</span><span class="n">legend</span><span class="p">(</span><span class="n">fontsize</span><span class="o">=</span><span class="m">8L</span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">fig</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">plt</span><span class="o">$</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="nf">c</span><span class="p">(</span><span class="m">12</span><span class="p">,</span><span class="w"> </span><span class="m">4</span><span class="p">))</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">subplot</span><span class="p">(</span><span class="m">1L</span><span class="p">,</span><span class="w"> </span><span class="m">2L</span><span class="p">,</span><span class="w"> </span><span class="m">1L</span><span class="p">);</span><span class="w"> </span><span class="n">plot_pi</span><span class="p">(</span><span class="n">pi_tabicl</span><span class="p">,</span><span class="w"> </span><span class="s2">"Conformalized TabICL"</span><span class="p">,</span><span class="w"> </span><span class="s2">"orange"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">subplot</span><span class="p">(</span><span class="m">1L</span><span class="p">,</span><span class="w"> </span><span class="m">2L</span><span class="p">,</span><span class="w"> </span><span class="m">2L</span><span class="p">);</span><span class="w"> </span><span class="n">plot_pi</span><span class="p">(</span><span class="n">pi_ridge</span><span class="p">,</span><span class="w">  </span><span class="s2">"Conformalized RidgeCV"</span><span class="p">,</span><span class="w"> </span><span class="s2">"steelblue"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">suptitle</span><span class="p">(</span><span class="s2">"Conformalized TabICL vs RidgeCV — diabetes dataset"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">tight_layout</span><span class="p">()</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">show</span><span class="p">()</span><span class="w">
</span></code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    WARNING: The R package "reticulate" only fixed recently
    an issue that caused a segfault when used with rpy2:
    https://github.com/rstudio/reticulate/pull/1188
    Make sure that you use a version of that package that includes
    the fix.
    TabICL      RMSE=54.4  coverage=0.955  avg_width=226.1
RidgeCV     RMSE=53.9  coverage=0.955  avg_width=211.5
</code></pre></div></div>

<p><img src="/images/2026-05-21/2026-05-21-Conformalized-TabICL-nnetsauce_7_1.png" alt="image-title-here" class="img-responsive" /></p>

<p>Probably a dataset that’s too <em>easy</em> for a Transformer. Conformalizing simple models helps them, in general, to obtain coverage rates close to the nominal level, as we see for RidgeCV here.</p>]]></content><author><name></name></author><category term="R" /><category term="Python" /><summary type="html"><![CDATA[Prediction Intervals for Tabular Regression in Python and R via Conformalized TabICL; comparison with RidgeCV]]></summary></entry><entry><title type="html">Conformalized TabPFN: Prediction Intervals for a Pretrained Transformer for Tabular Data in Python and R</title><link href="https://thierrymoudiki.github.io/blog/2026/05/17/r/python/conformalized-tabpfn" rel="alternate" type="text/html" title="Conformalized TabPFN: Prediction Intervals for a Pretrained Transformer for Tabular Data in Python and R" /><published>2026-05-17T00:00:00+00:00</published><updated>2026-05-17T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/05/17/r/python/conformalized-tabpfn</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/05/17/r/python/conformalized-tabpfn"><![CDATA[<p>Knowing a model’s prediction is useful. Knowing how confident that prediction is, even more so. Conformal prediction provides exactly that: statistically valid prediction intervals with guaranteed coverage (under certain conditions), regardless of the underlying model or data distribution.</p>

<p>In this post, we pair two powerful tools: <code class="language-plaintext highlighter-rouge">TabPFN</code>, a <strong>pretrained transformer for tabular data</strong>, and <code class="language-plaintext highlighter-rouge">nnetsauce</code>’s <code class="language-plaintext highlighter-rouge">PredictionInterval</code> (which implements Split Conformal Prediction), which wraps any scikit-learn-compatible regressor into a conformal predictor. We demonstrate the full pipeline on the diabetes dataset, first in Python, then in R via reticulate. Both versions produce identical results: a coverage rate of 96.7% at a nominal 95% level.</p>

<h1 id="1---python-version">1 - Python version</h1>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="n">tabpfn</span> <span class="n">tabpfn_client</span>
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">!</span><span class="n">pip</span> <span class="n">install</span> <span class="n">nnetsauce</span>
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">tabpfn_client</span>

<span class="n">API_TOKEN</span> <span class="o">=</span> <span class="s">""</span> <span class="c1"># &lt;- Paste your TabPFN token here (from https://priorlabs.ai/tabpfn)
</span>

<span class="n">tabpfn_client</span><span class="p">.</span><span class="n">set_access_token</span><span class="p">(</span><span class="n">API_TOKEN</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sklearn.datasets</span> <span class="kn">import</span> <span class="n">load_diabetes</span>
<span class="kn">from</span> <span class="nn">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">train_test_split</span>
<span class="kn">from</span> <span class="nn">tabpfn_client</span> <span class="kn">import</span> <span class="n">TabPFNRegressor</span>
<span class="kn">from</span> <span class="nn">sklearn.metrics</span> <span class="kn">import</span> <span class="n">mean_squared_error</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>

<span class="n">reg</span> <span class="o">=</span> <span class="n">TabPFNRegressor</span><span class="p">()</span>

<span class="n">X</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">load_diabetes</span><span class="p">(</span><span class="n">return_X_y</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">X_train</span><span class="p">,</span> <span class="n">X_test</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">y_test</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">42</span><span class="p">)</span>

<span class="n">reg</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
<span class="n">preds</span> <span class="o">=</span> <span class="n">reg</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">)</span>
<span class="n">rmse</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">mean_squared_error</span><span class="p">(</span><span class="n">y_test</span><span class="p">,</span> <span class="n">preds</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="o">-</span><span class="n">rmse</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00:00 Fitting... |

WARNING:tabpfn_client.client:The provided train set hashes match previously uploaded train sets.


00:00 Fitting... Done!
00:00 Predicting... -

WARNING:tabpfn_client.client:The provided test set hash matches a previously uploaded test set.


00:01 Predicting... Done!
-51.559912022529886
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">nnetsauce</span> <span class="k">as</span> <span class="n">ns</span>

<span class="n">reg_conformal</span> <span class="o">=</span> <span class="n">ns</span><span class="p">.</span><span class="n">PredictionInterval</span><span class="p">(</span><span class="n">reg</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="mi">95</span><span class="p">)</span>
<span class="n">reg_conformal</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
<span class="n">preds</span> <span class="o">=</span> <span class="n">reg_conformal</span><span class="p">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">,</span> <span class="n">return_pi</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00:00 Fitting... |

WARNING:tabpfn_client.client:The provided train set hashes match previously uploaded train sets.


00:00 Fitting... Done!
00:00 Predicting... -

WARNING:tabpfn_client.client:The provided test set hash matches a previously uploaded test set.


00:01 Predicting... Done!
00:00 Predicting... -

WARNING:tabpfn_client.client:The provided test set hash matches a previously uploaded test set.


00:01 Predicting... Done!
00:00 Predicting... -

WARNING:tabpfn_client.client:The provided test set hash matches a previously uploaded test set.


00:01 Predicting... Done!
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"coverage_rate: </span><span class="si">{</span><span class="n">np</span><span class="p">.</span><span class="n">mean</span><span class="p">((</span><span class="n">preds</span><span class="p">.</span><span class="n">lower</span><span class="o">&lt;=</span><span class="n">y_test</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">preds</span><span class="p">.</span><span class="n">upper</span><span class="o">&gt;=</span><span class="n">y_test</span><span class="p">))</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>coverage_rate: 0.9662921348314607
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">warnings</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>


<span class="n">warnings</span><span class="p">.</span><span class="n">filterwarnings</span><span class="p">(</span><span class="s">'ignore'</span><span class="p">)</span>

<span class="n">split_color</span> <span class="o">=</span> <span class="s">'green'</span>
<span class="n">split_color2</span> <span class="o">=</span> <span class="s">'orange'</span>
<span class="n">local_color</span> <span class="o">=</span> <span class="s">'gray'</span>

<span class="k">def</span> <span class="nf">plot_func</span><span class="p">(</span><span class="n">x</span><span class="p">,</span>
              <span class="n">y</span><span class="p">,</span>
              <span class="n">y_u</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
              <span class="n">y_l</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
              <span class="n">pred</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
              <span class="n">shade_color</span><span class="o">=</span><span class="s">""</span><span class="p">,</span>
              <span class="n">method_name</span><span class="o">=</span><span class="s">""</span><span class="p">,</span>
              <span class="n">title</span><span class="o">=</span><span class="s">""</span><span class="p">):</span>

    <span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="p">.</span><span class="n">figure</span><span class="p">()</span>

    <span class="n">plt</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s">'k.'</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="p">.</span><span class="mi">3</span><span class="p">,</span> <span class="n">markersize</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span>
             <span class="n">fillstyle</span><span class="o">=</span><span class="s">'full'</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="sa">u</span><span class="s">'Test set observations'</span><span class="p">)</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">y_u</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">y_l</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">):</span>
        <span class="n">plt</span><span class="p">.</span><span class="n">fill</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">concatenate</span><span class="p">([</span><span class="n">x</span><span class="p">,</span> <span class="n">x</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]]),</span>
                 <span class="n">np</span><span class="p">.</span><span class="n">concatenate</span><span class="p">([</span><span class="n">y_u</span><span class="p">,</span> <span class="n">y_l</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]]),</span>
                 <span class="n">alpha</span><span class="o">=</span><span class="p">.</span><span class="mi">3</span><span class="p">,</span> <span class="n">fc</span><span class="o">=</span><span class="n">shade_color</span><span class="p">,</span> <span class="n">ec</span><span class="o">=</span><span class="s">'None'</span><span class="p">,</span>
                 <span class="n">label</span> <span class="o">=</span> <span class="n">method_name</span> <span class="o">+</span> <span class="s">' Prediction interval'</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">pred</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
        <span class="n">plt</span><span class="p">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">pred</span><span class="p">,</span> <span class="s">'k--'</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.9</span><span class="p">,</span>
                 <span class="n">label</span><span class="o">=</span><span class="sa">u</span><span class="s">'Predicted value'</span><span class="p">)</span>

    <span class="c1">#plt.ylim([-2.5, 7])
</span>    <span class="n">plt</span><span class="p">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s">'$X$'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s">'$Y$'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="s">'upper right'</span><span class="p">)</span>
    <span class="n">plt</span><span class="p">.</span><span class="n">title</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>

    <span class="n">plt</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>

</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">max_idx</span> <span class="o">=</span> <span class="mi">50</span>
<span class="n">plot_func</span><span class="p">(</span><span class="n">x</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_idx</span><span class="p">),</span>
          <span class="n">y</span> <span class="o">=</span> <span class="n">y_test</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">max_idx</span><span class="p">],</span>
          <span class="n">y_u</span> <span class="o">=</span> <span class="n">preds</span><span class="p">.</span><span class="n">upper</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">max_idx</span><span class="p">],</span>
          <span class="n">y_l</span> <span class="o">=</span> <span class="n">preds</span><span class="p">.</span><span class="n">lower</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">max_idx</span><span class="p">],</span>
          <span class="n">pred</span> <span class="o">=</span> <span class="n">preds</span><span class="p">.</span><span class="n">mean</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">max_idx</span><span class="p">],</span>
          <span class="n">shade_color</span><span class="o">=</span><span class="n">split_color2</span><span class="p">,</span>
          <span class="n">title</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"conformalized TabPFN (</span><span class="si">{</span><span class="n">max_idx</span><span class="si">}</span><span class="s"> first points in test set)"</span><span class="p">)</span>

</code></pre></div></div>

<p><img src="/images/2026-05-17/2026-05-17-conformalized-tabpfn_10_0.png" alt="image-title-here" class="img-responsive" /></p>

<h1 id="2---r-version">2 - R version</h1>

<p>For this R version, I used R in the same notebook as Python, in Google Colab.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%</span><span class="n">load_ext</span> <span class="n">rpy2</span><span class="p">.</span><span class="n">ipython</span>
</code></pre></div></div>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%</span><span class="n">R</span> <span class="n">install</span><span class="p">.</span><span class="n">packages</span><span class="p">(</span><span class="s">"reticulate"</span><span class="p">)</span>
</code></pre></div></div>

<div class="language-r highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">%%</span><span class="n">R</span><span class="w">

</span><span class="c1"># Conformalized TabPFN in R via reticulate</span><span class="w">

</span><span class="n">library</span><span class="p">(</span><span class="n">reticulate</span><span class="p">)</span><span class="w">

</span><span class="c1"># ── 0. Python environment ──────────────────────────────────────────────────────</span><span class="w">
</span><span class="c1"># Use your preferred Python env. Uncomment one (automatic on Google Colab):</span><span class="w">
</span><span class="c1"># use_python("/usr/bin/python3")</span><span class="w">
</span><span class="c1"># use_virtualenv("r-tabpfn")</span><span class="w">
</span><span class="c1"># use_condaenv("r-tabpfn")</span><span class="w">

</span><span class="c1"># Install required packages into the active Python env (run once)</span><span class="w">
</span><span class="c1"># py_install(c("tabpfn", "tabpfn_client", "nnetsauce", "scikit-learn",</span><span class="w">
</span><span class="c1">#              "matplotlib", "numpy"), pip = TRUE)</span><span class="w">

</span><span class="c1"># ── 1. Imports ─────────────────────────────────────────────────────────────────</span><span class="w">
</span><span class="n">sklearn_datasets</span><span class="w">  </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"sklearn.datasets"</span><span class="p">)</span><span class="w">
</span><span class="n">sklearn_model_sel</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"sklearn.model_selection"</span><span class="p">)</span><span class="w">
</span><span class="n">sklearn_metrics</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"sklearn.metrics"</span><span class="p">)</span><span class="w">
</span><span class="n">tabpfn_client</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"tabpfn_client"</span><span class="p">)</span><span class="w">
</span><span class="n">ns</span><span class="w">                </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"nnetsauce"</span><span class="p">)</span><span class="w">
</span><span class="n">np</span><span class="w">                </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"numpy"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="w">               </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"matplotlib.pyplot"</span><span class="p">)</span><span class="w">
</span><span class="n">warnings</span><span class="w">          </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">import</span><span class="p">(</span><span class="s2">"warnings"</span><span class="p">)</span><span class="w">

</span><span class="c1"># ── 2. TabPFN API token ────────────────────────────────────────────────────────</span><span class="w">
</span><span class="n">API_TOKEN</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="s2">""</span><span class="w">   </span><span class="c1"># &lt;-- paste your TabPFN token here (from https://priorlabs.ai/tabpfn)</span><span class="w">
</span><span class="n">tabpfn_client</span><span class="o">$</span><span class="n">set_access_token</span><span class="p">(</span><span class="n">API_TOKEN</span><span class="p">)</span><span class="w">

</span><span class="n">TabPFNRegressor</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">tabpfn_client</span><span class="o">$</span><span class="n">TabPFNRegressor</span><span class="w">

</span><span class="c1"># ── 3. Data ────────────────────────────────────────────────────────────────────</span><span class="w">
</span><span class="n">diabetes</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sklearn_datasets</span><span class="o">$</span><span class="n">load_diabetes</span><span class="p">(</span><span class="n">return_X_y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">)</span><span class="w">
</span><span class="n">X</span><span class="w">          </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">diabetes</span><span class="p">[[</span><span class="m">1</span><span class="p">]]</span><span class="w">
</span><span class="n">y</span><span class="w">          </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">diabetes</span><span class="p">[[</span><span class="m">2</span><span class="p">]]</span><span class="w">

</span><span class="n">split</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">sklearn_model_sel</span><span class="o">$</span><span class="n">train_test_split</span><span class="p">(</span><span class="n">X</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w"> </span><span class="n">test_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.2</span><span class="p">,</span><span class="w"> </span><span class="n">random_state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">42L</span><span class="p">)</span><span class="w">
</span><span class="n">X_train</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">split</span><span class="p">[[</span><span class="m">1</span><span class="p">]]</span><span class="w">
</span><span class="n">X_test</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">split</span><span class="p">[[</span><span class="m">2</span><span class="p">]]</span><span class="w">
</span><span class="n">y_train</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">split</span><span class="p">[[</span><span class="m">3</span><span class="p">]]</span><span class="w">
</span><span class="n">y_test</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">split</span><span class="p">[[</span><span class="m">4</span><span class="p">]]</span><span class="w">

</span><span class="c1"># ── 4. Fit TabPFN regressor ────────────────────────────────────────────────────</span><span class="w">
</span><span class="n">reg</span><span class="w">   </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">TabPFNRegressor</span><span class="p">()</span><span class="w">
</span><span class="n">reg</span><span class="o">$</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span><span class="w"> </span><span class="n">y_train</span><span class="p">)</span><span class="w">
</span><span class="n">preds_plain</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">reg</span><span class="o">$</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">)</span><span class="w">

</span><span class="n">rmse</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">sqrt</span><span class="p">(</span><span class="n">sklearn_metrics</span><span class="o">$</span><span class="n">mean_squared_error</span><span class="p">(</span><span class="n">y_test</span><span class="p">,</span><span class="w"> </span><span class="n">preds_plain</span><span class="p">))</span><span class="w">
</span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"TabPFN RMSE: %.4f\n"</span><span class="p">,</span><span class="w"> </span><span class="n">rmse</span><span class="p">))</span><span class="w">

</span><span class="c1"># ── 5. Conformal prediction with nnetsauce ─────────────────────────────────────</span><span class="w">
</span><span class="n">reg_conformal</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ns</span><span class="o">$</span><span class="n">PredictionInterval</span><span class="p">(</span><span class="n">reg</span><span class="p">,</span><span class="w"> </span><span class="n">level</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">95L</span><span class="p">)</span><span class="w">
</span><span class="n">reg_conformal</span><span class="o">$</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span><span class="w"> </span><span class="n">y_train</span><span class="p">)</span><span class="w">
</span><span class="n">preds</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">reg_conformal</span><span class="o">$</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">,</span><span class="w"> </span><span class="n">return_pi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">)</span><span class="w">

</span><span class="n">coverage</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">np</span><span class="o">$</span><span class="n">mean</span><span class="p">((</span><span class="n">preds</span><span class="o">$</span><span class="n">lower</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">y_test</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">preds</span><span class="o">$</span><span class="n">upper</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">y_test</span><span class="p">))</span><span class="w">
</span><span class="n">cat</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"Coverage rate: %.4f\n"</span><span class="p">,</span><span class="w"> </span><span class="n">coverage</span><span class="p">))</span><span class="w">

</span><span class="c1"># ── 6. Plot (first 50 test points) ────────────────────────────────────────────</span><span class="w">
</span><span class="n">warnings</span><span class="o">$</span><span class="n">filterwarnings</span><span class="p">(</span><span class="s2">"ignore"</span><span class="p">)</span><span class="w">

</span><span class="n">max_idx</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="m">50L</span><span class="w">
</span><span class="n">x_range</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">np</span><span class="o">$</span><span class="n">array</span><span class="p">(</span><span class="m">0</span><span class="o">:</span><span class="p">(</span><span class="n">max_idx</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">))</span><span class="w">   </span><span class="c1"># numeric index</span><span class="w">
</span><span class="n">y_obs</span><span class="w">      </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">y_test</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="n">max_idx</span><span class="p">]</span><span class="w">
</span><span class="n">y_upper</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">preds</span><span class="o">$</span><span class="n">upper</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="n">max_idx</span><span class="p">]</span><span class="w">
</span><span class="n">y_lower</span><span class="w">    </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">preds</span><span class="o">$</span><span class="n">lower</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="n">max_idx</span><span class="p">]</span><span class="w">
</span><span class="n">y_pred</span><span class="w">     </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">preds</span><span class="o">$</span><span class="n">mean</span><span class="p">[</span><span class="m">1</span><span class="o">:</span><span class="n">max_idx</span><span class="p">]</span><span class="w">

</span><span class="c1"># Build the filled polygon (matplotlib-style concatenation)</span><span class="w">
</span><span class="n">x_fill</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">np</span><span class="o">$</span><span class="n">concatenate</span><span class="p">(</span><span class="nf">list</span><span class="p">(</span><span class="n">x_range</span><span class="p">,</span><span class="w"> </span><span class="n">x_range</span><span class="p">[</span><span class="n">max_idx</span><span class="o">:</span><span class="m">1</span><span class="p">]))</span><span class="w">
</span><span class="n">y_fill</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">np</span><span class="o">$</span><span class="n">concatenate</span><span class="p">(</span><span class="nf">list</span><span class="p">(</span><span class="n">y_upper</span><span class="p">,</span><span class="w"> </span><span class="n">y_lower</span><span class="p">[</span><span class="n">max_idx</span><span class="o">:</span><span class="m">1</span><span class="p">]))</span><span class="w">

</span><span class="n">fig</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">plt</span><span class="o">$</span><span class="n">figure</span><span class="p">()</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">plot</span><span class="p">(</span><span class="n">x_range</span><span class="p">,</span><span class="w"> </span><span class="n">y_obs</span><span class="p">,</span><span class="w">  </span><span class="s2">"k."</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="n">markersize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">10L</span><span class="p">,</span><span class="w">
         </span><span class="n">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Test set observations"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">fill</span><span class="p">(</span><span class="n">x_fill</span><span class="p">,</span><span class="w"> </span><span class="n">y_fill</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.3</span><span class="p">,</span><span class="w"> </span><span class="n">fc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"orange"</span><span class="p">,</span><span class="w"> </span><span class="n">ec</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"None"</span><span class="p">,</span><span class="w">
         </span><span class="n">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Conformal Prediction interval"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">plot</span><span class="p">(</span><span class="n">x_range</span><span class="p">,</span><span class="w"> </span><span class="n">y_pred</span><span class="p">,</span><span class="w"> </span><span class="s2">"k--"</span><span class="p">,</span><span class="w"> </span><span class="n">lw</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">2L</span><span class="p">,</span><span class="w"> </span><span class="n">alpha</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.9</span><span class="p">,</span><span class="w">
         </span><span class="n">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Predicted value"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">xlabel</span><span class="p">(</span><span class="s2">"Index"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">"Y"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"upper right"</span><span class="p">)</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">title</span><span class="p">(</span><span class="n">sprintf</span><span class="p">(</span><span class="s2">"Conformalized TabPFN (first %d points in test set)"</span><span class="p">,</span><span class="w"> </span><span class="n">max_idx</span><span class="p">))</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">tight_layout</span><span class="p">()</span><span class="w">
</span><span class="n">plt</span><span class="o">$</span><span class="n">show</span><span class="p">()</span><span class="w">
</span><span class="c1"># To save instead: plt$savefig("conformalized_tabpfn.png", dpi = 150L)</span><span class="w">
</span></code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00:02 Fitting... Done!
00:02 Predicting... Done!
TabPFN RMSE: 51.5599
00:01 Fitting... Done!
00:02 Predicting... Done!
00:00 Predicting... -

WARNING:tabpfn_client.client:The provided test set hash matches a previously uploaded test set.


00:01 Predicting... Done!
00:02 Predicting... Done!
Coverage rate: 0.9663
</code></pre></div></div>

<p><img src="/images/2026-05-17/2026-05-17-conformalized-tabpfn_14_3.png" alt="image-title-here" class="img-responsive" /></p>]]></content><author><name></name></author><category term="R" /><category term="Python" /><summary type="html"><![CDATA[Prediction Intervals for Tabular Regression in Python and R via Conformalized TabPFN]]></summary></entry><entry><title type="html">Probabilistic Time Series Cross-Validation with R package crossvalidation</title><link href="https://thierrymoudiki.github.io/blog/2026/05/16/r/crossvalidation" rel="alternate" type="text/html" title="Probabilistic Time Series Cross-Validation with R package crossvalidation" /><published>2026-05-16T00:00:00+00:00</published><updated>2026-05-16T00:00:00+00:00</updated><id>https://thierrymoudiki.github.io/blog/2026/05/16/r/crossvalidation</id><content type="html" xml:base="https://thierrymoudiki.github.io/blog/2026/05/16/r/crossvalidation"><![CDATA[<p>A previous post introduced the <code class="language-plaintext highlighter-rouge">crossvalidation</code> package for R. This time, the focus is on probabilistic forecasting — evaluating not just how accurate point forecasts are, but how well-calibrated prediction intervals are, using empirical coverage rates and Winkler scores – and <code class="language-plaintext highlighter-rouge">crossvalidation</code>.</p>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">install.packages</span><span class="p">(</span><span class="s2">"remotes"</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">install.packages</span><span class="p">(</span><span class="s2">"forecast"</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">remotes</span><span class="o">::</span><span class="n">install_github</span><span class="p">(</span><span class="s2">"Techtonique/crossvalidation"</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">library</span><span class="p">(</span><span class="n">crossvalidation</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<h1 id="example-1">Example 1</h1>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">require</span><span class="p">(</span><span class="n">forecast</span><span class="p">)</span><span class="w">
</span><span class="n">data</span><span class="p">(</span><span class="s2">"AirPassengers"</span><span class="p">)</span><span class="w">



</span><span class="n">eval_metric</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">predicted</span><span class="p">,</span><span class="w"> </span><span class="n">observed</span><span class="p">)</span><span class="w">
</span><span class="p">{</span><span class="w">
  </span><span class="n">error</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">observed</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">predicted</span><span class="o">$</span><span class="n">mean</span><span class="w">

  </span><span class="n">me</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">error</span><span class="p">)</span><span class="w">
  </span><span class="n">rmse</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">sqrt</span><span class="p">(</span><span class="n">mean</span><span class="p">(</span><span class="n">error</span><span class="o">^</span><span class="m">2</span><span class="p">))</span><span class="w">
  </span><span class="n">mae</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="nf">abs</span><span class="p">(</span><span class="n">error</span><span class="p">))</span><span class="w">

  </span><span class="c1"># ----- 80% interval -----</span><span class="w">

  </span><span class="n">lower80</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">predicted</span><span class="o">$</span><span class="n">lower</span><span class="p">[,</span><span class="w"> </span><span class="m">1</span><span class="p">]</span><span class="w">
  </span><span class="n">upper80</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">predicted</span><span class="o">$</span><span class="n">upper</span><span class="p">[,</span><span class="w"> </span><span class="m">1</span><span class="p">]</span><span class="w">

  </span><span class="n">coverage80</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="w">
    </span><span class="n">observed</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">lower80</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">observed</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">upper80</span><span class="w">
  </span><span class="p">)</span><span class="w">

  </span><span class="n">alpha80</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="m">0.20</span><span class="w">

  </span><span class="n">winkler80</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ifelse</span><span class="p">(</span><span class="w">
    </span><span class="n">observed</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">lower80</span><span class="p">,</span><span class="w">
    </span><span class="p">(</span><span class="n">upper80</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower80</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">alpha80</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">lower80</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">observed</span><span class="p">),</span><span class="w">
    </span><span class="n">ifelse</span><span class="p">(</span><span class="w">
      </span><span class="n">observed</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">upper80</span><span class="p">,</span><span class="w">
      </span><span class="p">(</span><span class="n">upper80</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower80</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">alpha80</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">observed</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">upper80</span><span class="p">),</span><span class="w">
      </span><span class="p">(</span><span class="n">upper80</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower80</span><span class="p">)</span><span class="w">
    </span><span class="p">)</span><span class="w">
  </span><span class="p">)</span><span class="w">

  </span><span class="c1"># ----- 95% interval -----</span><span class="w">

  </span><span class="n">lower95</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">predicted</span><span class="o">$</span><span class="n">lower</span><span class="p">[,</span><span class="w"> </span><span class="m">2</span><span class="p">]</span><span class="w">
  </span><span class="n">upper95</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">predicted</span><span class="o">$</span><span class="n">upper</span><span class="p">[,</span><span class="w"> </span><span class="m">2</span><span class="p">]</span><span class="w">

  </span><span class="n">coverage95</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="w">
    </span><span class="n">observed</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">lower95</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">observed</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">upper95</span><span class="w">
  </span><span class="p">)</span><span class="w">

  </span><span class="n">alpha95</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="m">0.05</span><span class="w">

  </span><span class="n">winkler95</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ifelse</span><span class="p">(</span><span class="w">
    </span><span class="n">observed</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">lower95</span><span class="p">,</span><span class="w">
    </span><span class="p">(</span><span class="n">upper95</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower95</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">alpha95</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">lower95</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">observed</span><span class="p">),</span><span class="w">
    </span><span class="n">ifelse</span><span class="p">(</span><span class="w">
      </span><span class="n">observed</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">upper95</span><span class="p">,</span><span class="w">
      </span><span class="p">(</span><span class="n">upper95</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower95</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">alpha95</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">observed</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">upper95</span><span class="p">),</span><span class="w">
      </span><span class="p">(</span><span class="n">upper95</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower95</span><span class="p">)</span><span class="w">
    </span><span class="p">)</span><span class="w">
  </span><span class="p">)</span><span class="w">

  </span><span class="nf">c</span><span class="p">(</span><span class="w">
    </span><span class="n">ME</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">me</span><span class="p">,</span><span class="w">
    </span><span class="n">RMSE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rmse</span><span class="p">,</span><span class="w">
    </span><span class="n">MAE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mae</span><span class="p">,</span><span class="w">
    </span><span class="n">Coverage80</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">coverage80</span><span class="p">,</span><span class="w">
    </span><span class="n">Winkler80</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">winkler80</span><span class="p">),</span><span class="w">
    </span><span class="n">Coverage95</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">coverage95</span><span class="p">,</span><span class="w">
    </span><span class="n">Winkler95</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">winkler95</span><span class="p">)</span><span class="w">
  </span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="p">(</span><span class="n">res</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">crossval_ts</span><span class="p">(</span><span class="n">y</span><span class="o">=</span><span class="n">AirPassengers</span><span class="p">,</span><span class="w"> </span><span class="n">initial_window</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">10</span><span class="p">,</span><span class="w">
</span><span class="n">horizon</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3</span><span class="p">,</span><span class="w"> </span><span class="n">fcast_func</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">forecast</span><span class="o">::</span><span class="n">thetaf</span><span class="p">,</span><span class="w"> </span><span class="n">eval_metric</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">eval_metric</span><span class="p">))</span><span class="w">
</span><span class="n">print</span><span class="p">(</span><span class="n">colMeans</span><span class="p">(</span><span class="n">res</span><span class="p">))</span><span class="w">

</span></code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Loading required package: forecast



  |======================================================================| 100%
</code></pre></div></div>

<table class="dataframe">
<caption>A matrix: 132 × 7 of type dbl</caption>
<thead>
	<tr><th></th><th scope="col">ME</th><th scope="col">RMSE</th><th scope="col">MAE</th><th scope="col">Coverage80</th><th scope="col">Winkler80</th><th scope="col">Coverage95</th><th scope="col">Winkler95</th></tr>
</thead>
<tbody>
	<tr><th scope="row">result.1</th><td>-28.794660</td><td>29.300287</td><td>28.794660</td><td>0.0000000</td><td>153.10992</td><td>0.3333333</td><td>207.58384</td></tr>
	<tr><th scope="row">result.2</th><td> 16.198526</td><td>16.894302</td><td>16.198526</td><td>1.0000000</td><td> 45.01795</td><td>1.0000000</td><td> 68.84902</td></tr>
	<tr><th scope="row">result.3</th><td> 11.201494</td><td>15.993359</td><td>12.578276</td><td>1.0000000</td><td> 45.05996</td><td>1.0000000</td><td> 68.91326</td></tr>
	<tr><th scope="row">result.4</th><td> 21.430125</td><td>22.483895</td><td>21.430125</td><td>0.6666667</td><td> 63.01207</td><td>1.0000000</td><td> 68.84778</td></tr>
	<tr><th scope="row">result.5</th><td> 10.055765</td><td>11.527746</td><td>10.055765</td><td>1.0000000</td><td> 45.99967</td><td>1.0000000</td><td> 70.35043</td></tr>
	<tr><th scope="row">result.6</th><td> -2.640822</td><td>10.676714</td><td> 9.999466</td><td>1.0000000</td><td> 46.56907</td><td>1.0000000</td><td> 71.22125</td></tr>
	<tr><th scope="row">result.7</th><td> 14.296434</td><td>23.709132</td><td>20.531135</td><td>0.6666667</td><td> 75.04186</td><td>1.0000000</td><td> 67.58381</td></tr>
	<tr><th scope="row">result.8</th><td> 38.247497</td><td>39.529998</td><td>38.247497</td><td>0.0000000</td><td>198.74990</td><td>0.3333333</td><td>212.44029</td></tr>
	<tr><th scope="row">result.9</th><td> 23.043159</td><td>23.947630</td><td>23.043159</td><td>0.3333333</td><td> 93.83463</td><td>1.0000000</td><td> 64.19366</td></tr>
	<tr><th scope="row">result.10</th><td>-21.689067</td><td>27.907560</td><td>21.689067</td><td>0.6666667</td><td> 90.23377</td><td>1.0000000</td><td> 84.12361</td></tr>
	<tr><th scope="row">result.11</th><td>-41.782157</td><td>46.664199</td><td>41.782157</td><td>0.3333333</td><td>222.06310</td><td>0.3333333</td><td>345.16553</td></tr>
	<tr><th scope="row">result.12</th><td>-34.934831</td><td>36.512081</td><td>34.934831</td><td>0.3333333</td><td>162.38092</td><td>0.6666667</td><td>212.58117</td></tr>
	<tr><th scope="row">result.13</th><td> -4.002700</td><td>12.728771</td><td> 9.999100</td><td>1.0000000</td><td> 59.64475</td><td>1.0000000</td><td> 91.21878</td></tr>
	<tr><th scope="row">result.14</th><td> 30.349582</td><td>30.588761</td><td>30.349582</td><td>0.6666667</td><td> 72.14355</td><td>1.0000000</td><td> 99.76932</td></tr>
	<tr><th scope="row">result.15</th><td> 21.192349</td><td>25.806712</td><td>21.192349</td><td>0.6666667</td><td> 71.39094</td><td>1.0000000</td><td>101.02401</td></tr>
	<tr><th scope="row">result.16</th><td> 23.193143</td><td>25.914875</td><td>23.193143</td><td>0.6666667</td><td> 91.70660</td><td>1.0000000</td><td> 76.57925</td></tr>
	<tr><th scope="row">result.17</th><td> 30.081542</td><td>30.679960</td><td>30.081542</td><td>0.3333333</td><td>111.58689</td><td>1.0000000</td><td> 75.78459</td></tr>
	<tr><th scope="row">result.18</th><td> -6.530509</td><td> 9.111376</td><td> 6.999059</td><td>1.0000000</td><td> 69.51704</td><td>1.0000000</td><td>106.31714</td></tr>
	<tr><th scope="row">result.19</th><td> 19.907586</td><td>23.010762</td><td>19.907586</td><td>1.0000000</td><td> 67.03506</td><td>1.0000000</td><td>102.52128</td></tr>
	<tr><th scope="row">result.20</th><td> 17.631089</td><td>19.829355</td><td>17.631089</td><td>1.0000000</td><td> 67.97573</td><td>1.0000000</td><td>103.95991</td></tr>
	<tr><th scope="row">result.21</th><td> 11.738022</td><td>14.718185</td><td>12.229846</td><td>1.0000000</td><td> 61.61617</td><td>1.0000000</td><td> 94.23380</td></tr>
	<tr><th scope="row">result.22</th><td>-21.787490</td><td>28.489509</td><td>21.787490</td><td>0.6666667</td><td> 93.30920</td><td>1.0000000</td><td> 88.70090</td></tr>
	<tr><th scope="row">result.23</th><td>-43.557571</td><td>47.527244</td><td>43.557571</td><td>0.3333333</td><td>206.77368</td><td>0.6666667</td><td>216.50078</td></tr>
	<tr><th scope="row">result.24</th><td>-34.473558</td><td>35.514155</td><td>34.473558</td><td>0.3333333</td><td>146.63288</td><td>0.6666667</td><td>173.17046</td></tr>
	<tr><th scope="row">result.25</th><td> -4.699360</td><td>10.498595</td><td> 7.201224</td><td>1.0000000</td><td> 60.07550</td><td>1.0000000</td><td> 91.87755</td></tr>
	<tr><th scope="row">result.26</th><td> 25.974138</td><td>26.581272</td><td>25.974138</td><td>1.0000000</td><td> 63.01942</td><td>1.0000000</td><td> 96.37989</td></tr>
	<tr><th scope="row">result.27</th><td> 16.905109</td><td>19.474600</td><td>16.905109</td><td>1.0000000</td><td> 58.04472</td><td>1.0000000</td><td> 88.77173</td></tr>
	<tr><th scope="row">result.28</th><td> 15.218760</td><td>16.352917</td><td>15.218760</td><td>1.0000000</td><td> 55.27721</td><td>1.0000000</td><td> 84.53920</td></tr>
	<tr><th scope="row">result.29</th><td>  7.625241</td><td> 8.933828</td><td> 7.625241</td><td>1.0000000</td><td> 55.27718</td><td>1.0000000</td><td> 84.53916</td></tr>
	<tr><th scope="row">result.30</th><td>  2.261970</td><td>17.595326</td><td>15.666212</td><td>1.0000000</td><td> 57.13292</td><td>1.0000000</td><td> 87.37725</td></tr>
	<tr><th scope="row">⋮</th><td>⋮</td><td>⋮</td><td>⋮</td><td>⋮</td><td>⋮</td><td>⋮</td><td>⋮</td></tr>
	<tr><th scope="row">result.103</th><td>  95.047754</td><td>111.26440</td><td> 95.04775</td><td>0.3333333</td><td> 485.7096</td><td>0.6666667</td><td> 594.3549</td></tr>
	<tr><th scope="row">result.104</th><td> 121.335201</td><td>125.76554</td><td>121.33520</td><td>0.0000000</td><td> 646.5750</td><td>0.3333333</td><td> 772.4818</td></tr>
	<tr><th scope="row">result.105</th><td>  27.661546</td><td> 53.66952</td><td> 52.33567</td><td>0.6666667</td><td> 149.4669</td><td>1.0000000</td><td> 226.7499</td></tr>
	<tr><th scope="row">result.106</th><td> -82.928463</td><td>106.53675</td><td> 87.39838</td><td>0.3333333</td><td> 439.0476</td><td>0.6666667</td><td> 391.0034</td></tr>
	<tr><th scope="row">result.107</th><td>-168.429957</td><td>174.86402</td><td>168.42996</td><td>0.0000000</td><td>1125.8534</td><td>0.0000000</td><td>2680.3671</td></tr>
	<tr><th scope="row">result.108</th><td> -86.047368</td><td> 89.34969</td><td> 86.04737</td><td>0.6666667</td><td> 241.5086</td><td>1.0000000</td><td> 281.3325</td></tr>
	<tr><th scope="row">result.109</th><td> -35.392983</td><td> 38.64620</td><td> 35.39298</td><td>1.0000000</td><td> 192.3314</td><td>1.0000000</td><td> 294.1455</td></tr>
	<tr><th scope="row">result.110</th><td>  32.273683</td><td> 33.69167</td><td> 32.27368</td><td>1.0000000</td><td> 199.9978</td><td>1.0000000</td><td> 305.8702</td></tr>
	<tr><th scope="row">result.111</th><td>  35.911969</td><td> 45.52857</td><td> 35.91197</td><td>1.0000000</td><td> 195.2069</td><td>1.0000000</td><td> 298.5432</td></tr>
	<tr><th scope="row">result.112</th><td>  28.584481</td><td> 41.79144</td><td> 38.16654</td><td>1.0000000</td><td> 196.5409</td><td>1.0000000</td><td> 300.5833</td></tr>
	<tr><th scope="row">result.113</th><td>  78.144295</td><td> 79.31310</td><td> 78.14430</td><td>1.0000000</td><td> 196.9343</td><td>1.0000000</td><td> 301.1850</td></tr>
	<tr><th scope="row">result.114</th><td>  37.152546</td><td> 52.61404</td><td> 39.21044</td><td>1.0000000</td><td> 192.5487</td><td>1.0000000</td><td> 294.4778</td></tr>
	<tr><th scope="row">result.115</th><td>  95.078342</td><td>110.88602</td><td> 95.07834</td><td>0.6666667</td><td> 366.3676</td><td>1.0000000</td><td> 274.9151</td></tr>
	<tr><th scope="row">result.116</th><td> 109.166178</td><td>116.17612</td><td>109.16618</td><td>0.3333333</td><td> 406.7397</td><td>1.0000000</td><td> 277.4405</td></tr>
	<tr><th scope="row">result.117</th><td>  41.289554</td><td> 62.02085</td><td> 57.33490</td><td>0.3333333</td><td> 215.1577</td><td>1.0000000</td><td> 222.4127</td></tr>
	<tr><th scope="row">result.118</th><td> -92.399494</td><td>116.61777</td><td> 92.82407</td><td>0.3333333</td><td> 466.7285</td><td>0.6666667</td><td> 445.3571</td></tr>
	<tr><th scope="row">result.119</th><td>-175.618445</td><td>183.27955</td><td>175.61845</td><td>0.0000000</td><td>1143.5479</td><td>0.0000000</td><td>2574.2409</td></tr>
	<tr><th scope="row">result.120</th><td> -94.580461</td><td> 97.36039</td><td> 94.58046</td><td>0.6666667</td><td> 277.7847</td><td>1.0000000</td><td> 293.2590</td></tr>
	<tr><th scope="row">result.121</th><td> -27.751828</td><td> 32.93559</td><td> 27.75183</td><td>1.0000000</td><td> 202.1374</td><td>1.0000000</td><td> 309.1425</td></tr>
	<tr><th scope="row">result.122</th><td>  36.177008</td><td> 38.16646</td><td> 36.17701</td><td>1.0000000</td><td> 208.6352</td><td>1.0000000</td><td> 319.0800</td></tr>
	<tr><th scope="row">result.123</th><td>   5.992278</td><td> 14.16185</td><td> 13.99743</td><td>1.0000000</td><td> 200.0098</td><td>1.0000000</td><td> 305.8885</td></tr>
	<tr><th scope="row">result.124</th><td>  12.637863</td><td> 33.65269</td><td> 27.98030</td><td>1.0000000</td><td> 200.1828</td><td>1.0000000</td><td> 306.1532</td></tr>
	<tr><th scope="row">result.125</th><td>  71.834372</td><td> 76.95073</td><td> 71.83437</td><td>1.0000000</td><td> 200.5753</td><td>1.0000000</td><td> 306.7534</td></tr>
	<tr><th scope="row">result.126</th><td>  85.518711</td><td> 93.75094</td><td> 85.51871</td><td>0.6666667</td><td> 252.5638</td><td>1.0000000</td><td> 295.0496</td></tr>
	<tr><th scope="row">result.127</th><td>  94.429064</td><td>115.52397</td><td> 94.42906</td><td>0.6666667</td><td> 407.3636</td><td>0.6666667</td><td> 417.2566</td></tr>
	<tr><th scope="row">result.128</th><td> 173.325805</td><td>177.66652</td><td>173.32580</td><td>0.0000000</td><td>1129.6141</td><td>0.0000000</td><td>2547.8618</td></tr>
	<tr><th scope="row">result.129</th><td>  33.890665</td><td> 63.84191</td><td> 61.66861</td><td>0.6666667</td><td> 242.6901</td><td>1.0000000</td><td> 230.3885</td></tr>
	<tr><th scope="row">result.130</th><td>-119.059067</td><td>137.73685</td><td>119.05907</td><td>0.3333333</td><td> 619.4166</td><td>0.3333333</td><td> 668.9786</td></tr>
	<tr><th scope="row">result.131</th><td>-180.821172</td><td>190.45241</td><td>180.82117</td><td>0.0000000</td><td>1152.4949</td><td>0.0000000</td><td>2469.3936</td></tr>
	<tr><th scope="row">result.132</th><td>-103.156396</td><td>108.61881</td><td>103.15640</td><td>0.6666667</td><td> 330.0400</td><td>1.0000000</td><td> 302.1675</td></tr>
</tbody>
</table>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>         ME        RMSE         MAE  Coverage80   Winkler80  Coverage95 
  2.6570822  51.4271704  46.5118747   0.6590909 218.4527816   0.8459596 
  Winkler95 
312.1383104 
</code></pre></div></div>

<h1 id="example-2">Example 2</h1>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">eval_metric</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">predicted</span><span class="p">,</span><span class="w"> </span><span class="n">observed</span><span class="p">)</span><span class="w">
</span><span class="p">{</span><span class="w">
  </span><span class="n">error</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">observed</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">predicted</span><span class="o">$</span><span class="n">mean</span><span class="w">

  </span><span class="n">me</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">error</span><span class="p">)</span><span class="w">
  </span><span class="n">rmse</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nf">sqrt</span><span class="p">(</span><span class="n">mean</span><span class="p">(</span><span class="n">error</span><span class="o">^</span><span class="m">2</span><span class="p">))</span><span class="w">
  </span><span class="n">mae</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="nf">abs</span><span class="p">(</span><span class="n">error</span><span class="p">))</span><span class="w">

  </span><span class="c1"># Only one interval returned</span><span class="w">
  </span><span class="n">lower</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">predicted</span><span class="o">$</span><span class="n">lower</span><span class="w">
  </span><span class="n">upper</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">predicted</span><span class="o">$</span><span class="n">upper</span><span class="w">

  </span><span class="n">coverage</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="w">
    </span><span class="n">observed</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">lower</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">observed</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">upper</span><span class="w">
  </span><span class="p">)</span><span class="w">

  </span><span class="n">alpha</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="m">0.05</span><span class="w">

  </span><span class="n">winkler</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">ifelse</span><span class="p">(</span><span class="w">
    </span><span class="n">observed</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">lower</span><span class="p">,</span><span class="w">
    </span><span class="p">(</span><span class="n">upper</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">alpha</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">lower</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">observed</span><span class="p">),</span><span class="w">
    </span><span class="n">ifelse</span><span class="p">(</span><span class="w">
      </span><span class="n">observed</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">upper</span><span class="p">,</span><span class="w">
      </span><span class="p">(</span><span class="n">upper</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">alpha</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">observed</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">upper</span><span class="p">),</span><span class="w">
      </span><span class="p">(</span><span class="n">upper</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lower</span><span class="p">)</span><span class="w">
    </span><span class="p">)</span><span class="w">
  </span><span class="p">)</span><span class="w">

  </span><span class="nf">c</span><span class="p">(</span><span class="w">
    </span><span class="n">ME</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">me</span><span class="p">,</span><span class="w">
    </span><span class="n">RMSE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rmse</span><span class="p">,</span><span class="w">
    </span><span class="n">MAE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mae</span><span class="p">,</span><span class="w">
    </span><span class="n">Coverage95</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">coverage</span><span class="p">,</span><span class="w">
    </span><span class="n">Winkler95</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mean</span><span class="p">(</span><span class="n">winkler</span><span class="p">)</span><span class="w">
  </span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">fcast_func</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">y</span><span class="p">,</span><span class="w"> </span><span class="n">h</span><span class="p">,</span><span class="w"> </span><span class="n">...</span><span class="p">)</span><span class="w">
</span><span class="p">{</span><span class="w">
  </span><span class="n">forecast</span><span class="o">::</span><span class="n">thetaf</span><span class="p">(</span><span class="w">
    </span><span class="n">y</span><span class="p">,</span><span class="w">
    </span><span class="n">h</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">h</span><span class="p">,</span><span class="w">
    </span><span class="n">level</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">95</span><span class="w">
  </span><span class="p">)</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">res</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="n">crossval_ts</span><span class="p">(</span><span class="w">
  </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AirPassengers</span><span class="p">,</span><span class="w">
  </span><span class="n">initial_window</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">10</span><span class="p">,</span><span class="w">
  </span><span class="n">horizon</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">3</span><span class="p">,</span><span class="w">
  </span><span class="n">fcast_func</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">fcast_func</span><span class="p">,</span><span class="w">
  </span><span class="n">eval_metric</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">eval_metric</span><span class="w">
</span><span class="p">)</span><span class="w">

</span><span class="n">print</span><span class="p">(</span><span class="n">colMeans</span><span class="p">(</span><span class="n">res</span><span class="p">))</span><span class="w">
</span></code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  |======================================================================| 100%
         ME        RMSE         MAE  Coverage95   Winkler95 
  2.6570822  51.4271704  46.5118747   0.8459596 312.1383104 
</code></pre></div></div>

<div class="language-R highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">boxplot</span><span class="p">(</span><span class="n">res</span><span class="p">[,</span><span class="w"> </span><span class="s2">"Coverage95"</span><span class="p">])</span><span class="w">
</span></code></pre></div></div>

<p><img src="/images/2026-05-16/2026-05-16-crossvalidation_10_0.png" alt="image-title-here" class="img-responsive" /></p>]]></content><author><name></name></author><category term="R" /><summary type="html"><![CDATA[Examples of use of R package crossvalidation for Probabilistic Time Series Cross-Validation (measuring coverage and Winkler score)]]></summary></entry></feed>