Concepts / Random Forest Classifiers

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.

  • Programming

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?

  • No, preprocessing has to be chosen by hand before the search starts

  • Yes, the search can treat the preprocessing choice as one more thing to try

Reveal answer
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.

Parameter grid(list)Entry 1: SVC familyclassifier: SVC()Entry 2:RandomForestClassifierfamilypreprocessing:StandardScaler(),Noneclassifier__gamma:list of valuesclassifier__C: listof valuesclassifier:RandomForestClassifier()preprocessing:StandardScaler(),Noneclassifier__max_features:list of valuesentry 1entry 2
Which keys belong to which family? Each dictionary in the list is one family, and the keys inside it apply only to that family's model.

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.

python
Notes on the code
  • 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?

  • Yes, every key is shared across all entries

  • No, gamma belongs only to the SVC family

Reveal answer
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.

Rule

Formula, step by step
  1. 1
    $n_{k,i}$ is the number of values in the list for key i of entry k in the grid.
  2. 2
    $\prod_{i} n_{k,i}$ multiplies those list lengths together, giving the number of candidates in entry k.
  3. 3
    $\sum_{k=1}^{K}$ adds the candidate counts across all K entries.
  4. 4
    $cv$ multiplies the total by the number of cross-validation folds, because each candidate is fitted once per fold.
Worked example

Counting the fits for the grid above

Using the illustrative grid from earlier, with cv=5, how many model fits does GridSearchCV perform?

  1. 1
    Count 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.

  2. 2
    Count the Random Forest entry

    The preprocessing list has 2 values and max_features has 2 values. The product is 2 times 2, which is 4 candidates. The classifier list again has one object.

  3. 3
    Add the entries

    Across the two entries, the candidate total is 32 plus 4, which is 36 candidates.

  4. 4
    Multiply 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.

Result

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.

Next candidateFit on training partof foldScore on held-outpart of foldAll folds done?Average the foldscoresAll candidates done?Pick highest meanscoreno, next foldyesno, next candidateyes
In what order does GridSearchCV visit each candidate and each fold, and when does it choose the winner?

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.

python
Notes on the code
  • 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.

Full datasetTraining setTest setCross-validationfolds on training setbest_score_Score on test settrain_test_splitheld backused by searchselectionused once at the end
Which rows of data are used for the best CV score, and at what point is the untouched test set used to report the final score?

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.

Key point

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 like

    Putting classifier__gamma in the Random Forest entry and expecting it to tune the SVC

    Why it fails

    Each entry is an independent family, and each entry defines only the keys that apply to its own model.

    Do this instead

    Place each model's own hyperparameters inside that model's dictionary.

  • Common mistake

    Misspelling a step name in the grid

    What it looks like

    Using a key such as classifer__C when the pipeline step is named classifier

    Why it fails

    The grid's key names must match the pipeline's step names exactly.

    Do this instead

    Copy the step names directly from the pipeline definition.

  • Common mistake

    Forgetting that the grid multiplies the fit count

    What it looks like

    Adding one more value to a preprocessing list inside a large entry and being surprised by a long run

    Why it fails

    The candidate count is a product within each entry and is repeated for every fold.

    Do this instead

    Count the candidates and multiply by cv before running the search.

  • Common mistake

    Reporting best_score_ as the final performance of the model

    Why it fails

    best_score_ came from the data the search used to pick the winner, so it is somewhat optimistic.

    Do this instead

    Report 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

MEDIUM

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.
EASY

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.

Related concepts

More concepts starting with R