FinalModel API¶
FinalModel¶
h2ml.pipeline.final_model.FinalModel
dataclass
¶
Fitted model ready for inference on new data.
Attributes:
| Name | Type | Description |
|---|---|---|
estimator |
Any
|
Sklearn-compatible estimator fitted on the full training set. |
feature_names |
list[str]
|
Ordered list of features the model was trained on. |
task_type |
TaskType
|
TaskType.CLASSIFICATION or TaskType.REGRESSION. |
requires_scaling |
bool
|
Whether StandardScaler was applied before fitting. |
scaler |
Optional[Any]
|
Fitted StandardScaler (None when requires_scaling is False). |
best_model_name |
Optional[str]
|
Name of the model as registered in the h2ml registry. |
best_params |
Optional[dict]
|
Hyperparameters used for the final fit (None = defaults). |
conformal |
Optional[ConformalCalibration]
|
Global conformal calibrator built from out-of-fold residuals; powers predict_interval / predict_set. None when no calibration was available (e.g. partial pipeline run). |
y_transform |
Optional[str]
|
Name of the y-transform applied during training (e.g. "log"), or None. predict() returns the transformed space and the caller inverts it; predict_interval() bounds are already in the original scale. See preprocessing/transforms.py. |
local_conformal |
Optional[LocalConformalCalibration]
|
Space-time block-local conformal calibrator. Used instead of
|
variogram |
Optional[Any]
|
Fitted VariogramResult describing the spatial autocorrelation range of the model's residuals (diagnostic only; not used in prediction). None when coords were absent or fitting failed. |
Example
final = result.build_final_model() final.predict(X_new_df) final.save("models/final_model.pkl") final = FinalModel.load("models/final_model.pkl")
load(path)
classmethod
¶
Reload a FinalModel saved with :meth:save.
WARNING: only load files from trusted sources — joblib uses pickle, which executes arbitrary code on deserialisation.
predict(X)
¶
Predict on new data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
DataFrame | ndarray
|
DataFrame (columns are aligned by name) or ndarray (columns must match feature_names order). |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
1-D array of predictions. |
predict_interval(X, alpha=0.1, coords=None, times=None)
¶
Conformal prediction interval for each sample (regression only).
The interval is centred on the point estimate and has width 2q, where q is the conformal threshold calibrated from out-of-fold residuals. Coverage is guaranteed to be ≥ 1-alpha in expectation.
When coords and/or times are provided and the model has a LocalConformalCalibration, q varies per sample based on the nearest spatial block's residual distribution, giving wider intervals in high-error regions and narrower ones where the model is well calibrated.
Note: bounds are always in the original y scale. q is calibrated on original-scale OOF residuals, so when the pipeline used a y-transform the point estimate is inverted internally before the interval is applied — do not apply the inverse transform to the returned bounds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
DataFrame | ndarray
|
Input features (DataFrame or ndarray). |
required |
alpha
|
float
|
Miscoverage level. Default 0.10 → 90% prediction intervals. |
0.1
|
coords
|
Optional[ndarray]
|
(n_samples, 2) spatial coordinates. Enables local calibration. |
None
|
times
|
Optional[ndarray]
|
(n_samples,) datetime64[D] or YYYY-MM-DD strings. Enables temporal calibration. |
None
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
(lower, upper) as a pair of 1-D arrays. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the model is not a regression model, or if no conformal calibration is attached (rebuild via result.build_final_model() after a full pipeline run). |
predict_proba(X)
¶
Predict class probabilities (classification only).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
DataFrame | ndarray
|
DataFrame (columns aligned by name) or ndarray (columns must match feature_names order). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Binary |
ndarray
|
1-D array of positive-class probabilities. |
Multiclass |
ndarray
|
2-D array of shape (n_samples, n_classes). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the model was trained for a regression task. |
predict_set(X, alpha=0.1, coords=None, times=None)
¶
Conformal prediction set for each sample (classification only).
Each prediction set contains the classes that are plausible given the coverage guarantee. A singleton set means the model is confident; a larger set means it is uncertain.
Coverage guarantee: the true label is in the prediction set with probability ≥ 1-alpha.
Nonconformity score per class k: 1 - p_k. Class k is included in the set when its score does not exceed the calibrated threshold q.
When coords and/or times are provided and the model has a LocalConformalCalibration, q varies per sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
DataFrame | ndarray
|
Input features (DataFrame or ndarray). |
required |
alpha
|
float
|
Miscoverage level. Default 0.10 → 90% coverage sets. |
0.1
|
coords
|
Optional[ndarray]
|
(n_samples, 2) spatial coordinates. Enables local calibration. |
None
|
times
|
Optional[ndarray]
|
(n_samples,) datetime64[D] or YYYY-MM-DD strings. |
None
|
Returns:
| Type | Description |
|---|---|
list[ndarray]
|
List of arrays of class labels, one per sample. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the model is not a classification model, or if no conformal calibration is attached (rebuild via result.build_final_model() after a full pipeline run). |
save(path)
¶
Persist to path (single .pkl file via joblib). Parent directory is created if needed.
ConformalCalibration¶
h2ml.evaluation.conformal.ConformalCalibration
dataclass
¶
Nonconformity scores from out-of-fold CV predictions, used to construct finite-sample coverage-guaranteed prediction intervals (regression) or prediction sets (classification).
Scores are pre-sorted ascending. The threshold at level 1-alpha is the ceil((1-alpha)(n+1))/n quantile, which guarantees marginal coverage ≥ 1-alpha.
Attributes:
| Name | Type | Description |
|---|---|---|
scores |
ndarray
|
Sorted nonconformity scores from calibration folds. |
n |
int
|
Number of calibration samples (len(scores)). |
task_type |
TaskType
|
TaskType of the calibrated model. |
threshold(alpha)
¶
Return the nonconformity threshold that gives ≥ 1-alpha coverage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
alpha
|
float
|
Miscoverage level (e.g. 0.10 for 90% coverage). |
required |
LocalConformalCalibration¶
h2ml.evaluation.conformal.LocalConformalCalibration
dataclass
¶
Block-local conformal calibration in combined space-time.
Threshold lookup uses three levels of fallback
- Compound cell (spatial block × time bin) — finest granularity.
- Spatial block (all time bins pooled) — if compound cell has < min_compound_n samples.
- Global fallback — if spatial block has < min_block_n samples.
At inference each query point is assigned to the spatial block of its nearest OOF training sample via k-NN in a jointly normalised context space. The time bin is derived from the query point's own date (not the nearest OOF sample's date), so the seasonal threshold reflects when the prediction is being made.
Nearest-OOF-sample lookup (not centroid) is used so that non-convex or elongated AHC clusters (SPCVSplitter) are handled correctly.
Attributes:
| Name | Type | Description |
|---|---|---|
scores_by_block |
list[ndarray]
|
Sorted nonconformity scores per spatial block. Index i matches oof_block_indices == i. |
oof_context_scaled |
ndarray
|
(n_oof, D) OOF context already normalised by context_mean/std. Used as the k-NN index at inference. |
oof_block_indices |
ndarray
|
(n_oof,) int index into scores_by_block per OOF sample. |
context_mean |
ndarray
|
(D,) scaler mean — applied to normalise query context. |
context_std |
ndarray
|
(D,) scaler std. |
fallback_scores |
ndarray
|
Global sorted scores — level-3 fallback. |
metric |
str
|
"euclidean" or "haversine". Haversine only applies when has_coords=True, has_times=False, and D==2. |
min_block_n |
int
|
Minimum OOF samples a spatial block needs to use its own scores (level 2). Smaller blocks fall to global (level 3). |
has_coords |
bool
|
Whether spatial coordinates were included at calibration time. Coords passed at inference are silently ignored if False. |
has_times |
bool
|
Whether temporal context was included at calibration time. Times passed at inference are silently ignored if False. |
compound_scores |
Optional[dict]
|
{(block_idx, time_bin): sorted np.ndarray} — level-1 lookup. None when times were absent at calibration. |
time_bin_resolution |
Optional[str]
|
"month" (bins 1–12) or "season" (0=DJF…3=SON). None when times were absent at calibration. |
min_compound_n |
int
|
Minimum OOF samples a compound cell needs to be used (level 1). Lower than min_block_n because compound cells are smaller by construction (n_blocks × n_bins cells share the same total count). |
summary(alpha=0.1, max_blocks=None)
¶
Per-block (and per-time-bin) calibration thresholds at the given alpha.
Returns one 'spatial' row per block (all time bins pooled) plus, when compound cells exist, one 'compound' row per populated (block, time_bin) cell. The bin labels follow self.time_bin_resolution (season → DJF/MAM/JJA/SON, month → 1–12), so no resolution argument is needed.
Columns
block: Spatial block index (into scores_by_block).
level: "spatial" or "compound".
time_bin: Integer time bin for compound rows;
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
alpha
|
float
|
Miscoverage level (0.10 → 90% coverage). |
0.1
|
max_blocks
|
Optional[int]
|
Cap the number of blocks reported (None = all). |
None
|
threshold(alpha, coords=None, times=None)
¶
Return per-sample nonconformity thresholds.
Only the context dimensions present at calibration time are used — extra dimensions silently dropped so scaler shapes always match (e.g. times passed to a model built without store.times are ignored).
When times is provided and time_bin_resolution is set, each sample's threshold is looked up from the compound (spatial block × time bin) cell first, falling back through spatial block and global as needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
alpha
|
float
|
Miscoverage level (e.g. 0.10 → 90% coverage). |
required |
coords
|
Optional[ndarray]
|
(n_samples, 2) spatial coordinates. Degrees when metric="haversine". |
None
|
times
|
Optional[ndarray]
|
(n_samples,) datetime64[D] or YYYY-MM-DD strings. |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
(n_samples,) float array of per-sample thresholds. |
DeltaFinalModel¶
h2ml.pipeline.final_model.DeltaFinalModel
dataclass
¶
Two-component delta model combining a presence/absence classifier and a count/abundance regressor.
Prediction: P(present) × E(count | present) Conformal interval: [max(0, delta − q), delta + q] where q is calibrated from combined out-of-fold residuals on the full delta output.
The regressor's y-transform (if any) is inverted inside predict() so the output is always in the original count scale. This differs from FinalModel, where the caller handles inversion — the multiplication P × count requires the original scale.
Attributes:
| Name | Type | Description |
|---|---|---|
clf |
FinalModel
|
Presence/absence classifier — supplies P(present). |
reg |
FinalModel
|
Count/abundance regressor — supplies E(count | present). |
conformal |
Optional[ConformalCalibration]
|
Conformal calibrator over the combined delta output (not the components); powers predict_interval. None when no calibration was built. |
local_conformal |
Optional[LocalConformalCalibration]
|
Space-time block-local calibrator used when coords/times are passed to predict_interval, giving per-sample thresholds. None for non-spatial runs. |
variogram |
Optional[Any]
|
Fitted VariogramResult for the delta residuals (diagnostic only; imported lazily). None when unavailable. |
Example
positive_idx = np.where(y_all > 0)[0] delta = build_delta_final_model(clf_result, reg_result, X_all, y_all, positive_idx) delta.save("models/sparrow_delta-model") delta = DeltaFinalModel.load("models/sparrow_delta-model") lower, upper = delta.predict_interval(X_new, alpha=0.10)
load(path)
classmethod
¶
Reload a DeltaFinalModel saved with :meth:save.
WARNING: only load files from trusted sources — joblib uses pickle, which executes arbitrary code on deserialisation.
predict(X)
¶
Delta prediction: P(present) × E(count | present).
The regressor's y-transform is inverted here so the result is in the original count scale. Pass a DataFrame to let each sub-model select its own features by name; pass an ndarray only when both models share the same feature set and column order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
'pd.DataFrame | np.ndarray'
|
Input features (DataFrame preferred; ndarray only when clf and reg share the same feature set and column order). |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
1-D array of expected counts in the original scale. |
predict_interval(X, alpha=0.1, coords=None, times=None)
¶
Conformal prediction interval for each sample (count scale).
Coverage is guaranteed for the full delta output, not each component separately. The lower bound is clipped at zero (counts are non-negative).
When coords and/or times are provided and the model has a LocalConformalCalibration, q varies per sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
'pd.DataFrame | np.ndarray'
|
Input features. |
required |
alpha
|
float
|
Miscoverage level. Default 0.10 → 90% coverage. |
0.1
|
coords
|
Optional[ndarray]
|
(n_samples, 2) spatial coordinates. Enables local calibration. |
None
|
times
|
Optional[ndarray]
|
(n_samples,) datetime64[D] or YYYY-MM-DD strings. |
None
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
(lower, upper) pair of 1-D arrays. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no conformal calibration is attached (rebuild via build_delta_final_model() with positive_indices provided). |
save(path)
¶
Persist to path (directory). Creates the directory if needed. Saves clf.pkl, reg.pkl, conformal.pkl, local_conformal.pkl, variogram.pkl. Reload with DeltaFinalModel.load(path).
build_final_model¶
h2ml.pipeline.final_model.build_final_model(result)
¶
Fit the overall best model on the full training dataset and return a FinalModel ready for inference.
Picks the correct feature store (reduced or full) via best_feature_stage, applies StandardScaler when the model requires it, and fits with best_params when step 4 ran.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
result
|
'PipelineResult'
|
PipelineResult from H2MLPipeline.run(). |
required |
Returns:
| Type | Description |
|---|---|
FinalModel
|
FinalModel instance. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the result is incomplete (no step-1 CV result, no best_model_name, or the chosen feature store is missing), or if best_model_name is no longer present in the registry (e.g. the model was removed after the pipeline ran). |