Skip to content

ChimeraBoostRegressor

Gradient boosted oblivious trees for regression. See the User Guide: regression basics, quantile regression, and custom objectives.

Bases: RegressorMixin, BaseEstimator

Gradient boosted oblivious trees for regression.

A scikit-learn compatible regressor supporting squared-error, absolute-error, and quantile losses, native categorical features, sample weights, bagging, and exact SHAP attributions.

Read more in the User Guide.

Parameters:

Name Type Description Default
n_estimators int

Maximum number of boosting rounds (trees). With early_stopping on, this is an upper bound and the best round is selected automatically.

2000
learning_rate float or None

Shrinkage applied to each tree. When early stopping is active, None resolves to 0.1 on data of about 15,000 training rows or more and fades to 0.07 at 5,000 or fewer; see adaptive_learning_rate.

None
depth int or None

Depth of each oblivious tree; a depth-d tree makes d splits. None resolves to 6 for squared-error/absolute-error losses, and to 4 for loss="Quantile" -- estimating an extreme conditional quantile from a leaf needs more samples per leaf than estimating a mean, so deep trees overfit the tails and the predicted quantiles collapse toward the median. Raise to 8-10 for large, interaction-heavy problems; set it explicitly to override the per-loss default.

None
l2_leaf_reg float

L2 regularization on leaf values.

1.0
max_bins int

Histogram bins per numeric feature.

128
subsample float

Row subsampling fraction per tree. Below 1.0, rows are drawn by Minimum Variance Sampling (gradient-weighted, unbiased) rather than uniformly.

1.0
colsample float or None

Fraction of features eligible for each tree. None resolves to 1.0 for a single model and to the bagged-member default 0.85 inside n_ensembles > 1 fits (see member_params_).

None
cat_smoothing float

Prior strength for ordered target statistics; higher shrinks rare categories harder toward the global mean. Must be > 0 -- it is the Bayesian pseudocount in the encoder denominator, so 0 is undefined.

1.0
cat_n_permutations int

Number of random orderings averaged by the ordered target encoder.

4
early_stopping_rounds int or None

Rounds without validation improvement before stopping. None becomes 50 when early stopping is active.

None
loss str or object

Training objective. Built in: "RMSE", "MAE", "Quantile" (level set by alpha), "Huber" (transition set by delta), and the log-link losses "Poisson", "Gamma", "Tweedie" (power set by tweedie_variance_power), whose predictions are exp(raw score) > 0. Alternatively a custom objective instance: subclass chimeraboost.CustomObjective and implement grad_hess(y, raw) and eval(y, raw, sample_weight=None).

"RMSE"
alpha float

Quantile level for loss="Quantile" (e.g. 0.9 for the 90th percentile).

0.5
delta float

Huber transition point for loss="Huber", in y units: quadratic within delta of the target, linear beyond. Fixed, not quantile-adaptive -- scale it to the data.

1.0
tweedie_variance_power float

Variance power for loss="Tweedie", strictly between 1 (Poisson) and 2 (Gamma).

1.5
eval_metric callable or None

Custom validation metric metric(y_true, y_pred[, sample_weight]) -> float scored on the validation set each round and used for early stopping and the internal model selections instead of the training loss. y_pred is the prediction (after the loss link). Lower is better, unless the callable carries a greater_is_better = True attribute -- validation_history_ then records negated values so the internal lower-is-better machinery is unchanged. The training loss still drives the gradients; the verbose per-round "train" column stays in training-loss units.

None
min_child_weight float

Minimum total hessian required on each side of a split.

1.0
thread_count int or None

numba thread count. None or -1 uses all detected cores.

None
random_state int or None

Seed for reproducibility (deterministic for a fixed thread_count).

None
verbose bool

Print per-round train and validation metrics.

False
ordered_boosting bool

Use the leave-one-out leaf training step instead of plain Newton updates.

False
cat_combinations bool or None

Add all pairwise categorical-by-categorical features. None enables them automatically only when the data is entirely categorical (where the interaction columns help without crowding out numeric splits); set True/False to force it on/off.

None
leaf_estimation_iterations int

Newton refinement steps per leaf.

1
linear_leaves bool or None

Fit a ridge linear model per leaf over the numeric split features instead of a constant value, adding local slope where step leaves underfit. Leaves with too few rows fall back to a constant. Not available with MAE or quantile loss. None (the default) = validation-selected: both variants are fit and the one with the lower validation loss is kept (~2x fit time; requires an early-stopping split or eval_set, RMSE loss, and >= 1000 rows -- otherwise constant leaves are used). Set True/False to force one variant and skip the double fit.

None
linear_lambda float

Ridge penalty on per-leaf linear slopes; larger is closer to a constant.

1.0
quantize_gradients bool

Run the split search on quantized gradients/hessians packed into integer histograms (LightGBM-style quantized training, ~15-bit): ~20-25% faster fits at benchmark-flat accuracy. Leaf values always use the exact float gradients; the rounding noise touches only split selection and is deterministic for a fixed random_state. False restores exact float64 histograms.

True
cross_features (bool, always or None)

Numeric interaction columns. None (the default) and True refit with difference and product columns for the pairs of the top numeric features of the base fit and keep whichever model reaches the lower validation loss (cross_features_selected_ records the outcome, cross_pairs_ the columns kept); applies to RMSE loss with >= 2000 rows and >= 2 numeric features, and is skipped otherwise. False turns it off. Oblivious trees can only staircase a numeric interaction such as x_i < x_j; a cross column makes it a single split. Costs up to ~2x fit time when the refit runs. "always" skips the validation race and keeps the cross columns unconditionally (a narrower top-4 block, ranked by a short importance probe): one full fit instead of the race, for the fast one-fit operating point. quality=1 pins this on the regressor. Same applicability gates; inert where they fail.

None
cross_top_columns int or None

Cap on how many candidate cross columns the augmented fit carries. None (the default) carries all of them. An integer k keeps only the k candidates whose values correlate most strongly with the base fit's validation residuals, which cuts the augmented fit's per-round cost; the validation race still decides whether the surviving block is used at all (under cross_features="always" it trims the forced block instead). Inert wherever cross features do not apply.

None
selection_rounds int or None

Round budget for the internal selection fits. The constant/linear-leaf variants and the pre-cross base fit run at most this many rounds (auditions, judged on their best validation loss within the budget); the winning candidate continues to full early stopping, and the audition winner is refit in full only when the cross-augmented model loses or cross features do not apply. An audition that early-stops before the budget is the full fit already (no extra cost). None runs every variant to full early stopping instead (the pre-0.15 behavior, ~1.5x slower fits); an audition can occasionally pick a different variant than full fits would.

100
early_stopping bool

Hold out a validation split and stop when its score stops improving.

True
validation_fraction float

Validation fraction used when early_stopping is on and no eval_set is passed to fit.

0.2
n_ensembles int or None

Number of bagged members. None or 1 trains a single model; >= 2 averages independent members, each fit on its own random row sample (max_samples, without replacement by default).

None
ensemble_n_jobs int

Worker processes fitting ensemble members concurrently, each on an equal share of the thread budget (same total cores as a single fit; models are identical either way, wall-clock 1.2-2x faster). -1 sizes the pool from the budget, capped at n_ensembles; 1 fits members sequentially, each with the full budget.

-1
max_samples float

Fraction of rows each ensemble member trains on, drawn WITHOUT replacement ("subagging"). The default 0.8 beats the classic bootstrap on strength and fit time (a full-size bootstrap holds only ~0.63n unique rows at n rows of compute). 1.0 restores the classic full-size with-replacement bootstrap. Unsampled rows are each member's early-stopping eval set either way. When groups is passed to fit, the draw is over whole groups instead of rows (a cluster bootstrap at 1.0), so each member's eval set is made of groups it never trained on.

0.8
refit_full (replay, bool)

After the automatic early-stopping split has chosen the tree budget (and model selection / calibration have used it), retrain the winning configuration on 100% of the rows -- rounds scaled by the train-size ratio, learning rate pinned -- so the final model does not pay the holdout data tax. Only affects fits that used the automatic split (an explicit eval_set or early_stopping=False is unchanged); loss="Quantile" ignores it to keep its conformal holdout honest. validation_history_ keeps the early-stopped fit's curve. Costs one extra refit; on by default since 0.25.0, as the strongest single-model setting measured (benchmarks/SELECT_PLAN.md). Set False, or quality=2, for the faster pre-0.25 behaviour.

The default is "replay", which gets the same thing for about two thirds of the cost. Growing trees is 83-85% of a fit and is a SEARCH; "replay" reuses the winner's tree structures and refits only the leaf values against full-data gradients, so the held-out rows still shape every leaf value while the split search is not paid for twice.

Measured against True at 3 seeds: on Grinsztajn accuracy was flat (27W-32L over 59 datasets, mean +0.005%) and fit time fell 34% on all 59; on high-cardinality categorical data it ran slightly behind (mean -0.256%) for 17% less fit time. Pass True for the from-scratch refit -- marginally stronger on high-card data, and the setting benchmarked in REFIT_PLAN.md. Multiclass ignores "replay" and always uses the from-scratch refit (benchmarks/REPLAY_PLAN.md).

"replay"
refit_members bool

The bagged analogue of refit_full, and off by default. A bag member trains on max_samples of the rows and early-stops on its out-of-bag complement, so its leaf values never see the rows it stopped on -- the full-data refit that helps a single model has never fired for it. With True each member replays its own tree structure against gradients from every row once early stopping is done. Only the leaf values move; the splits stay exactly as that member's own sample grew them, which is where a bag's diversity actually lives.

Measured on the decision suites, an 8-member bag improves in every stratum, with perfect sweeps on the small-data ones (Grinsztajn at a quarter of the rows 12W-0L, +1.206%), for about 10-17% more fit time. Because each member is individually stronger you can also spend the gain on fewer members: 5 refit members beat a plain 8-member bag on accuracy while fitting about 20% faster. Ignored unless the fit is bagged (n_ensembles >= 2), and ignored for multiclass, where a member would need a full refit rather than a cheap structure replay.

False
adaptive_learning_rate bool

Let the auto learning_rate depend on how much data it has, instead of being size-blind: a linear fade from 0.07 at 5,000 training rows or fewer up to the historical flat 0.1 at 15,000 or more. Small data is where a lower rate pays, and it is also where the extra trees it needs are cheap. Default-on since 0.30.0; above the upper threshold it is a no-op and the model is byte-identical to earlier versions, so only small-data fits move. Set False for the flat 0.1 everywhere.

Measured on the decision suites, the mean is positive in six of seven strata, with sign-test passes at a quarter of the rows on both Grinsztajn (9W-3L) and high-card (3W-0L) and no losses at all on high-card at full size (6W-0L). Gains are individually small (medians of +0.13% to +0.31%) and cost 1.09x to 1.31x fit time on the sizes it touches. Only consulted when learning_rate is None and early stopping is on -- without early stopping the rate already scales with the round budget. Bagged fits (n_ensembles >= 2) are unaffected too, since their members already carry an explicit member learning rate.

True
cat_features list of int or str, or None

Default categorical columns, given as integer positions and/or column names (names resolved against the DataFrame at fit). Used when fit is called without its own cat_features (the fit argument overrides). Provided as a constructor argument so GridSearchCV/Pipeline can carry it.

None

Attributes:

Name Type Description
feature_importances_ ndarray of shape (n_features,)

Split-gain importance per input feature, normalized to sum to 1.

best_iteration_ int

Number of trees retained after early stopping.

expected_value_ float

SHAP baseline in the same additive space as shap_values. For the identity-link losses it is the mean prediction over the background (with the conformal quantile offset folded in when present); for the log-link losses and custom losses with a non-identity transform it is the mean raw score over the background. Set after calling shap_values.

estimators_ list or None

Fitted members when n_ensembles > 1, otherwise None.

member_params_ dict

Bagged-mode member defaults that were auto-applied (params the user left on auto resolve to tuned member values inside a bag; explicit values always win). Set only when n_ensembles > 1.

quantile_offset_ float

Split-conformal correction added to every prediction when loss="Quantile" and a validation split was available: the conformal order statistic of the validation residuals, restoring the nominal coverage that learning-rate shrinkage of the per-leaf quantile steps otherwise starves. 0.0 for other losses or without a validation set.

linear_leaves_selected_ bool or None

With linear_leaves=None, whether the linear-leaf variant won the validation selection. None when no selection took place.

Source code in chimeraboost/sklearn_api.py
def __init__(self, n_estimators=2000, learning_rate=None, depth=None,
             l2_leaf_reg=1.0, max_bins=128, subsample=1.0, colsample=None,
             cat_smoothing=1.0, cat_n_permutations=4,
             early_stopping_rounds=None,
             loss="RMSE", alpha=0.5, min_child_weight=1.0, thread_count=None,
             random_state=None, verbose=False, ordered_boosting=False,
             cat_combinations=None, leaf_estimation_iterations=1,
             linear_leaves=None, linear_lambda=1.0, cross_features=None,
             cross_top_columns=None, selection_rounds=100,
             early_stopping=True, validation_fraction=0.2,
             n_ensembles=None, ensemble_n_jobs=-1, max_samples=0.8,
             cat_features=None, quantize_gradients=True,
             eval_metric=None, delta=1.0, tweedie_variance_power=1.5,
             refit_full="replay", refit_members=False, quality=None,
             adaptive_learning_rate=True):
    self.n_estimators = n_estimators
    self.learning_rate = learning_rate
    self.depth = depth
    self.l2_leaf_reg = l2_leaf_reg
    self.max_bins = max_bins
    self.subsample = subsample
    self.colsample = colsample
    self.cat_smoothing = cat_smoothing
    self.cat_n_permutations = cat_n_permutations
    self.early_stopping_rounds = early_stopping_rounds
    self.cat_features = cat_features
    self.loss = loss
    self.alpha = alpha
    self.delta = delta
    self.tweedie_variance_power = tweedie_variance_power
    self.eval_metric = eval_metric
    self.min_child_weight = min_child_weight
    self.thread_count = thread_count
    self.random_state = random_state
    self.verbose = verbose
    self.ordered_boosting = ordered_boosting
    self.cat_combinations = cat_combinations
    self.leaf_estimation_iterations = leaf_estimation_iterations
    self.linear_leaves = linear_leaves
    self.linear_lambda = linear_lambda
    self.cross_features = cross_features
    self.cross_top_columns = cross_top_columns
    self.selection_rounds = selection_rounds
    self.early_stopping = early_stopping
    self.validation_fraction = validation_fraction
    self.n_ensembles = n_ensembles
    self.ensemble_n_jobs = ensemble_n_jobs
    self.max_samples = max_samples
    self.quantize_gradients = quantize_gradients
    self.refit_full = refit_full
    self.refit_members = refit_members
    self.quality = quality
    # Size fade for the auto learning rate, default-on since 0.30.0; only
    # consulted when learning_rate is None. False == the historical flat 0.1.
    self.adaptive_learning_rate = adaptive_learning_rate

validation_history_ property

validation_history_

Per-round validation score recorded during fit.

The training loss (RMSE space for regression), or the custom eval_metric when one was set -- negated if the metric declares greater_is_better = True, so lower is always better here.

A list as long as the number of rounds run. Empty when no eval_set or early-stopping split was available; a list of the members' histories for a bagged model (n_ensembles > 1).

fit

fit(
    X,
    y,
    cat_features=None,
    eval_set=None,
    groups=None,
    sample_weight=None,
    callbacks=None,
)

Fit the model.

Parameters:

Name Type Description Default
X array - like

Training data.

required
y array - like

Training data.

required
cat_features list of int or str, or None

Columns to treat as categoricals, given as integer positions and/or column names (names resolved against the DataFrame). Falls back to the cat_features constructor argument when not given here; passing it here overrides the constructor value. (The constructor form lets GridSearchCV/Pipeline carry it, which a fit-only kwarg can't.)

None
eval_set (X_val, y_val) tuple or None

Explicit validation set. When provided, automatic splitting is skipped regardless of the early_stopping setting.

None
groups array-like of shape (n_samples,) or None

Group labels for the samples (e.g. df['subject_id']). When supplied and early_stopping triggers an automatic split, groups are kept intact across the train/validation boundary using GroupShuffleSplit.

None
sample_weight array-like of shape (n_samples,) or None

Per-sample weights, normalized to mean 1 internally. Applied throughout: the gradient/leaf fit, the categorical target encoder, the quantile bin borders, and the early-stopping metric on an automatically split (or bagged out-of-bag) validation set, so a zero-weight row never influences the model. An explicitly passed eval_set carries no weights and is scored unweighted.

None
callbacks callable or list of callable, or None

Per-round fit hooks cb(iteration, train_loss, val_loss, model); a callback returning True requests an early stop. Used for live validation-curve capture and instrumentation. Not supported with n_ensembles > 1 (members fit in parallel worker processes).

None
Source code in chimeraboost/sklearn_api.py
def fit(self, X, y, cat_features=None, eval_set=None, groups=None,
        sample_weight=None, callbacks=None):
    """Fit the model.

    Parameters
    ----------
    X, y : array-like
        Training data.
    cat_features : list of int or str, or None
        Columns to treat as categoricals, given as integer positions and/or
        column names (names resolved against the DataFrame). Falls back to the
        ``cat_features`` constructor argument when not given here; passing it
        here overrides the constructor value. (The constructor form lets
        ``GridSearchCV``/``Pipeline`` carry it, which a fit-only kwarg can't.)
    eval_set : (X_val, y_val) tuple or None
        Explicit validation set. When provided, automatic splitting is
        skipped regardless of the *early_stopping* setting.
    groups : array-like of shape (n_samples,) or None
        Group labels for the samples (e.g. ``df['subject_id']``). When
        supplied and *early_stopping* triggers an automatic split, groups
        are kept intact across the train/validation boundary using
        ``GroupShuffleSplit``.
    sample_weight : array-like of shape (n_samples,) or None
        Per-sample weights, normalized to mean 1 internally. Applied
        throughout: the gradient/leaf fit, the categorical target encoder,
        the quantile bin borders, and the early-stopping metric on an
        automatically split (or bagged out-of-bag) validation set, so a
        zero-weight row never influences the model. An explicitly passed
        ``eval_set`` carries no weights and is scored unweighted.
    callbacks : callable or list of callable, or None
        Per-round fit hooks ``cb(iteration, train_loss, val_loss, model)``;
        a callback returning True requests an early stop. Used for live
        validation-curve capture and instrumentation. Not supported with
        ``n_ensembles > 1`` (members fit in parallel worker processes).
    """
    cat_features = _resolve_cat_features(self, cat_features)
    cat_features = _resolve_cat_feature_names(cat_features, X)
    _validate_hyperparams(self)
    y = _validate_fit_input(self, X, y, cat_features, sample_weight,
                            classification=False)
    # Cached shap_importances describe the previous fit; drop them.
    self._shap_importances_cache_ = None

    if eval_set is not None:
        _check_eval_set(eval_set, self.n_features_in_)

        # A reordered or renamed eval DataFrame is consumed positionally and
        # silently wrecks early stopping, and everything calibrated on the
        # holdout. Bag members skip this: their eval sets are built
        # internally from already-validated parent input.
        if not getattr(self, "_is_bag_member", False):
            _check_feature_names_match(self, eval_set[0])

    with _quality_applied(self):
        if self.n_ensembles and self.n_ensembles > 1:
            if callbacks is not None:
                raise ValueError(
                    "callbacks are not supported with n_ensembles > 1.")
            self.estimators_ = _fit_bagged(self, X, y, cat_features,
                                           eval_set, groups, sample_weight)
            return self

        self.estimators_ = None
        return self._fit_single(X, y, cat_features, eval_set, groups,
                                sample_weight, callbacks)

predict_raw

predict_raw(X)

Raw additive score before the loss link and conformal quantile offset.

For the identity-link losses (RMSE/MAE/Huber) this equals predict; for loss="Quantile" it is predict minus the fitted quantile_offset_. For the log-link losses (Poisson/Gamma/Tweedie) and custom losses with a non-identity transform it is the pre-link score -- the space shap_values reconstructs exactly. Averaged across the bag when n_ensembles > 1, mirroring predict.

Source code in chimeraboost/sklearn_api.py
def predict_raw(self, X):
    """Raw additive score before the loss link and conformal quantile offset.

    For the identity-link losses (RMSE/MAE/Huber) this equals ``predict``;
    for ``loss="Quantile"`` it is ``predict`` minus the fitted
    ``quantile_offset_``. For the log-link losses (Poisson/Gamma/Tweedie)
    and custom losses with a non-identity ``transform`` it is the pre-link
    score -- the space ``shap_values`` reconstructs exactly. Averaged across
    the bag when ``n_ensembles > 1``, mirroring ``predict``.
    """
    Xv = _check_predict_input(self, X)
    X = X if Xv is None else Xv

    if self.estimators_ is not None:
        with _thread_limit(self.thread_count):
            Xc, ctx = _bag_predict_context(self, X)
            return np.mean([m.model_.predict_raw(Xc, ctx)
                            for m in self.estimators_], axis=0)
    return self.model_.predict_raw(X)

staged_predict

staged_predict(X)

Yield the prediction after each successive tree.

The conformal quantile offset is a post-fit constant and is included in every stage, so the final stage equals predict.

Source code in chimeraboost/sklearn_api.py
def staged_predict(self, X):
    """Yield the prediction after each successive tree.

    The conformal quantile offset is a post-fit constant and is included in
    every stage, so the final stage equals ``predict``.
    """
    Xv = _check_predict_input(self, X)
    X = X if Xv is None else Xv

    if self.estimators_ is not None:
        raise NotImplementedError("staged_predict is not defined for a "
                                  "bagged ensemble (n_ensembles > 1).")

    for staged in self.model_.staged_predict_raw(X):
        yield self._transform_raw(staged) + self.quantile_offset_

report

report(X, y, sample_weight=None, baseline=None)

Score this model on (X, y): RMSE, MAE and the R2 skill score.

Returns the chimeraboost.metrics.regression_report dict; chimeraboost.metrics.format_report prints it. baseline sets what the skill score is measured against -- pass the training targets to score against the mean the model actually had, rather than the hindsight mean of y.

Source code in chimeraboost/sklearn_api.py
def report(self, X, y, sample_weight=None, baseline=None):
    """Score this model on ``(X, y)``: RMSE, MAE and the R2 skill score.

    Returns the `chimeraboost.metrics.regression_report` dict;
    `chimeraboost.metrics.format_report` prints it. ``baseline`` sets what
    the skill score is measured against -- pass the training targets to
    score against the mean the model actually had, rather than the
    hindsight mean of ``y``.
    """
    from . import metrics
    return metrics.regression_report(y, self.predict(X), sample_weight,
                                     baseline)

shap_values

shap_values(X, X_background=None)

Exact interventional TreeSHAP contributions in the model's additive space.

Returns an array of shape (n_samples, n_features) whose rows sum to the model's additive score minus expected_value_. For the identity- link losses this is predict(X) - expected_value_; for loss="Quantile" the fitted conformal offset is folded into expected_value_ too, so the rows still sum to predict(X) - expected_value_. For the log-link losses (Poisson/Gamma/Tweedie) and custom losses with a non-identity transform, attributions stay in raw (link) space and rows sum to predict_raw(X) - expected_value_. expected_value_ (set as an attribute by this call) is the mean additive score over the background. Each entry is a feature's signed additive contribution; linear-leaf slopes are included exactly. Averaged across the bag when n_ensembles > 1 -- the bag prediction is the members' mean, so the averaged attribution stays exact. X_background overrides the reference distribution (default: a sample of the training data).

Source code in chimeraboost/sklearn_api.py
def shap_values(self, X, X_background=None):
    """Exact interventional TreeSHAP contributions in the model's additive space.

    Returns an array of shape ``(n_samples, n_features)`` whose rows sum to
    the model's additive score minus ``expected_value_``. For the identity-
    link losses this is ``predict(X) - expected_value_``; for
    ``loss="Quantile"`` the fitted conformal offset is folded into
    ``expected_value_`` too, so the rows still sum to ``predict(X) -
    expected_value_``. For the log-link losses (Poisson/Gamma/Tweedie) and
    custom losses with a non-identity ``transform``, attributions stay in raw
    (link) space and rows sum to ``predict_raw(X) - expected_value_``.
    ``expected_value_`` (set as an attribute by this call) is the mean
    additive score over the background. Each entry is a feature's signed
    additive contribution; linear-leaf slopes are included exactly. Averaged
    across the bag when ``n_ensembles > 1`` -- the bag prediction is the
    members' mean, so the averaged attribution stays exact. ``X_background``
    overrides the reference distribution (default: a sample of the training
    data).
    """
    Xv = _check_predict_input(self, X)
    X = X if Xv is None else Xv

    if X_background is not None:
        # The background matrix is consumed positionally too; a reordered
        # DataFrame would silently skew every baseline.
        bg = _check_predict_input(self, X_background)
        X_background = X_background if bg is None else bg

    if self.estimators_ is not None:
        out = [m.model_.shap_values(X, background=X_background)
               for m in self.estimators_]

        # Fold each member's conformal quantile offset into the baseline so
        # rows still sum to predict(X) - expected_value_.
        self.expected_value_ = float(np.mean(
            [b + m.quantile_offset_ for m, (_, b) in zip(self.estimators_, out)]))
        return np.mean([p for p, _ in out], axis=0)

    phi, base = self.model_.shap_values(X, background=X_background)
    # The conformal quantile offset is a constant shift; it belongs to the
    # baseline, keeping rows summing to predict(X) - expected_value_.
    self.expected_value_ = base + self.quantile_offset_
    return phi

shap_importances

shap_importances(
    X, feature_names=None, n_features=None, prettified=False
)

Global SHAP importance: mean(abs(shap_values(X))) per feature.

Returns a structured (feature, importance) array sorted descending, or a {feature: importance} dict when prettified=True (CatBoost's flag). feature holds feature_names when given, else the names captured from a DataFrame at fit, else column indices. n_features truncates to the top N.

The expensive SHAP pass is cached on the instance, keyed by the data's content, so repeated calls on the same X -- including with different formatting options -- reuse it. The cache is dropped on refit. See shap_values for the attribution space and cost.

Source code in chimeraboost/sklearn_api.py
def shap_importances(self, X, feature_names=None, n_features=None,
                     prettified=False):
    """Global SHAP importance: ``mean(abs(shap_values(X)))`` per feature.

    Returns a structured ``(feature, importance)`` array sorted descending,
    or a ``{feature: importance}`` dict when ``prettified=True``
    (CatBoost's flag). ``feature`` holds ``feature_names`` when given,
    else the names captured from a DataFrame at fit, else column indices.
    ``n_features`` truncates to the top N.

    The expensive SHAP pass is cached on the instance, keyed by the data's
    content, so repeated calls on the same X -- including with different
    formatting options -- reuse it. The cache is dropped on refit. See
    ``shap_values`` for the attribution space and cost.
    """
    return _shap_importances(self, X, feature_names, n_features,
                             prettified)