mapi_sklearn¶
This package is for scikit-learn and xgboost models. You write estimator(). The package gives
stacking, safe persistence and uncertainty.
Base classes¶
SklearnModel: scikit-learn and xgboost estimators on labelled data (plan §5).
A plugin author implements only :meth:SklearnModel.estimator, returning an allow-listed
estimator (a choice from :data:~mapi_sklearn.estimators.ESTIMATORS, a
{kind, params} mapping, or an instance of an allow-listed class). The platform:
- stacks the
rowsdims of the model-stage dataset into samples and builds the design matrix from the selected variables and coordinate features (:mod:mapi_sklearn.design), dropping incomplete rows through the SDK row mask; - fits one or more estimators for the plugin's uncertainty kind;
- persists them with skops or xgboost JSON (never pickle);
- at score time rebuilds the same columns, handles unseen levels
(:mod:
mapi_sklearn.levels), predicts and unstacks back to labelled arrays in the plugin's representation:
================= ===================== ==========================================
base class representation predictions group
================= ===================== ==========================================
SklearnModel point y_hat(*rows) (+ contributions)
SklearnQuantile quantiles y_hat(quantile, *rows)
SklearnBootstrap draws y_hat(chain, draw, *rows)
SklearnConformal interval y_hat(bound=[lower, upper, point], *rows)
SklearnClassifier point y_hat(*rows) = P(target == positive)
SklearnMulticlass point y_hat(*rows, class) = P(target == class)
================= ===================== ==========================================
Forecasting is direct only: future features must be supplied (or produced by the
pipeline from coordinates); forecast_strategy: recursive raises
RECURSIVE_UNSUPPORTED.
SklearnModel
¶
Bases: CustomModel[SettingsT]
Point-prediction plugin base class (representation point).
Subclass it (or :class:SklearnQuantileModel, :class:SklearnBootstrapModel,
:class:SklearnConformalModel, :class:SklearnClassifier), set id and
version, and optionally override :meth:estimator.
estimator
¶
The estimator to fit: an allow-listed choice, {kind, params} or instance.
The default returns settings.estimator.
SklearnQuantileModel
¶
Bases: SklearnModel[SettingsT]
Conditional quantiles (representation quantiles).
xgboost fits one native multi-quantile model (reg:quantileerror); quantile-capable
sklearn estimators (QuantileRegressor, GradientBoostingRegressor,
HistGradientBoostingRegressor) fit one model per level.
SklearnBootstrapModel
¶
Bases: SklearnModel[SettingsT]
Bootstrap ensemble (representation draws: chain=1, one draw per replicate).
expected outputs are the replicate predictions (uncertainty of the fitted mean);
predictive outputs add an out-of-bag residual drawn per cell, approximating the
predictive distribution. Draws are joint across cells, so every aggregation is valid.
SklearnConformalModel
¶
Bases: SklearnModel[SettingsT]
Split-conformal prediction intervals (representation interval, never draws).
y_hat(bound=[lower, upper, point], ...) with attribute alpha: each interval
covers the observed value with probability at least 1 - alpha for data exchangeable
with the calibration rows. Intervals have per-cell coverage only and cannot be summed.
SklearnClassifier
¶
capabilities_for
¶
capabilities_for(kind: UncertaintyKind) -> Capabilities
Capabilities of a plugin with uncertainty kind.
sklearn_schema_template
¶
The model input schema template shared by the sklearn plugins.
Every row dim is declared categorical with policy new_levels (strategy from
settings.new_levels) except time_dim, which time_kind declares as an
extending time/integer/index dim (time_kind: none: no such dim). The
effective policy is the tighter of this and the data's own policy.
Settings¶
Settings of the scikit-learn / xgboost model plugins.
A spec's model.settings for sklearn.* plugins looks like::
estimator: {kind: xgboost.XGBRegressor, params: {n_estimators: 600, max_depth: 6}}
rows: [store, sku, time] # dims stacked into samples
time_dim: time # the row dim that extends at forecast time
columns: {roles: [covariate]} # which variables become feature columns
coord_features: {store: category, sku: category}
uncertainty: {kind: quantile, quantiles: [0.05, 0.5, 0.95]}
forecast_strategy: direct
retransform: median
The uncertainty kind fixes the output representation, so each kind is its own plugin
(sklearn.tabular_quantiles accepts only kind: quantile and so on).
SklearnSettings
¶
PointSettings
¶
Bases: SklearnSettings
sklearn.tabular_regressor: point predictions with optional contributions.
contributions: auto (exact for linear estimators, none otherwise), exact
(linear estimators only), zeroing (counterfactual zeroing for any estimator) or
none.
QuantileSettings
¶
BootstrapSettings
¶
ConformalSettings
¶
ClassifierSettings
¶
Bases: SklearnSettings
sklearn.tabular_classifier: binary class probabilities (y_hat = P(positive)).
positive_class defaults to the larger of the two target labels.
Estimator registry¶
The allow-listed estimator registry.
Plugins never import arbitrary classes. An estimator is chosen by kind from
:data:ESTIMATORS, and its hyper-parameters are validated by that kind's Pydantic params
model (extra="forbid", bounded values). The platform then builds the estimator with
every parameter passed explicitly, so behaviour does not drift when a library changes a
default. Parameters the platform owns (seeds, threads, categorical handling and the
loss/objective an uncertainty kind needs) are not part of the params models.
In a spec::
estimator: {kind: xgboost.XGBRegressor, params: {n_estimators: 600, max_depth: 6}}
LightGBM and CatBoost (v0.14) are an optional extra (mapi-sklearn[gbm]) and are imported
only when an estimator of theirs is built or loaded; without them those kinds raise
SETTINGS_INVALID.
ESTIMATORS
¶
ESTIMATORS: dict[str, EstimatorEntry] = {
e.kind: e
for e in (
EstimatorEntry(
"sklearn.LinearRegression",
"sklearn.linear_model",
"LinearRegression",
LinearRegressionParams,
LinearRegressionChoice,
"regression",
linear=True,
seed_param=None,
description="Ordinary least squares.",
),
EstimatorEntry(
"sklearn.Ridge",
"sklearn.linear_model",
"Ridge",
RidgeParams,
RidgeChoice,
"regression",
linear=True,
description="Least squares with an L2 penalty.",
),
EstimatorEntry(
"sklearn.Lasso",
"sklearn.linear_model",
"Lasso",
LassoParams,
LassoChoice,
"regression",
linear=True,
description="Least squares with an L1 penalty.",
),
EstimatorEntry(
"sklearn.ElasticNet",
"sklearn.linear_model",
"ElasticNet",
ElasticNetParams,
ElasticNetChoice,
"regression",
linear=True,
description="Least squares with a mixed L1/L2 penalty.",
),
EstimatorEntry(
"sklearn.QuantileRegressor",
"sklearn.linear_model",
"QuantileRegressor",
QuantileRegressorParams,
QuantileRegressorChoice,
"regression",
linear=True,
quantile="per_level",
quantile_setter=_set("quantile"),
seed_param=None,
description="Linear quantile regression (pinball loss, L1 penalty).",
),
EstimatorEntry(
"sklearn.LogisticRegression",
"sklearn.linear_model",
"LogisticRegression",
LogisticRegressionParams,
LogisticRegressionChoice,
"classification",
linear=True,
description="Binary logistic regression.",
),
EstimatorEntry(
"sklearn.RandomForestRegressor",
"sklearn.ensemble",
"RandomForestRegressor",
RandomForestRegressorParams,
RandomForestRegressorChoice,
"regression",
n_jobs_param="n_jobs",
trusted=_TREE,
description="Random forest of regression trees.",
),
EstimatorEntry(
"sklearn.RandomForestClassifier",
"sklearn.ensemble",
"RandomForestClassifier",
RandomForestClassifierParams,
RandomForestClassifierChoice,
"classification",
n_jobs_param="n_jobs",
trusted=_TREE,
description="Random forest of classification trees.",
),
EstimatorEntry(
"sklearn.GradientBoostingRegressor",
"sklearn.ensemble",
"GradientBoostingRegressor",
GradientBoostingRegressorParams,
GradientBoostingRegressorChoice,
"regression",
quantile="per_level",
quantile_setter=_set("alpha"),
loss_param="loss",
quantile_loss="quantile",
trusted=_TREE,
description="Gradient-boosted regression trees.",
),
EstimatorEntry(
"sklearn.HistGradientBoostingRegressor",
"sklearn.ensemble",
"HistGradientBoostingRegressor",
HistGradientBoostingRegressorParams,
HistGradientBoostingRegressorChoice,
"regression",
native_nan=True,
native_categorical="sklearn_hist",
quantile="per_level",
quantile_setter=_set("quantile"),
loss_param="loss",
quantile_loss="quantile",
trusted=_HIST,
description="Histogram gradient boosting (native missing values and categories).",
),
EstimatorEntry(
"xgboost.XGBRegressor",
"xgboost",
"XGBRegressor",
XGBRegressorParams,
XGBRegressorChoice,
"regression",
persistence="xgboost",
native_nan=True,
native_categorical="xgboost",
quantile="native_multi",
loss_param="objective",
quantile_loss="reg:quantileerror",
n_jobs_param="n_jobs",
description="XGBoost gradient-boosted trees (native missing values, categories and multi-quantile objective).",
),
EstimatorEntry(
"xgboost.XGBClassifier",
"xgboost",
"XGBClassifier",
XGBClassifierParams,
XGBClassifierChoice,
"classification",
persistence="xgboost",
native_nan=True,
native_categorical="xgboost",
n_jobs_param="n_jobs",
description="XGBoost gradient-boosted trees for binary or multiclass classification.",
),
EstimatorEntry(
"sklearn.HistGradientBoostingClassifier",
"sklearn.ensemble",
"HistGradientBoostingClassifier",
HistGradientBoostingClassifierParams,
HistGradientBoostingClassifierChoice,
"classification",
native_nan=True,
native_categorical="sklearn_hist",
trusted=_HIST,
description="Histogram gradient boosting for classification (native missing values and categories).",
),
EstimatorEntry(
"lightgbm.LGBMClassifier",
"lightgbm",
"LGBMClassifier",
LGBMClassifierParams,
LGBMClassifierChoice,
"classification",
persistence="lightgbm",
native_nan=True,
n_jobs_param="n_jobs",
fixed={"verbosity": -1},
description="LightGBM gradient-boosted trees (needs mapi-sklearn[gbm]).",
),
EstimatorEntry(
"catboost.CatBoostClassifier",
"catboost",
"CatBoostClassifier",
CatBoostClassifierParams,
CatBoostClassifierChoice,
"classification",
persistence="catboost",
native_nan=True,
seed_param="random_seed",
n_jobs_param="thread_count",
fixed={
"verbose": False,
"allow_writing_files": False,
},
description="CatBoost oblivious gradient-boosted trees (needs mapi-sklearn[gbm]).",
),
)
}
Every estimator kind a plugin may use, keyed by kind.
EstimatorChoice
¶
EstimatorChoice = Annotated[
LinearRegressionChoice
| RidgeChoice
| LassoChoice
| ElasticNetChoice
| QuantileRegressorChoice
| LogisticRegressionChoice
| RandomForestRegressorChoice
| RandomForestClassifierChoice
| GradientBoostingRegressorChoice
| HistGradientBoostingRegressorChoice
| XGBRegressorChoice
| XGBClassifierChoice
| HistGradientBoostingClassifierChoice
| LGBMClassifierChoice
| CatBoostClassifierChoice,
Field(discriminator="kind"),
]
An allow-listed estimator and its validated hyper-parameters.
EstimatorEntry
¶
EstimatorEntry(
kind: str,
module: str,
name: str,
params: type[Params],
choice: type[_Choice],
task: Task,
persistence: Literal[
"skops", "xgboost", "lightgbm", "catboost"
] = "skops",
linear: bool = False,
native_nan: bool = False,
native_categorical: Literal["xgboost", "sklearn_hist"]
| None = None,
quantile: QuantileMode | None = None,
quantile_setter: Callable[
[dict[str, Any], float], dict[str, Any]
]
| None = None,
loss_param: str | None = None,
quantile_loss: str | None = None,
seed_param: str | None = "random_state",
n_jobs_param: str | None = None,
trusted: frozenset[str] = frozenset(),
fixed: Mapping[str, Any] = dict(),
description: str = "",
)
Static facts about one allow-listed estimator.
linear estimators expose coef_/intercept_ (exact additive contributions);
native_nan ones accept missing feature values; native_categorical says how
integer-coded categorical columns are declared (xgboost feature types or the
categorical_features of sklearn's histogram boosting). quantile says how a
quantile model is built: one native multi-quantile model, or one model per level with
quantile_setter. loss_param/loss_default/quantile_loss name the loss or
objective the quantile mode manages. trusted lists the extra types skops may load.
fixed holds platform-owned constructor arguments (quiet logging, no files written).
load_class
¶
The estimator class; SETTINGS_INVALID when its optional library is missing.
get_entry
¶
get_entry(kind: str) -> EstimatorEntry
The registry entry for kind; SETTINGS_INVALID listing the kinds otherwise.
Built-in plugins¶
The built-in sklearn.* model plugins (registered through the mapi.models entry point).
Each plugin takes its estimator from settings.estimator; the uncertainty kind, and so
the output representation, is fixed by the plugin:
========================== ============= ==================================================
plugin representation uncertainty
========================== ============= ==================================================
sklearn.tabular_regressor point none (contributions, retransform)
sklearn.tabular_quantiles quantiles {kind: quantile, quantiles: [...]}
sklearn.tabular_bootstrap draws {kind: bootstrap, n: 50, by: store}
sklearn.tabular_conformal interval {kind: conformal, alpha: 0.1, calibration: 0.2}
sklearn.tabular_classifier point binary class probability
sklearn.multiclass_classifier point one probability per class (y_hat(..., class))
========================== ============= ==================================================