> ## Documentation Index
> Fetch the complete documentation index at: https://docs.priorlabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Started with Predictive Distribution

> Learn how to extract predictive distributions with TabPFNRegressor

<div className="cookbook-meta">
  {/* cookbook-authors:start process_markdown.py */}

  <div className="cookbook-authors">
    <div className="cookbook-author-bar">
      <span className="cookbook-author-by">By</span>
      <span className="cookbook-author-list"><span className="cookbook-author-entry"><span className="cookbook-author-name">Prior Labs</span><span className="cookbook-author-links"><a href="https://www.linkedin.com/company/prior-labs" className="cookbook-author-icon-link" aria-label="LinkedIn" target="_blank" rel="noopener noreferrer"><svg className="cookbook-author-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 1 1 0-4.124 2.062 2.062 0 0 1 0 4.124zM7.119 20.452H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /></svg></a><a href="https://twitter.com/prior_labs" className="cookbook-author-icon-link" aria-label="X" target="_blank" rel="noopener noreferrer"><svg className="cookbook-author-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" /></svg></a></span></span></span>
    </div>
  </div>

  {/* cookbook-authors:end process_markdown.py */}

  {/* cookbook-colab:start process_markdown.py */}

  <div className="cookbook-colab">
    <a href="https://colab.research.google.com/github/PriorLabs/tabpfn-cookbook/blob/main/notebooks/predictive_distribution.ipynb" className="cookbook-colab-button" target="_blank" rel="noopener noreferrer">
      <svg className="cookbook-colab-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
        <path fill="#F9AB00" d="M16.9414 4.9757a7.033 7.033 0 0 0-4.9308 2.0646 7.033 7.033 0 0 0-.1232 9.8068l2.395-2.395a3.6455 3.6455 0 0 1 5.1497-5.1478l2.397-2.3989a7.033 7.033 0 0 0-4.8877-1.9297zM7.07 4.9855a7.033 7.033 0 0 0-4.8878 1.9316l2.3911 2.3911a3.6434 3.6434 0 0 1 5.0227.1271l1.7341-2.9737-.0997-.0802A7.033 7.033 0 0 0 7.07 4.9855zm15.0093 2.1721l-2.3892 2.3911a3.6455 3.6455 0 0 1-5.1497 5.1497l-2.4067 2.4068a7.0362 7.0362 0 0 0 9.9456-9.9476zM1.932 7.1674a7.033 7.033 0 0 0-.002 9.6816l2.397-2.397a3.6434 3.6434 0 0 1-.004-4.8916zm7.664 7.4235c-1.38 1.3816-3.5863 1.411-5.0168.1134l-2.397 2.395c2.4693 2.3328 6.263 2.5753 9.0072.5455l.1368-.1115z" />
      </svg>

      <span className="cookbook-colab-label">Open in Colab</span>
    </a>
  </div>

  {/* cookbook-colab:end process_markdown.py */}
</div>

*Going beyond point estimates to the full predictive distribution.*

A TabPFN regressor does not just output a single number per row. It predicts a full distribution over the target, which we can summarise as a mean, read off at chosen quantiles, or visualise directly. To generate point-estimates the `TabPFNRegressor` object takes the mean of the predicted distribution.

This notebook captures that full output, inspects its structure, and uses it to draw calibrated uncertainty bands around the model's predictions. We run the regressor through the hosted API client (`tabpfn-client`); the same code works with the local `tabpfn` package by changing the import.

## Setup

*Installing the TabPFN client and the plotting dependencies.*

```python theme={null}
!pip install tabpfn tabpfn-client matplotlib numpy scikit-learn
```

## Imports and Data

*Loading the diabetes dataset and the distribution plotting helper.*

The regressor comes from the hosted client (`tabpfn_client`). Alongside it we import `plot_regression_distribution` from the open-source `tabpfn` package, a helper that draws TabPFN's predicted distribution for a single sample.

```python theme={null}
import os

import matplotlib.pyplot as plt
import numpy as np
import torch

from google.colab import userdata
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split

from tabpfn_client import TabPFNRegressor
from tabpfn.visualisation import plot_regression_distribution


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=0
)
```

## Authenticating with a Token

*Setting `TABPFN_TOKEN` so the client can reach the API.*

```python theme={null}
from tabpfn_client import set_access_token
set_access_token(userdata.get('TABPFN_TOKEN'))
```

## Fit the Regressor

*A small ensemble keeps the full-distribution output light.*

Each estimator contributes its own predicted distribution, and the final output combines them. We use four here.

```python theme={null}
reg = TabPFNRegressor(n_estimators=4)
reg.fit(X_train, y_train)
```

```console theme={null}
TabPFNRegressor(client_options=ClientOptions(timeout=900.0,
                                             headers={'sentry-trace': 'd7d5e153e9284a1aaa644ffd3cae054d'}),
                n_estimators=4)
```

## Capturing the Full Output

*Requesting `output_type="full"` returns a dictionary, not an array.*

Instead of one prediction per row, the full output exposes every summary TabPFN computes, keyed by name.

```python theme={null}
preds = reg.predict(X_test, output_type="full")
preds.keys()  # preds are a dictionary
```

```console theme={null}
dict_keys(['mean', 'median', 'mode', 'quantiles', 'logits', 'borders', 'criterion'])
```

## Inspecting the Output

*The mean and the predicted quantiles, side by side.*

`mean` holds the point estimate per row. `quantiles` holds the predicted value at each default quantile, from the 10th to the 90th percentile.

```python theme={null}
preds["mean"]
```

```console theme={null}
array([262.00595093, 247.46105957, 157.95018005, 112.13021088,
       168.45626831, 260.21682739, 101.82640839, 206.1414032 ,
       144.20509338, 239.69104004, 170.84356689, 186.34484863,
       102.5146637 ,  92.51793671, 267.41168213,  81.6782608 ,
       149.95092773,  75.79134369, 103.53370667, 226.96896362,
       193.64593506, 150.20507812, 163.20532227, 135.34480286,
       210.42773438, 168.1986084 , 108.92704773,  82.55252075,
       187.76705933, 157.13589478, 179.16030884,  83.51014709,
       136.45083618, 163.94586182, 146.91384888, 196.48248291,
       171.73265076, 183.18984985, 112.78544617, 208.20550537,
        90.22658539, 161.11459351, 141.42713928, 189.02024841,
       172.44181824,  82.47047424, 131.43049622, 123.00216675,
       109.7409668 , 240.20011902, 157.71350098,  76.81249237,
       135.29710388, 160.92269897, 243.48034668, 174.11050415,
       193.51113892, 108.92158508, 128.37950134, 182.95803833,
       227.03120422, 156.3691864 , 145.6862793 , 103.51408386,
       258.57275391, 154.26098633,  87.26889038, 238.52149963,
       211.35943604,  78.00679779,  79.92175293, 134.60266113,
        98.80968475, 125.20201111, 109.49157715, 179.54232788,
        97.65361023, 218.19348145, 247.75469971, 197.04919434,
       138.65386963, 222.8142395 ,  69.69721985, 221.32472229,
        85.98129272,  92.65812683, 133.4095459 , 194.07327271,
       128.49983215])
```

```python theme={null}
# default quantiles are: [0.1, 0.2, ..., 0.8, 0.9]
# the shape of the quantiles array is quantiles x rows
preds["quantiles"].shape
```

```console theme={null}
(9, 89)
```

## Visualising a Single Prediction

*Plotting the full predicted distribution for one row.*

`plot_regression_distribution` shows the shape of the distribution TabPFN assigns to a single sample, making its confidence, or lack of it, visible at a glance.

```python theme={null}
preds["logits"] = torch.as_tensor(np.nan_to_num(np.asarray(preds["logits"]), nan=-np.inf))
plot_regression_distribution(preds, sample_idx=0)
```

![Predicted distribution for sample 0](https://raw.githubusercontent.com/PriorLabs/tabpfn-cookbook/main/visuals/predictive_distribution/sample-prediction-0.png)

```python theme={null}
plot_regression_distribution(preds, sample_idx=10)
```

![Predicted distribution for sample 10](https://raw.githubusercontent.com/PriorLabs/tabpfn-cookbook/main/visuals/predictive_distribution/sample-prediction-10.png)

## Uncertainty Across the Input Range

*Building an uncertainty band on a controlled synthetic dataset.*

To see how the input affects the uncertainty in the prediction, we generate data where the noise grows with the input.

### Generate the data

*A linear trend with noise that widens as X grows.*

```python theme={null}
n_train = 100
n_test = 50
rng = np.random.default_rng(0)
X_train = rng.uniform(0.0, 10.0, size=n_train)
y_train = 2 * X_train + rng.uniform(size=n_train) * X_train
X_train = X_train.reshape(-1,1)
X_test = np.linspace(10.0, 20.0, n_test, dtype=np.float32).reshape(-1, 1)
```

### Generate predictions

*Mean predictions, plus the full distribution for the quantiles.*

```python theme={null}
reg = TabPFNRegressor()
reg.fit(X_train, y_train)
preds = reg.predict(X_test) # mean point-estimates
full_preds = reg.predict(X_test, output_type="full")
```

### Plot the uncertainty band

*Shading between the 10th and 90th predicted quantiles.*

The band widens where the model is less certain, including the extrapolation region past the training data.

```python theme={null}
# @title
q10 = full_preds["quantiles"][0]
q90 = full_preds["quantiles"][-1]

plt.scatter(X_train, y_train, label="Train Data")
plt.fill_between(X_test.flatten(), q10, q90, alpha=0.2, color="C1", label="Uncertainty Band")
plt.plot(X_test, preds, color="C1", label=" Mean Prediction")

plt.xlabel("X")
plt.ylabel("y")
plt.legend()
plt.show()
```

![Uncertainty band plot](https://raw.githubusercontent.com/PriorLabs/tabpfn-cookbook/main/visuals/predictive_distribution/uncertainty-band.png)
