## kernels.PredictiveDistribution


Sampled predictive distribution over a set of targets.


Usage

``` python
kernels.PredictiveDistribution(
    samples,
    targets,
    units=None,
)
```


samples: (n_draws, n_targets) array of predictive samples. targets: one row of metadata per target (e.g. origin_period, premium, label). Index is positional. units: carried from the source triangle, purely informational.


## Parameter Attributes


`samples: np.ndarray`  

`targets: pd.DataFrame`  

`units: str | None = None`  


## Methods

| Name | Description |
|----|----|
| [cdf()](#cdf) | Empirical predictive CDF at the observed outcomes, in \[0, 1\]. |
| [from_arrow()](#from_arrow) | Decode draws written by [to_arrow()](kernels.to_arrow.md#ibnr.kernels.to_arrow), refusing any other kind. |
| [summary()](#summary) | Meyers-style output table: one row per target with posterior mean, |
| [to_arrow()](#to_arrow) | Arrow IPC bytes carrying every draw, bit for bit. See `kernels.codec`. |
| [to_summary()](#to_summary) | JSON-safe digest - moments, quantiles, target metadata, no draws. |
| [with_total()](#with_total) | Append a target that is the row-wise sum of all current targets. |

------------------------------------------------------------------------


#### cdf()


Empirical predictive CDF at the observed outcomes, in \[0, 1\].


Usage

``` python
cdf(observed)
```


This is the PIT value / "outcome percentile" of Meyers' validation tables (he reports it x100). One value per target.

A target whose outcome is missing, or whose draws hold any missing value, gets NaN rather than a number. Every comparison against NaN is False, so the plain fraction of draws at or below the outcome reads a missing outcome as exactly 0.0, the lowest percentile there is, and counts every missing draw as lying above the outcome. NaN is the designed value for an outcome that has not emerged yet (`contract.realized_values`, and the mack entry's total for a partially unemerged cohort).

The mask is per target, so a neighbouring target whose values are all present keeps its percentile. Infinite outcomes and infinite draws are NOT masked: the empirical CDF is well defined there, and an outcome below every draw is a real verdict of 0.0 that has to stay distinguishable from a missing one. The CHANGELOG entry has the rest of the story, including the one published figure this moved.


------------------------------------------------------------------------


#### from_arrow()


Decode draws written by [to_arrow()](kernels.to_arrow.md#ibnr.kernels.to_arrow), refusing any other kind.


Usage

``` python
from_arrow(data)
```


`expect` is what makes the classmethod mean anything: the dispatcher routes on the payload's own kind, so without it this returns a Triangle when handed triangle bytes.


------------------------------------------------------------------------


#### summary()


Meyers-style output table: one row per target with posterior mean,


Usage

``` python
summary(observed=None)
```


SE, CV, and (when outcomes are given) the outcome and its percentile.


------------------------------------------------------------------------


#### to_arrow()


Arrow IPC bytes carrying every draw, bit for bit. See `kernels.codec`.


Usage

``` python
to_arrow(*, compression=None)
```


------------------------------------------------------------------------


#### to_summary()


JSON-safe digest - moments, quantiles, target metadata, no draws.


Usage

``` python
to_summary(*, quantiles=None)
```


Two orders of magnitude smaller than the draws and deliberately one-way: there is no `from_summary`, because a summary is not a distribution (CLAUDE.md decision 4).


------------------------------------------------------------------------


#### with_total()


Append a target that is the row-wise sum of all current targets.


Usage

``` python
with_total(label="total", label_column="label")
```
