Grid search

GridSearchCV on a tiny parameter grid.

GridSearchCV tries every combination of parameters, scores each with cross-validation, and keeps the winner. Keep the grid tiny in this editor.

Goal

Search C on logistic regression and print the best score and params.

A three-value grid

from sklearn.datasets import make_classification
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression

X, y = make_classification(n_samples=200, n_features=4, random_state=0)
grid = GridSearchCV(
    LogisticRegression(max_iter=200),
    param_grid={"C": [0.1, 1, 10]},
    cv=3,
    n_jobs=1,
)
grid.fit(X, y)
print("best C", grid.best_params_)
print("best CV accuracy", round(grid.best_score_, 3))
print(pd.DataFrame(grid.cv_results_)[["param_C", "mean_test_score"]].round(3))

C is inverse regularization: larger C fits train more closely.

Pipeline parameters

from sklearn.datasets import make_classification
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

X, y = make_classification(n_samples=200, n_features=4, random_state=0)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=0
)
pipe = Pipeline(
    [
        ("scale", StandardScaler()),
        ("clf", LogisticRegression(max_iter=200)),
    ]
)
grid = GridSearchCV(
    pipe,
    param_grid={"clf__C": [0.1, 1, 10]},
    cv=3,
    n_jobs=1,
)
grid.fit(X_train, y_train)
print("best", grid.best_params_, "CV", round(grid.best_score_, 3))
print("test accuracy", round(accuracy_score(y_test, grid.predict(X_test)), 3))

Nested names use a double underscore: clf__C is C on the step named clf. Score the test set only after search finishes.

Pitfall

A grid of 20 values × 5 folds × a forest of 200 trees will hang this tab. Stay at a few combinations and cv=3.