Bring-your-own-model¶
mli interprets a model you trained elsewhere through two entry points,
picked by whether mli has a native adapter for the model.
In short
- A supported tree ensemble or glass-box model goes to
fit_profiler: the full native surface. - Any other scorer with
predict_proba/predictgoes tomonitor_predictions(model=...). - With only the scores, pass
monitor_predictions(predictions=...). result.capabilities.backendsays which path ran:native,lite_modelorlite_predictions.
| You have | Use | Backend | What runs |
|---|---|---|---|
A model mli has an adapter for |
fit_profiler |
native |
native profiling plus requested optional stages; geometry and rule support depend on the family |
A model with predict_proba / predict but no adapter |
monitor_predictions |
lite_model |
surrogate / error tree / archetype-lite / metrics / drift / fairness |
| A tabular foundation model (an in-context learner) | monitor_predictions |
lite_model |
the same lite path: an in-context learner has no leaf structure and exact SHAP is intractable, so there is no native adapter |
Only predictions (no model) |
monitor_predictions |
lite_predictions |
the same lite path, with no model call |
from parleml_mli import (
ProfilingConfig,
RulesConfig,
fit_profiler,
monitor_predictions,
TaskType,
)
Supported models¶
The native path (fit_profiler) is taken only for models mli has an
adapter for. These fall into two tiers by how archetypes are built:
Leaf-space — archetypes from tree-leaf co-occurrence, plus IF-THEN rule extraction:
- CatBoost —
CatBoostClassifier,CatBoostRegressor,CatBoostRanker - LightGBM —
LGBMClassifier,LGBMRegressor,LGBMRanker,lightgbm.Booster - XGBoost —
XGBClassifier,XGBRegressor,XGBRanker,xgboost.Booster - scikit-learn ensembles —
RandomForest,ExtraTrees,GradientBoosting(Classifier/Regressor)
SHAP-space — archetypes built from SHAP values instead of per-sample leaves. Rule support is separate from archetype geometry: HGB and single-tree classifiers have tree-rule extractors; linear and additive models expose their native structure rather than the same tree-mining surface:
HistGradientBoostingClassifier/RegressorDecisionTreeClassifier/Regressor- EBM —
ExplainableBoostingClassifier/Regressor - RuleFit —
RuleFitClassifier/Regressor - scikit-learn linear / GLM —
LogisticRegression,LinearRegression,Ridge,Lasso,ElasticNet,SGDClassifier/SGDRegressor,PoissonRegressor,GammaRegressor,TweedieRegressor
Any other estimator that exposes predict_proba / predict (custom wrappers,
Pipelines, neural nets) runs the lite path via monitor_predictions;
passing only predictions runs the predictions-only path.
Supported tasks
Both entry points handle binary classification (the default,
task_type=TaskType.BINARY), multiclass (profiled as a primary-class
one-vs-rest slice with a per-class fan-out), and regression
(task_type=TaskType.REGRESSION). They are not classification-only.
Native — a recognised model¶
If your model is in the supported list above, call fit_profiler directly for
the full surface. With a binary y it profiles the positive class — the
model's classes_[1], the probability column every artifact scores — whatever
the labels are (0/1, 1/2, "no"/"yes", booleans); multiclass and
regression run their own fan-out / all-rows path:
result = fit_profiler(
X=X_train,
y=y_train,
model=my_lgbm,
X_test=X_test,
y_test=y_test,
config=ProfilingConfig(rules=RulesConfig()),
)
assert result.capabilities.backend == "native"
print(result.target_.positive_label, result.target_.source) # e.g. "yes" model_classes
positive_class= names the positive label explicitly — by string or numeric
form, so a stored form value such as "True" or "1.0" names the model's
True / 1.0; with a fitted model it must be model.classes_[1] (anything
else raises rather than silently explaining the other class). The resolved
answer is on result.target_, and the binary decision cut every
threshold-aware artifact — error analysis included — used on
result.threshold_ (result.decision_threshold is its value).
Labels need no preprocessing
Pass y in the model's own labels. Rows with a missing label are rejected
(drop or impute them first) instead of being assigned a class.
Lite — an unrecognised model¶
A model exposing predict_proba / predict that mli has no native adapter for
(a custom wrapper, a pipeline, a neural net) runs the lite path — a
decision-tree surrogate, error tree, archetype-lite clustering, holdout metrics,
drift, and fairness. monitor_predictions treats the model as an opaque scorer:
result = monitor_predictions(
X=X_train,
y=y_train,
model=my_custom_estimator, # has predict_proba, not in the adapter registry
X_test=X_test, y_test=y_test,
mode="all", # surrogate + error + archetype_lite + metrics
surrogate_engine="lgbm",
)
assert result.capabilities.backend == "lite_model"
Lite — predictions only¶
When you can't ship the model at all, hand over its scores:
result = monitor_predictions(
X=X_train,
y=y_train,
predictions=my_scores, # 1-D array of probabilities / values
predictions_test=my_test_scores,
X_test=X_test, y_test=y_test,
task_type=TaskType.BINARY,
)
assert result.capabilities.backend == "lite_predictions"
Inspect result.capabilities to see exactly which artifacts the chosen backend
was able to produce, then save and view as usual:
See the monitor_predictions reference,
the fit_profiler reference, and
Configuration for every tuning section.