Conformalized TabICL: Prediction Intervals for a State-Of-The-Art Tabular Foundation Model in Python and R

R-bloggers 2026-05-21

[This article was first published on T. Moudiki's Webpage - R, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

A few days ago, I presented Conformalized TabPFN: Prediction Intervals for a Pretrained Transformer for Tabular Data in Python and R. Today, it’s about TabICL, another state-of-the-art tabular foundation model. TabICL requires no token, as you’ll notice in the following Python and R code.

1 – Python version

!pip install tabicl nnetsauce # scikit-learn matplotlib numpyfrom sklearn.datasets import load_diabetesfrom sklearn.model_selection import train_test_splitfrom sklearn.linear_model import RidgeCVfrom sklearn.metrics import mean_squared_errorfrom tabicl import TabICLRegressorimport nnetsauce as nsimport numpy as npimport matplotlib.pyplot as pltfrom time import time# ── data ───────────────────────────────────────────────────X, y = load_diabetes(return_X_y=True)X_train, X_test, y_train, y_test = train_test_split(    X, y, test_size=0.2, random_state=42)# ── base models ────────────────────────────────────────────models = {    "TabICL": TabICLRegressor(),    "RidgeCV": RidgeCV(),}results = {}for name, reg in models.items():    start = time()    conf = ns.PredictionInterval(reg, level=95)    conf.fit(X_train, y_train)    pi = conf.predict(X_test, return_pi=True)    print(f"{name:10s}  time={time() - start:.1f}s")    coverage = np.mean((pi.lower <= y_test) & (pi.upper >= y_test))    width    = np.mean(pi.upper - pi.lower)    rmse     = np.sqrt(mean_squared_error(y_test, pi.mean))    results[name] = {"pi": pi, "coverage": coverage,                     "width": width, "rmse": rmse}    print(f"{name:10s}  RMSE={rmse:.1f}  "          f"coverage={coverage:.3f}  avg_width={width:.1f}")# ── plot side-by-side ──────────────────────────────────────fig, axes = plt.subplots(1, 2, figsize=(12, 4), sharey=True)colors = {"TabICL": "orange", "RidgeCV": "steelblue"}max_idx = 50for ax, (name, res) in zip(axes, results.items()):    pi = res["pi"]    x  = range(max_idx)    ax.fill_between(x, pi.lower[:max_idx], pi.upper[:max_idx],                     alpha=0.35, color=colors[name], label="95% PI")    ax.plot(x, pi.mean[:max_idx], "k--", lw=1.5, label="predicted")    ax.plot(x, y_test[:max_idx], "k.", ms=6, alpha=0.4, label="observed")    ax.set_title(        f"{name}  |  cov={res['coverage']:.3f}  width={res['width']:.1f}"    )    ax.legend(fontsize=8)plt.suptitle("Conformalized TabICL vs RidgeCV — diabetes dataset")plt.tight_layout()plt.show()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<?, ?B/s]TabICL      time=21.8sTabICL      RMSE=54.4  coverage=0.955  avg_width=226.1RidgeCV     time=0.0sRidgeCV     RMSE=53.9  coverage=0.955  avg_width=211.5

image-title-here

2 - R version

 %load_ext rpy2.ipython # in a Colab notebook, use this%R install.packages("reticulate")%%R  # in Colab/Jupyter with rpy2; remove this line for pure Rlibrary(reticulate)# pip install tabicl nnetsauce scikit-learn matplotlib numpysklearn_ds  <- import("sklearn.datasets")sklearn_ms  <- import("sklearn.model_selection")sklearn_m   <- import("sklearn.metrics")sklearn_lm  <- import("sklearn.linear_model")tabicl      <- import("tabicl")ns          <- import("nnetsauce")np          <- import("numpy")plt         <- import("matplotlib.pyplot")# ── data ───────────────────────────────────────────────────d       <- sklearn_ds$load_diabetes(return_X_y = TRUE)X <- d[[1]]; y <- d[[2]]sp      <- sklearn_ms$train_test_split(X, y,             test_size = 0.2, random_state = 42L)X_train <- sp[[1]]; X_test <- sp[[2]]y_train <- sp[[3]]; y_test <- sp[[4]]# ── helper: fit + evaluate ─────────────────────────────────eval_model <- function(reg, name) {  conf <- ns$PredictionInterval(reg, level = 95L)  conf$fit(X_train, y_train)  pi   <- conf$predict(X_test, return_pi = TRUE)  cov  <- np$mean((pi$lower <= y_test) * (pi$upper >= y_test))  wid  <- np$mean(pi$upper - pi$lower)  rmse <- sqrt(sklearn_m$mean_squared_error(y_test, pi$mean))  cat(sprintf("%-10s  RMSE=%.1f  coverage=%.3f  avg_width=%.1f\n",              name, rmse, cov, wid))  invisible(pi)}# ── run both models ────────────────────────────────────────pi_tabicl  <- eval_model(tabicl$TabICLRegressor(),  "TabICL")pi_ridge   <- eval_model(sklearn_lm$RidgeCV(),       "RidgeCV")# ── plot ───────────────────────────────────────────────────max_idx <- 50Lx_range <- np$array(0:(max_idx - 1))plot_pi <- function(pi, title, col) {  x_fill <- np$concatenate(list(x_range, x_range[max_idx:1]))  y_fill <- np$concatenate(list(    pi$upper[1:max_idx], pi$lower[max_idx:1]))  plt$fill(x_fill, y_fill, alpha=0.35, fc=col, ec="None", label="95% PI")  plt$plot(x_range, pi$mean[1:max_idx], "k--", lw=1.5, label="predicted")  plt$plot(x_range, y_test[1:max_idx], "k.", ms=6L, alpha=0.4, label="observed")  plt$title(title); plt$legend(fontsize=8L)}fig <- plt$figure(figsize=c(12, 4))plt$subplot(1L, 2L, 1L); plot_pi(pi_tabicl, "Conformalized TabICL", "orange")plt$subplot(1L, 2L, 2L); plot_pi(pi_ridge,  "Conformalized RidgeCV", "steelblue")plt$suptitle("Conformalized TabICL vs RidgeCV — diabetes dataset")plt$tight_layout()plt$show()    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.1RidgeCV     RMSE=53.9  coverage=0.955  avg_width=211.5

image-title-here

Probably a dataset that’s too easy 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.

To leave a comment for the author, please follow the link and comment on their blog: T. Moudiki's Webpage - R.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Continue reading: Conformalized TabICL: Prediction Intervals for a State-Of-The-Art Tabular Foundation Model in Python and R