Hyperparameter Tuning for Logistic Regression
GridSearchCV wraps an estimator, here a Pipeline, and performs a cross-validated grid search over the hyperparameters you specify.
Starting With the Tuning Code
This article starts with code rather than theory. The program below uses a logistic regression model on the cancer dataset, wrapped in a Pipeline and tuned with GridSearchCV. Read it once now, then run it through the trace that accompanies this article and watch what each line does before reading the explanation that follows.
- The first split line divides the cancer data into training and test portions.
- The Pipeline and
param_gridlines are the setup that the source snippet assumes already exists; this version is an illustrative form of them. - GridSearchCV receives the pipe, the
param_grid, and cv=5 folds. - fit is called on X_train and
y_trainonly, not on the full dataset.
The three lines at the centre of the workflow are the split, the construction of the search object, and the call to fit. The search object is built from three ingredients: the pipe, which is the estimator to tune; the param_grid, which lists the hyperparameter values to try; and cv=5, which sets the number of cross-validation folds. The setup above is only illustrative. What matters is the shape of the workflow, not the particular values chosen for C.
What do you think happens?
Before looking at the output, what do you expect grid.best_estimator_ to hold?
Reveal answer
A fitted Pipeline containing the scaler and the classifier with the best settings found
GridSearchCV was given the whole pipeline as its estimator, so the pipeline is the unit being tuned. grid.best_estimator_ returns the whole fitted pipeline with the best settings, not a single number.
Tracing What GridSearchCV Does With the Data
GridSearchCV performs a grid search over the hyperparameters you specify for a given estimator, and it performs cross-validation while doing so. Because the estimator here is a Pipeline, each candidate setting is applied to a model that already includes the data processing step. The scaler and the classifier travel together through every candidate evaluation, so the pipeline is the unit being tuned.
Read the diagram from top to bottom. GridSearchCV hands the training data to the pipeline. The pipeline sends that data through the scaler first, then passes the scaled values to the logistic regression. The score that comes back is what the search uses to compare candidates. The sequence matters: the classifier never sees raw values when the pipeline is doing its job, because the scaler runs before it.
How the Grid Multiplies Into Fits
A grid is a list of candidate values for each hyperparameter, and the search tries them one at a time. In the illustrative grid above, the single hyperparameter C has four candidate values. Each candidate is evaluated with cross-validation, and cv=5 means each candidate is scored across five folds of the training data. The search then keeps the candidate with the best cross-validated result.
Counting the fits in the illustrative grid
The param_grid has four values for C, and GridSearchCV is called with cv=5. How many cross-validation fits does the search perform?
- 1Count the candidates
The grid lists four values of C, so there are four candidate settings.
- 2Count the folds per candidate
cv=5 means each candidate is evaluated on five folds of the training data.
- 3Multiply
Four candidates times five folds gives twenty cross-validation fits for this grid.
Twenty cross-validation fits. Adding more hyperparameter values or more folds multiplies this count.
Reading best_estimator_
After the search has finished, grid.best_estimator_ holds the whole fitted pipeline with the best settings found. The source prints this object to show which configuration won. The printed result is a Pipeline, and its representation lists every step together with the arguments it was built with. Reading that printout is the fastest way to confirm what the search actually selected.
The hierarchy shows where to look. The pipeline is the outer object, and it contains named steps. The tuned value C is not stored on the pipeline itself; it belongs to the logistic regression step, which is why reading the printout and reaching into the individual step are both necessary when you want to check the tuned value.
Reaching Coefficients Through named_steps
Once the search has finished, the logistic regression inside the best pipeline can be reached by its step name. The named_steps attribute of a Pipeline is a dictionary-like view of the steps, keyed by the names you gave them. In the setup above, the classifier was named logreg, so it is retrieved with that key. The coef_ attribute of the logistic regression then holds the fitted coefficients.
- best_estimator_ is the fitted pipeline returned by the search.
named_steps["logreg"] uses the step name given when the Pipeline was built.- coef_ holds the fitted coefficients of the logistic regression step.
Coefficients represent the change in log odds, so they are the quantities you interpret when explaining the model. Note that the coefficients belong to the classifier as it was fitted inside the tuned pipeline, so they reflect the scaled inputs the classifier actually received, not the raw measurements.
Mistakes Beginners Make With the Tuned Pipeline
Common mistake Fitting the search on the full dataset
What it looks likegrid.fit(X, y) instead of grid.fit(X_train, y_train)Why it failsThe test portion is no longer held back, so the later evaluation is no longer clean.
Do this insteadCall fit on X_train and y_train only, and keep the test split for evaluation.
Common mistake Reading coefficients from the original pipe object
What it looks likepipe.named_steps["logreg"].coef_ after the search has run
Why it failsThe pipe object is the estimator that was given to the search, not the tuned result the search returns.
Do this insteadTake the pipeline from grid.best_estimator_ and then use named_steps on that object.
Common mistake Using the wrong step name key
What it looks likenamed_steps["classifier"] when the step was built as "logreg"
Why it failsnamed_stepsis keyed by the names you gave each step, so an unknown key does not find the classifier.Do this insteadCheck the printed best_estimator_ to confirm the exact step names before indexing.
Common mistake Assuming the printed pipeline proves the tuned value without checking it against the param_grid
Name each step in the Pipeline deliberately. Clear step names make the printed best_estimator_ easier to read and make named_steps lookups predictable when you come back to the code later.
Finding Where an Unexpected Result Begins
When a tuned result does not match what you expected, the useful question is where in the workflow the mismatch first appears. An error in an early stage often shows up only later as a strange coefficient or an unexpected winning value. So the method is to walk the stages in order and check the earliest stage that could explain the symptom.
Work through the stages in that order. Begin with the split, then check the construction of the pipe and the param_grid, then the call to fit on the training data, then the printed best_estimator_, and finally the coefficients pulled from named_steps. A symptom seen at the last stage, such as a strange coefficient, may have started at an earlier stage such as a wrong split or a wrong grid.
Practice Tracing a Tuning Run
Suppose the printed best_estimator_ shows a classifier that seems to have an unexpected setting, and the coefficients look odd. Using the workflow stages from this article, name the first stage you would check and explain what you would look for there.
Hints
- Start at the earliest stage, not the coefficients.
- Ask whether the data passed to fit was the training split.
- Check whether the
param_gridcontains the values you intended.
Explain in your own words why the pipeline, rather than the bare logistic regression, is the object GridSearchCV tunes, and say what the scaler does for every candidate setting.
Hints
- Think about what travels together through each candidate evaluation.
- Consider what the classifier receives when the scaler runs first.
Key Takeaways
- GridSearchCV wraps an estimator, here a Pipeline, and performs a cross-validated grid search over the hyperparameters you specify, so the scaler and classifier are tuned together.
- fit is called on the training data only, which keeps the test portion clean for later evaluation.
- grid.best_estimator_ returns the whole fitted pipeline with the best settings found, and its printout confirms what was selected.
named_stepsreaches an individual step by its name, and coef_ on the logistic regression step holds the fitted coefficients, which represent changes in log odds.- When a result looks wrong, check the workflow stage by stage and inspect the earliest stage that could explain the symptom.