Random Forest Classifiers
In the source's run, the selected classifier is an SVC, the selected preprocessing is a StandardScaler, and the selected values are the ones stored under classifier__C and classifier__gamma.
Searching Models and Preprocessing Together
Earlier in a machine learning workflow, a common habit is to tune one model's settings and compare the results by hand. That works, but it answers only one question: which hyperparameter values work best for this model? A more complete approach asks a bigger question: which combination of model, preprocessing step, and hyperparameter values works best? GridSearchCV can answer that bigger question, and this article follows how it does so for a Random Forest Classifier and a competing model.
What do you think happens?
If you are already tuning the C value of a Support Vector Classifier, can the same search also decide whether the input data should be scaled first?
Reveal answer
Yes, the search can treat the preprocessing choice as one more thing to try.
GridSearchCV does not care whether the thing it searches over is a number, a model, or a preprocessing step. It tries each candidate in the grid, evaluates it, and reports which one scored best.
Reading the Parameter Grid
The central object in this workflow is the parameter grid. It is a Python list, and each entry in that list is a dictionary describing one family of candidates. Each dictionary maps a key to a list of values to try. Because each entry is independent, the search never forces one family's settings onto another family's model. The grid is therefore a list of separate small menus rather than one large menu that mixes everything together.
Read the tree from the top. The list has two entries. The first entry is the SVC family: it names the classifier object, a preprocessing choice, and two hyperparameters, gamma and C. The second entry is the RandomForestClassifier family, which names its own classifier object, the same preprocessing choice, and its own hyperparameter. The RandomForestClassifier entry does not receive gamma or C, and the SVC entry does not receive the Random Forest's settings. Each family defines only the keys that apply to its own model.
- The list holds two dictionaries, one per model family.
- The key 'classifier' lists the model objects themselves.
- The key 'preprocessing' lists the preprocessing objects directly, including None for no scaling.
- Keys with a double underscore set a parameter inside a named pipeline step.
The grid above is an illustration written for this article: the SVC values and the StandardScaler-or-None choice follow the source's pattern, while the Random Forest key max_features is a generated example of a family-specific setting. The shape is the lesson, so you can copy the pattern and substitute your own values.
What do you think happens?
In the grid above, can the RandomForestClassifier candidates receive a gamma value?
Reveal answer
No, gamma belongs only to the SVC family.
Each entry defines only the keys that apply to its own model. The two entries are independent, so the search does not combine the Random Forest with the SVC's gamma and C values.
Counting Candidates Before You Run
Before running anything, it helps to know how much work a grid will do. The source's method is to count the candidates in each entry and then add the entries together. Within one entry, the number of candidates is the product of the lengths of its value lists. Across entries, you add those counts. Each candidate is then fitted once per cross-validation fold, so the number of fits is the number of candidates multiplied by the number of folds.
- 1$n_{k,i}$ is the number of values in the list for key i of entry k in the grid.
- 2$\prod_{i} n_{k,i}$ multiplies those list lengths together, giving the number of candidates in entry k.
- 3$\sum_{k=1}^{K}$ adds the candidate counts across all K entries.
- 4$cv$ multiplies the total by the number of cross-validation folds, because each candidate is fitted once per fold.
Counting the fits for the grid above
Using the illustrative grid from earlier, with cv=5, how many model fits does GridSearchCV perform?
- 1Count the SVC entry
The preprocessing list has 2 values, gamma has 4 values, and C has 4 values. The product is 2 times 4 times 4, which is 32 candidates. The classifier list has only one object, so it contributes a factor of 1.
- 2Count the Random Forest entry
The preprocessing list has 2 values and
max_featureshas 2 values. The product is 2 times 2, which is 4 candidates. The classifier list again has one object. - 3Add the entries
Across the two entries, the candidate total is 32 plus 4, which is 36 candidates.
- 4Multiply by the folds
With cv=5, each of the 36 candidates is fitted once per fold, so the total is 36 times 5, which is 180 fits.
The grid evaluates 36 candidates, which means 180 fits across five folds.
How GridSearchCV Visits Candidates
Once the grid is defined, the source runs the search as usual. First, the data is split into training and test sets with train_test_split, using random_state=0 so the split is repeatable. The grid is then built around a pipeline object, which the source calls pipe, and GridSearchCV is asked to use five cross-validation folds. Calling fit runs the whole search on the training data only. The test set is held back until the end.
Read the loop as nested. For each candidate, the search fits and scores it on every fold, and the scores for that candidate are combined. Only after every candidate has been evaluated does the search pick the winner. The winner is the candidate with the best cross-validation score, which the search uses for selection. Notice that the outer loop covers the grid's candidates across all families, so a preprocessing choice and a classifier are tried side by side in one search.
- The pipeline pipe has two named steps, preprocessing and classifier, which the grid keys must match.
- cv=5 asks for five cross-validation folds for every candidate.
- fit runs the whole search on the training data only, and the test set stays untouched.
Reading the Winner and the Two Scores
After fit, three attributes and methods matter. The best_params_ attribute reports the winning combination across both models and the preprocessing step, not just the best hyperparameter value. The best_score_ attribute reports the best cross-validation score from the training data. The score method, called on the held-out test set, reports how the chosen model performs on data the search never saw.
The best parameters come back as a dictionary that includes the winning classifier object, the winning preprocessing object, and the winning hyperparameter values. In the source's run, the selected classifier is an SVC, the selected preprocessing is a StandardScaler, and the selected values are the ones stored under classifier__C and classifier__gamma. Reading this dictionary tells you which branch of the grid won, not only which number was best.
The two scores answer different questions. The best cross-validation score is the score the search used to choose the winner, so it is somewhat optimistic about the chosen model. The test-set score is computed on data that played no part in the search. When the two are close, as in the source's results, that suggests the search did not overfit the cross-validation folds. A large gap between them would be a reason to be cautious about the reported performance.
best_score_ is a selection score computed on training folds. The test-set score is the final check, computed once on rows the search never touched. Report the test-set score as the performance of the chosen model, and use best_score_ to understand what the search optimized.
Mistakes With Grids and Pipelines
Common mistake Assuming a key in one dictionary applies to every model in the list
What it looks likePutting classifier__gamma in the Random Forest entry and expecting it to tune the SVC
Why it failsEach entry is an independent family, and each entry defines only the keys that apply to its own model.
Do this insteadPlace each model's own hyperparameters inside that model's dictionary.
Common mistake Misspelling a step name in the grid
What it looks likeUsing a key such as classifer__C when the pipeline step is named classifier
Why it failsThe grid's key names must match the pipeline's step names exactly.
Do this insteadCopy the step names directly from the pipeline definition.
Common mistake Forgetting that the grid multiplies the fit count
What it looks likeAdding one more value to a preprocessing list inside a large entry and being surprised by a long run
Why it failsThe candidate count is a product within each entry and is repeated for every fold.
Do this insteadCount the candidates and multiply by cv before running the search.
Common mistake Reporting best_score_ as the final performance of the model
Why it failsbest_score_ came from the data the search used to pick the winner, so it is somewhat optimistic.
Do this insteadReport the test-set score as the final check, and compare it with best_score_ to judge overfitting.
Common mistake Running fit on the full dataset before splitting, which lets the test rows influence the search
Trace a Grid by Hand
A grid has two entries. Entry A has a classifier list with 1 object, a preprocessing list with 2 objects, and a C list with 3 values. Entry B has a classifier list with 1 object, a preprocessing list with 2 objects, and a max_features list with 4 values. Using cv=5, how many candidates does the search evaluate, and how many fits does it perform? Then state which key in entry B names a parameter of a pipeline step, and which key names a step itself.
Hints
- Count the candidates in Entry A by multiplying the list lengths, then do the same for Entry B.
- Add the two candidate counts before you multiply by the number of folds.
- A key with a double underscore names a parameter inside a step. A key without one names the step and lists its objects.
Explain, in two or three sentences, why the best cross-validation score and the test-set score are both reported, and what a large gap between them would suggest.
Hints
- Think about which rows were used to choose the winner.
- Think about when the test set is used.
Key Takeaways
- A parameter grid is a list of dictionaries, and each dictionary is one independent family of candidates with its own keys.
- The number of candidates within an entry is the product of its value-list lengths, the entries are added together, and cv multiplies the total number of fits.
- A double underscore names a parameter inside a pipeline step, while a key such as preprocessing names a step and lists its possible objects.
- GridSearchCV fits and scores every candidate on every fold, picks the best mean cross-validation score, and reports the winner through best_params_ and best_score_.
- The test-set score is the final check on untouched data, and a large gap from best_score_ is a warning sign about overfitting the folds.