scikit-learn compatible
Zone boosting you can read like a spreadsheet.
Fully transparent zone boosting — no decision trees, no gradient descent, no neural weights. Every number in a prediction traces back to a quantile, a group count, or a group average, and is inspectable directly from the fitted model.
pip install zoneboost
Quickstart
Regression
import pandas as pd
from zoneboost import ZoneBoostRegressor
X = pd.DataFrame({
"rooms": [3, 4, 2, 5, 3, 4, 2, 5],
"distance_km": [5.0, 2.0, 8.0, 1.0, 6.0, 3.0, 7.5, 1.5],
"neighborhood": ["a", "b", "a", "b", "a", "b", "a", "b"],
})
y = [300, 450, 220, 520, 310, 470, 230, 510]
model = ZoneBoostRegressor(
categorical_features=["neighborhood"], random_state=0
)
model.fit(X, y)
model.predict(X)
Classification
from zoneboost import ZoneBoostClassifier
y_class = [0, 1, 0, 1, 0, 1, 0, 1]
clf = ZoneBoostClassifier(
categorical_features=["neighborhood"], random_state=0
)
clf.fit(X, y_class)
clf.predict_proba(X) # (n_samples, n_classes), rows sum to 1
clf.predict(X) # binary and 3+ classes alike
What zoneboost gives you
One weak learner, two estimators
ZoneBoostRegressor and ZoneBoostClassifier (binary and
multiclass) share the exact same underlying weak learner — classification just
boosts in log-odds space instead of raw target space.
Adaptive zones, not fixed bins
Continuous predictors get variance-reducing split points re-derived fresh every round from that round's residual — the same criterion a regression tree split uses, without growing a tree.
Exact categorical handling
Declared or auto-detected categorical columns skip cut-point search entirely: every distinct value gets its own zone, with no assumption that nearby encoded values behave alike.
Missing values, handled honestly
NaN/None need no imputation — a missing value gets its own dedicated zone, so informative missingness is learned rather than silently imputed away.
Explainable by construction
explain(X) is an exact algebraic decomposition of what
predict already computes — not a post-hoc approximation — and its
terms sum exactly to the prediction.
Drop into scikit-learn
Works with Pipeline, GridSearchCV,
cross_val_score, and clone — no special-cased fitting
code required.
How it works, in brief
Each boosting round fits a weak learner made of two transparent pieces: a main effect (a 1D lookup from zone to average residual) for every predictor, and an interaction (a 2D lookup from joint zones to average residual) for every pair of predictors. Every zone's own mean is shrunk toward a hierarchical prior via empirical Bayes — so sparse zones lean toward their prior instead of overfitting a handful of rows. Read the full mechanics, including missing-value handling and how classification reuses the same learner, in How It Works.
Read the docs
Installation, the full parameter table, and how
explain() decomposes a prediction.