Bias is error from overly simplistic assumptions (model too rigid to capture the real pattern). Variance is error from being too sensitive to the specific training data (model captures noise, not just signal). Total error ≈ bias² + variance + irreducible noise.
As model complexity grows, bias drops but variance climbs — total error is minimized somewhere in the middle, not at either extreme.
Model is too simple to capture the pattern — poor performance on both train and test/validation data.
Model memorizes training data, including noise — great train performance, much worse test performance.
A single train/test split can be lucky or unlucky — cross-validation averages performance across multiple splits for a more reliable estimate.
Split data into k equal parts; train on k−1, validate on the remaining one, rotate k times, average the results. Default choice for i.i.d. tabular data.
Like k-fold, but preserves the class proportion in every fold. Required for classification, especially with imbalanced classes — plain k-fold can accidentally create folds with very few (or zero) minority-class examples.
Folds respect chronological order — always train on the past, validate on the future, expanding the training window each time. Required whenever data has a time component; regular k-fold would leak future information into training.
| Method | How it searches | Pros | Cons |
|---|---|---|---|
| GridSearchCV | Tries every combination in a specified parameter grid | Exhaustive, guaranteed to try the best combo in the grid | Expensive — combinations explode as parameters/values grow |
| RandomizedSearchCV | Samples a fixed number of random combinations from the parameter space | Much cheaper than grid search; often finds near-optimal settings with far fewer trials | Might miss the true best combo; still somewhat inefficient (doesn't learn from past trials) |
| Bayesian Optimization (e.g. Optuna) | Builds a probabilistic model of "which regions look promising," and picks the next trial based on past results | Converges to good hyperparameters in fewer trials — smart, adaptive search | More setup/complexity; less parallelizable than grid/random search (trials depend on prior outcomes) |
from sklearn.model_selection import GridSearchCV from sklearn.ensemble import RandomForestClassifier param_grid = { 'n_estimators': [100, 200, 300], 'max_depth': [None, 5, 10], 'min_samples_split': [2, 5, 10] } grid = GridSearchCV( RandomForestClassifier(random_state=42), param_grid, cv=5, scoring='f1', n_jobs=-1 ) grid.fit(X_train, y_train) print(grid.best_params_) print(grid.best_score_)
objective(trial) function that suggests hyperparameter values (trial.suggest_float, trial.suggest_int), trains/evaluates the model, and returns a score. Optuna's sampler (TPE by default) uses past trial results to intelligently choose the next set of values to try — pruning unpromising trials early to save compute.