Grid search in scikit-learn compares a fixed set of hyperparameter combinations by fitting the estimator repeatedly through cross-validation. It suits small search spaces where every candidate should be scored instead of sampled, such as choosing a few SVC values before training a final classifier.
GridSearchCV wraps the estimator and behaves like the selected estimator after fitting. Parameter names follow the estimator path, so a pipeline step named svc accepts grid keys such as svc__C and svc__gamma.
A compact breast cancer classification run keeps the grid intentionally small and holds back a separate test split. Cross-validation chooses the best parameter combination on the training rows, and the held-out score checks that the refitted estimator still predicts unseen rows after the search.
Steps to run grid search with scikit-learn:
- Save the grid-search script as run_grid_search.py.
- run_grid_search.py
import sklearn from sklearn.datasets import load_breast_cancer from sklearn.metrics import accuracy_score from sklearn.model_selection import GridSearchCV, StratifiedKFold, train_test_split from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC X, y = load_breast_cancer(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.25, stratify=y, random_state=42, ) model = make_pipeline( StandardScaler(), SVC(), ) param_grid = { "svc__C": [0.1, 1, 10], "svc__gamma": ["scale", 0.01], "svc__kernel": ["rbf"], } cv = StratifiedKFold( n_splits=5, shuffle=True, random_state=42, ) search = GridSearchCV( model, param_grid=param_grid, scoring="accuracy", cv=cv, refit=True, ) search.fit(X_train, y_train) candidate_count = len(search.cv_results_["params"]) test_predictions = search.predict(X_test) held_out_accuracy = accuracy_score(y_test, test_predictions) print(f"scikit-learn {sklearn.__version__}") print(f"scoring: {search.scoring}") print(f"cross-validation folds: {search.n_splits_}") print(f"evaluated candidates: {candidate_count}") print(f"total fits: {candidate_count * search.n_splits_}") print(f"best parameters: {search.best_params_}") print(f"best mean CV accuracy: {search.best_score_:.3f}") print(f"held-out accuracy: {held_out_accuracy:.3f}") print("top candidates:") ranked_candidates = sorted( zip( search.cv_results_["rank_test_score"], search.cv_results_["mean_test_score"], search.cv_results_["params"], ), key=lambda item: item[0], ) for rank, mean_score, params in ranked_candidates[:3]: print(f" rank {rank}: mean={mean_score:.3f}, params={params}")
The parameter grid has three C values, two gamma values, and one kernel value. GridSearchCV evaluates their cross-product, so this run has six candidate settings before cross-validation expands them across folds.
- Run the script from a Python environment that has scikit-learn installed.
$ python run_grid_search.py scikit-learn 1.9.0 scoring: accuracy cross-validation folds: 5 evaluated candidates: 6 total fits: 30 best parameters: {'svc__C': 10, 'svc__gamma': 0.01, 'svc__kernel': 'rbf'} best mean CV accuracy: 0.972 held-out accuracy: 0.979 top candidates: rank 1: mean=0.972, params={'svc__C': 10, 'svc__gamma': 0.01, 'svc__kernel': 'rbf'} rank 2: mean=0.970, params={'svc__C': 10, 'svc__gamma': 'scale', 'svc__kernel': 'rbf'} rank 3: mean=0.967, params={'svc__C': 1, 'svc__gamma': 'scale', 'svc__kernel': 'rbf'} - Check the evaluated candidate and total fit counts.
The output shows six candidates and thirty total fits because each candidate is evaluated across five cross-validation folds.
- Check the best parameter set before keeping the model.
The output selects svc__C=10, svc__gamma=0.01, and svc__kernel=rbf for the configured accuracy scorer. The top-candidate rows show how close the next two settings were.
- Check the held-out score before reusing the refitted estimator.
refit=True retrains the best candidate on the full training split, so search.predict(X_test) uses the selected pipeline. The held-out accuracy line checks that the refitted estimator can score rows outside the grid-search folds.
- Replace the sample grid with project-specific values after the smoke test works.
param_grid = { "svc__C": [0.5, 1, 2], "svc__gamma": ["scale", 0.05], "svc__kernel": ["rbf"], }
Keep the grid bounded. Each extra candidate is evaluated once per fold, so small-looking grid additions can multiply the fit count quickly.
- Remove the smoke-test script if it is not part of the project.
$ rm run_grid_search.py
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.