Voting and stacking ensembles
This page covers ensemble candidates in a generated Databricks Bundle's
config/training.yml: the voting and stacking model.params fields, nested
member search axes, worked voting, stacking and calibrated examples, and the
setup questions and defaults for each slot. Read it when one model candidate
should combine several learners. The worked examples append a models block to
the common setup header
in the tuning guide.
Back to Databricks Bundle tuning
An ensemble is one model candidate containing several learners. In contrast,
competition evaluates separate candidates and selects one winner. Choose
voting_regressor, voting_classifier, stacking_regressor or
stacking_classifier; see their model cards for
task-specific member menus and defaults.
model.params setting |
Type/default | Effect |
|---|---|---|
base_estimators |
List of distinct member names; model-specific defaults | Choose member keys such as ridge, lasso, random_forest, not automatically the top-level model IDs. Unknown, duplicate and empty selections fail. |
base_estimator_params |
Mapping, {} |
Fixed constructor overrides keyed by selected member name. Unknown members/parameters fail. |
weights |
Voting only; null means equal | Ordered list with one finite nonnegative value per member, or a member-name mapping with omitted selected members defaulting to 1. At least one value must be positive. These weight model votes, not training rows. |
voting |
Classification voting only, soft |
soft averages probabilities; every member needs probability output. hard votes on class labels and has no ordinary predict_proba output. |
final_estimator |
Stacking only; ridge for regression, logistic_regression for classification |
A supported member key for the learner trained on base-model out-of-fold predictions. |
final_estimator_params |
Stacking only; mapping, {} |
Fixed final-learner constructor overrides. |
cv |
Stacking only; integer 5, 2..20 |
Internal out-of-fold predictions for the final learner. prefit is not admitted. |
passthrough |
Stacking only; boolean false |
Also give original input features to the final learner. |
calibrate_base_models |
Boolean, false |
Classification only: wrap each base classifier in probability calibration. |
calibration_method |
String, sigmoid |
sigmoid or isotonic; isotonic needs enough calibration data. |
calibration_cv |
Integer, 3; 2..20 |
Internal calibration folds, separate from shared search CV and stacking CV. |
tune_base_models |
Boolean; false without tuning, inserted true by a tuning wrapper if absent | With automatic spaces, include selected members' search axes. Explicit true requires a tuning wrapper. A manually supplied space owns its own axes. |
n_jobs |
Integer, 1 for Bundle search |
Keep ensemble and member workers at one during search. |
Voting rejects stacking-only fields; stacking rejects weights and voting.
Classification calibration controls are different from the downstream
decision_threshold policy. Row weight_column is a third, independent concept;
all selected members and the final learner must meet the sample-weight contract.
For manual spaces, a member parameter is named <member>__<parameter>, and a
stacking final-learner parameter is final_estimator__<parameter>. Calibrated
members insert estimator__: for example
logistic_regression__estimator__C. Fixed overrides remain fixed in automatic
spaces, and conflicting manual axes fail. Do not search structural member lists,
weights arrays, or estimator objects as scalar axes.
Voting example
Append this alternative models block to the common regression header. It
searches ridge while keeping lasso's alpha fixed. To fit the same ensemble once,
delete the whole tuning mapping.
models:
revenue:
model:
type: voting_regressor
params:
base_estimators: [ridge, lasso]
base_estimator_params:
lasso: {alpha: 0.01}
weights: {ridge: 2, lasso: 1}
tuning:
strategy: grid
metric: rmse
max_candidates: 2
search_space: {ridge__alpha: [0.1, 1.0]}
Stacking example
This alternative searches both a member and the final estimator. Its internal
cv: 2 happens inside each outer search fit, so it costs more than a single
ridge grid even though there are only four candidate combinations.
models:
revenue:
model:
type: stacking_regressor
params:
base_estimators: [ridge, lasso]
base_estimator_params:
lasso: {alpha: 0.01}
final_estimator: ridge
cv: 2
passthrough: false
tuning:
strategy: grid
metric: rmse
max_candidates: 4
search_space:
ridge__alpha: [0.1, 1.0]
final_estimator__alpha: [0.1, 1.0]
Calibrated classification example
This block overrides the header's task/target/metric for a classification model.
The table must have a binary churn label and enough examples per class for
both search and calibration folds. Update the example model's quality threshold
to your domain's accuracy gate before deployment.
models:
churn:
task: classification
target_column: churn
metric: heldout_accuracy
quality_threshold: 0.7
stratify: true
model_name: "{catalog}.{metadata_schema}.churn_model{resource_suffix}"
model:
type: voting_classifier
params:
base_estimators: [logistic_regression, decision_tree]
base_estimator_params:
decision_tree: {max_depth: 2, random_state: 42}
voting: soft
calibrate_base_models: true
calibration_method: sigmoid
calibration_cv: 2
tuning:
strategy: grid
metric: accuracy
max_candidates: 2
search_space:
logistic_regression__estimator__C: [0.1, 1.0]
Spark scoring and serving endpoints
Voting, stacking and calibrated ensembles can score on Spark workers
(batch_compute: spark) and behind serving endpoints. Training first checks
the fitted ensemble as one model: every member, every calibration estimator and
the stacking final learner must be a supported built-in model, and the
ensemble's own predictions must give the same results in batches of any size.
Spark and online-feature projects run this check automatically; an
endpoint-only project enables it with defaults.allow_tested_custom_steps: true.
The check, its evidence and the full model list are described in
Score on Spark workers.
A linear final learner such as the default logistic_regression can differ in
the last floating-point digits between batch sizes. The check allows such
rounding differences
in probabilities but never a changed label. Voting, including soft voting, and
stacking with a decision_tree final learner passed the same checks on real
data.
Setup questions and defaults for each slot
Detailed setup repeats the ensemble question group for the selected single model, each competition candidate, and each multi-target branch. It asks for the member count (default two), each distinct member and the stacking final estimator where applicable. Regression offers up to 14 member positions and classification up to 13; installed optional packages and weighted-mode eligibility still constrain the choices. Selecting two members exposes two member questions, rather than silently filling every available position.
The wizard does not ask for the settings below. Each slot writes their defaults
into model.params in config/training.yml; edit them there, or set them in an
answer file before generation:
| Setting | Answer-file suffix | Default |
|---|---|---|
Voting weight of member K |
weight_K |
1 |
| Classification voting mode | voting |
soft |
| Stacking folds | cv |
3 (5 when omitted from hand-written YAML) |
Stacking passthrough |
passthrough |
false |
| Calibrate classification members | calibrate (YAML calibrate_base_models) |
false |
| Calibration folds | calibration_cv |
3 |
Calibration method defaults to sigmoid; edit YAML to select isotonic.
The answer-file names follow these patterns, with N the candidate/branch
number, task equal to regression or classification, and K the member
position:
| Scope | Answer-file prefix | Common suffixes |
|---|---|---|
| Single model | single_ensemble_<task>_ |
base_count, base_K, weight_K, final |
| Competition slot | competition_ensemble_N_<task>_ |
Same, isolated to that candidate. |
| Multi-target branch | branch_N_ensemble_<task>_ |
Same, isolated to that branch. |
For the shared slot suffixes voting, cv, passthrough, calibrate and
calibration_cv, omit the task portion of the prefix. Examples are
single_ensemble_cv, competition_ensemble_2_calibrate and
branch_1_ensemble_passthrough.
For example, competition_ensemble_2_regression_base_1: "ridge" selects the
first member of candidate two; its weight_1 key applies only to voting.
Setup writes these choices into that model's params; the editable YAML
is the place for detailed member overrides, calibration and manual nested axes.
Inspect the emitted entry because setup keeps these defaults without asking.
Shared competition search settings and per-branch settings still obey the same
accepted tuning fields and budgets in the
tuning guide.