Machine Learning · Insper

AutoML

How to spend the search budget

Grid, random, Bayesian optimization, TPE, successive halving, and the two ways an automated search fails

The question no lesson asked yet

  • Every model comes with knobs; Model Selection explained what they do, Cross-Validation how to compare the results honestly.
  • A grid with 5 hyperparameters and 5 values each: 3,125 cross-validations, most of them in regions that were obviously bad after the first dozen.

hyperparameter optimization

treats the search itself as an optimization problem

AutoML

pushes the same idea to the whole pipeline: preprocessing, family, hyperparameters, the final ensemble

The path of this lesson

  1. Frame the searchan expensive, noisy black box; the search space
  2. Grid or randomBergstra & Bengio, measured
  3. A search that learnsBayesian optimization, TPE, Optuna
  4. Stop bad trials earlypruning, successive halving, Hyperband
  5. Automate, then checkthe whole pipeline, leaks, a flattering score
Each stage answers one question: what are we optimizing, and over which space? → with no memory, grid or random? → can past trials choose the next one? → why pay in full for a bad trial? → how far can automation go, and where does it fail?
Stage 1 · what are we optimizing, and over which space?

One call to the black box

\(\lambda\): a configuration. \(f(\lambda)\): its cross-validated score. Tuning = find the \(\lambda\) with the largest \(f(\lambda)\).

  • kc1: 2,109 software modules of a NASA flight system, 21 code metrics; target: was a defect found later? (15.5% defective)
  • One call = a 5-fold CV ROC AUC of a boosted model.
Predict. The same configuration, cross-validated with 5 different shuffles of the folds. Does it get the same score each time?

Expensive, noisy, and a black box

settings5 fold shufflesmean
defaults0.760 · 0.776 · 0.767 · 0.769 · 0.7690.768
small, slow trees0.795 · 0.806 · 0.804 · 0.803 · 0.8050.803

expensive

each call is 5 fits; on a real project, minutes or hours. The number of calls is the budget.

noisy

0.760 to 0.776 for the same settings: a difference of 0.01 may not be real

black box

no gradient with respect to min_samples_leaf; integers, categories, conditional knobs

A tuning method is a rule for choosing the next \(\lambda\), given the ones already evaluated.

Designing the space (1): the scale

Predict. Sample a learning rate uniformly between 0.001 and 1. What share of the draws falls in \([0.001, 0.01)\)?
learning rate inuniformlog-uniform
[0.001, 0.01)0.9%33.5%
[0.01, 0.1)9.1%33.2%
[0.1, 1)90.0%33.3%

By hand: \(0.009 / 0.999 = 0.9\%\); on the log scale each of the 3 decades gets a third.

Anything that acts multiplicatively (learning rates, C, alpha, numbers of leaves or neighbors) gets a log scale: loguniform, or log=True in Optuna.

Designing the space (2): conditional knobs

  • C belongs to the logistic regression, max_leaf_nodes to the booster, gamma to an RBF kernel.
  • One grid over all of them would pair every C with every tree size: the same logistic regression, fitted again and again.
The search space is a tree: first choose the family, then that family's knobs. Model Selection used a list of grids; Optuna will write it as an if.
Stage 2 · searching without memory

Grid or random? The argument

  • A score that depends on one hyperparameter \(x_1\) (a bump of width 0.05); the other \(d - 1\) do nothing.
  • A grid with \(k\) values per axis costs \(k^d\) evaluations, but tries \(x_1\) at only \(k\) values.
  • Random search with budget \(B\) tries \(x_1\) at \(B\) values, whatever \(d\) is.
Predict. 81 evaluations over 4 hyperparameters (a 3 × 3 × 3 × 3 grid). How does the grid compare with a 3 × 3 grid of only 9 evaluations?

Grid or random? Measured on 4,000 problems

dbudgetgridrandom
290.3780.629
2810.8240.985
3270.3780.900
4810.3780.986
42560.5010.998
A 3 by 3 grid tries the important hyperparameter at only 3 values, 9 random points at 9; mean best score against the budget

Mean best score. The grid pays for every irrelevant axis with a multiplication of its cost; random search pays nothing (Bergstra & Bengio, 2012).

Simulator: same budget, different searches

Predict. Budget 81: how many distinct values of \(x_1\) does the 9 × 9 grid try, and how many does random search try?

Stage 3 · can past trials choose the next one?

Bayesian optimization: a search that learns

Random search draws the 27th configuration exactly like the first. When each evaluation costs an hour, that is wasteful.

  1. fit a cheap surrogate to the (configuration, score) pairs so far: it predicts the score anywhere, with an uncertainty;
  2. choose the next configuration by maximizing an acquisition function: exploitation (high predicted score) against exploration (high uncertainty);
  3. evaluate it, add it to the history, repeat.

A stand-in score with a known truth: a broad peak of 0.78 at 0.25 and a higher, narrower one of 0.82 at 0.72.

The surrogate: a Gaussian process

Three evaluations so far: 0.15 and 0.35 (0.72943), 0.95 (0.700). Best so far \(f^+ = 0.72943\).

\(x\)mean \(\mu\)sd \(\sigma\)reading
0.250.730760.00419between two points: nearly sure, just above \(f^+\)
0.550.722120.01246far from any point: below \(f^+\), three times more uncertain
0.720.713900.01318the real peak, but the surrogate knows nothing about it
Predict. Which of the three deserves the next evaluation?

Expected improvement, by hand

\[ \mathrm{EI}(x) = \underbrace{(\mu - f^+)\,\Phi(z)}_{\text{exploitation}} + \underbrace{\sigma\,\varphi(z)}_{\text{exploration}}, \qquad z = \frac{\mu - f^+}{\sigma} \]
\(x\)\(z\)\((\mu - f^+)\Phi(z)\)\(\sigma\varphi(z)\)EI
0.25+0.32+0.000830.001590.00242
0.55−0.59−0.002030.004170.00214
0.72−1.18−0.001850.002620.00077
At 0.25 the mean does the work; at 0.55 the uncertainty does, and almost wins. The expensive function is evaluated once per iteration; the cheap surrogate is queried thousands of times.

Four iterations

Four iterations of Bayesian optimization: the first exploits the small peak at 0.25, the second explores and lands on the high peak at 0.72, the last two refine around it

1: exploits 0.25 → 0.780. 2: its EI collapses, so it explores the gap → 0.72, 0.820. 3–4: refine at 0.685 and 0.775. Random search would need about 28 draws to land that close to 0.72.

The surrogate's assumptions matter

100 runs from random starting triples, 30 evaluations each. Share of runs that reached 0.81:

within 10within 20within 30
BO, length scale 0.1540%65%65%
BO, length scale 0.1061%92%92%
random search37%54%65%
With 0.15 the surrogate is too sure the score is smooth: it predicts a flat, certain 0.70 over the narrow peak and stops looking. A wrong model makes wrong decisions confidently.

TPE: model \(x\) given the score

  • Split the trials into the good ones (best fraction \(\gamma\)) and the rest.
  • Density of the good values \(\ell(x)\), density of the others \(g(x)\): one Gaussian bump per trial.
  • Sample where \(\ell(x)/g(x)\) is largest (Bergstra et al., 2011).
\(x\)0.10.250.50.70.9
\(\ell / g\)0.031.240.455.730.09
12 random trials, 2 of the 3 good ones near 0.68: the next trial goes to 0.710, which scores 0.817. One pair of 1-D densities per knob: integers, categories and conditional knobs are easy.

Optuna: TPE against random, measured

Six hyperparameters: one matters a lot, one a little, four not at all. Best possible: 0.870. 20 seeds.

Predict. After 10 trials, who is ahead?
mean best after10204060 trials
random0.8120.8190.8300.843
TPE0.8120.8470.8570.860

Identical at 10: TPE's first 10 trials are random. After 40 it is above what random reaches after 60.

Define-by-run: the space is code


def build(trial):
    family = trial.suggest_categorical('family', ['logistic', 'boosting'])
    if family == 'logistic':
        C = trial.suggest_float('C', 1e-3, 1e2, log=True)
        return make_pipeline(FunctionTransformer(np.log1p), StandardScaler(),
                             LogisticRegression(C=C, max_iter=2000))
    return HistGradientBoostingClassifier(
        learning_rate=trial.suggest_float('learning_rate', 0.01, 0.5, log=True), ...)
  
On kc1 the best is a logistic regression, C ≈ 0.03, 0.798, tied with the hand-picked booster; TPE spent 31 of its 40 trials on it. A space that leaves out the simple model can never tell you that you did not need the complicated one.
Stage 4 · why pay in full for a bad trial?

Pruning: stop a bad trial early

  • The objective reports its running mean after every fold (trial.report).
  • The median pruner stops a trial worse than the median of earlier trials at the same fold.
10 of 40
trials pruned
171 of 200
folds fitted: 15% of the budget saved
Pruning is a bet that a trial that starts badly ends badly. The next method makes that bet systematically.

Successive halving: a tournament

Start \(n = 27\) configurations on a small budget; keep the best third; give the survivors 3 × more; repeat.

roundconfigurationstrees eachcost
12710270
2930270
3390270
41270270
total1,080
All 27 at 270 trees would cost 7,290: the tournament looks at 27 configurations for the price of 4 full ones (Jamieson & Talwalkar, 2016; HalvingRandomSearchCV).

What the tournament assumes

The ranking after a small budget predicts the ranking after the full one. Two tournaments: budget in trees, budget in rows.

Predict. Score all 27 candidates at the full budget. Which tournament picked the better winner?
winner with budgetfull scorerank
trees0.78113 of 27
rows0.7875 of 27
best at full budget0.7911
The same 27 configurations halved with trees or rows as the budget; with trees every small learning rate is eliminated after 10 trees

With a small learning rate, 10 trees have barely started: the slow learners, best at 270 trees, all died in round 1.

Hyperband: several tournaments

How aggressive should the tournament be? Hyperband runs brackets of different aggressiveness, each costing about the same (Li et al., 2018).

bracketrounds (configurations × budget)cost
s = 327 × 1 → 9 × 3 → 3 × 9 → 1 × 27108
s = 212 × 3 → 4 × 9 → 1 × 2799
s = 16 × 9 → 2 × 27108
s = 04 × 27 (plain random search)108
If the early ranking is reliable, bracket 3 finds the winner cheaply; if it misleads, bracket 0 still gives the slow learners a fair chance. 423 units for 49 configurations.
Stage 5 · how far can automation go, and where does it fail?

Full-pipeline AutoML: the CASH problem

Combined Algorithm Selection and Hyperparameter optimization (Thornton et al., 2013).

systemhow it searcheswhat it returns
auto-sklearnBayesian optimization, warm-started on similar data setsan ensemble (ensemble selection)
TPOTgenetic programming over pipeline treesthe best pipeline, as scikit-learn code
AutoGluon-Tabularlittle search: bagging and multi-layer stackinga stacked ensemble
FLAMLcost-aware: cheap configurations firstthe best single model in a time budget
Two recurring ideas: ensembles of good, different models, and warm starts. You still write the label, the metric, the time limit, and before all that, the train and test tables.

It optimizes the leak you gave it

bug_reports: filed after release; the model must flag risky modules before release, when the count is zero for everyone.

Predict. The same random search, with and without the column. Which model is better once it is used for real?
ROC AUC
best CV, without the column / with it0.792 / 0.916
test, leaky winner, column filled in0.962
test, honest winner0.804
test, leaky winner, as it will be used (bug_reports = 0)0.782

Every automated check passes. The leak is in the data: only someone who knows when each column is recorded can catch it.

A longer search overfits the validation data

CV score of the chosen configuration and its test score, against the number of trials, with 1,687 and with 300 development rows

1,687 rows, 10 → 150 trials: CV 0.803 → 0.808, test 0.804 → 0.809. Honest.

300 rows: CV 0.772 → 0.788, test 0.765 → 0.769. Three quarters of the reported gain is luck.

Past a point, more trials buy optimism. Grade the whole search: a locked test set, once, or nested CV.

The rest of the job

framing the problem

what is predicted, for whom, when, and what an error costs

choosing the metric

84.5% of kc1 modules are clean: a search on accuracy approves a model that never flags

the validation design

groups, time order and leaks are exploited by the search, not corrected

data and features

removing one leaky column changed average precision by 0.18; tuning, by 0.007

And deployment: a stacked ensemble of 40 models may be the hardest to serve, explain and retrain.

A practical default

  1. Lock a test set away and fix one cv.
  2. Baselines first: a dummy, a linear model, a booster with defaults.
  3. Random search or Optuna, 30–100 trials, log scales, the simple model in the space.
  4. For large data or slow models: halving or pruning, with a budget unit that does not interact with the knobs.
  5. Stop when the best score stops moving by more than its fold standard deviation.
  6. Report the locked test score, or a nested CV of the whole search, never the search's own best score.
Lab · two to three minutes of computing

Four searches, one budget

phoneme: 5,404 vowels, oral or nasal. Grid, random, TPE and halving get 27 evaluations each.

Chosen (best CV): the halving winner, CV 0.9528, test 0.9455; the defaults drop as much (0.9468 → 0.9374).

Random search: best_score_ 0.9499; nested estimate 0.9472 ± 0.0067.

Run !pip install optuna first. Lab notebook (Jupyter or Colab, File → Upload notebook).

Best CV ROC AUC so far on phoneme for grid, random search, TPE and halving

Summary

  1. Tuning is an expensive, noisy black box: the budget is the number of calls.
  2. Design the space: log scales and conditional knobs.
  3. Random beats grid when only a few knobs matter.
  4. Bayesian optimization and TPE learn where to look; their assumptions matter.
  5. Halving and Hyperband stop bad configurations early, if the early ranking is right.
  6. A search optimizes your leaks and its own luck: grade it on untouched data.