Greedy ensemble selection over an AutoML trial pool.
A search leaves behind dozens of fitted models and keeps one. Caruana et al. (2004) showed that a weighted average of the pool, assembled greedily, is reliably better than its single best member and costs nothing more to build: the models are already fitted, and selection works purely on their stored validation predictions.
This module implements that procedure and the small combiner that carries the result. It is not a replacement for VotingClassifier, which builds an ensemble by fitting a declared list of learners with fixed weights; here the members are already fitted, the pool is whatever the search happened to produce, and the weights are what selection discovers.
References
Classes
A weighted average of already-fitted models, chosen by selection.
greedy_selection from an AutoML trial pool and used as the final predictor when the ensemble scores better than the best single trial. It holds fitted models, so it has no fit: everything it needs was learned during the search.__init__( self, models: Sequence[Any], weights: np.ndarray, task: str = 'classification', classes: Optional[np.ndarray] = None, )
Parameters
models
greedy_selection.
weights
task
classes
Attributes
members_
(weight, model) pairs that actually contribute, heaviest first.
See Also
>>> import numpy as np
>>> from tuiml.algorithms.trees import DecisionTreeClassifier
>>> from tuiml.automl.ensembling import GreedyEnsemble
>>> from tuiml.datasets import load_iris
>>> data = load_iris()
>>> trees = [DecisionTreeClassifier(max_depth=d).fit(data.X, data.y)
... for d in (1, 3)]
>>> ensemble = GreedyEnsemble(trees, np.array([0.25, 0.75]),
... task="classification",
... classes=np.unique(data.y))
>>> ensemble.predict(data.X[:3]).tolist()
[0, 0, 0]
Methods
predict_proba
(self, X: np.ndarray) -> np.ndarray
predict_proba
(self, X: np.ndarray) -> np.ndarray
Predict weighted-average class probabilities.
Parameters
X
Returns
proba
classes_.
Raises
RuntimeError
Functions
Select an ensemble greedily, with replacement, from a pool of models.
Overview
- Start from the empty ensemble.
- In each round, try appending every pool member to the current
-
Repeat for
n_rounds. Selection is with replacement: a strong
- Return the prefix of the selection sequence with the highest score,
Theory
After k rounds the ensemble prediction is the running mean of the selected members,
so the number of times model j was selected, divided by k, is its weight. Because each round maximises the score of \bar{p}_k directly, selection optimises the target metric itself rather than a differentiable surrogate, and it cannot do worse than the single best model, which is always available as the first pick.
Parameters
predictions
(n_samples, n_classes) probabilities for classification, or (n_samples,) values for regression.
y_true
scorer
(y_true, y_pred) -> float, higher is better.
n_rounds
decode
scorer expects, e.g. probabilities to hard class labels. Identity when omitted.
Returns
weights
score
order
Raises
ValueError
predictions is empty.
>>> import numpy as np
>>> from tuiml.automl.ensembling import greedy_selection
>>> y = np.array([0, 0, 1, 1])
>>> good = np.array([[.9, .1], [.8, .2], [.2, .8], [.1, .9]])
>>> bad = np.array([[.4, .6], [.3, .7], [.6, .4], [.7, .3]])
>>> accuracy = lambda t, p: float(np.mean(t == p))
>>> weights, score, order = greedy_selection(
... [good, bad], y, accuracy, n_rounds=4,
... decode=lambda p: p.argmax(axis=1))
>>> weights.tolist()
[1.0, 0.0]
>>> score
1.0
Return a model's class probabilities in a fixed column order.
classes first.Parameters
model
X
classes
Returns
proba
classes.