title: Why do I need to fit a GridSearchCV object to the data before I can get the best parameters and model?
body: <p>My question is similar to the one <a href="https://stackoverflow.com/questions/60786220/attributeerror-gridsearchcv-object-has-no-attribute-best-params">here</a>, but the answer there does not explain <em>why</em> we must fit to the data before getting the best paramters, it just states that we must. In my understanding, GridSeachCV picks the best model parameters using cross validation, and then returns this best model in the <code>.best_estimator</code> attribute. Then we can fit the that model to our data. But shouldn't we be able to access the parameters it picked and the <code>.best_estimator</code> model before fitting to the data?</p>
  <p>As an example, the code below works fine:</p>
  <pre><code>logreg = LogisticRegression(solver='liblinear')  
  params = {'penalty':['l1','l2'], 'C':np.logspace(-3,3,7),}
  grid = GridSearchCV(estimator=logreg, params, cv=4)                                                                                                                                                   
  grid.fit(X_train,y_train)  
  best_model_params = grid.best_params_
  y_pred = grid.predict(X_test)
  </code></pre>
  <p>But the following code does not work:</p>
  <pre><code>logreg = LogisticRegression(solver='liblinear')  
  params = {'penalty':['l1','l2'], 'C':np.logspace(-3,3,7),}
  grid = GridSearchCV(estimator=logreg, params, cv=4)                                                                                                                                                   
  best_model_params = grid.best_params_
  grid.fit(X_train,y_train)  
  y_pred = grid.predict(X_test)
  </code></pre>
  <p>It gives <code>AttributeError: 'GridSearchCV' object has no attribute 'best_estimator_'</code>.</p>
  <p>On a related note, if <code>grid.best_estimator_</code> is the best LogisticRegression model (the model with the set of hyperparameters found to be best through cross validation in GridSearchCV) then why do we fit the <code>grid</code> object instead of the <code>grid.best_estimator_</code> object? E.g. if I could figure out how to access the <code>best_estimator</code> attribute before fitting, would the following code work?:</p>
  <pre><code>logreg = LogisticRegression(solver='liblinear')  
  params = {'penalty':['l1','l2'], 'C':np.logspace(-3,3,7),}
  grid = GridSearchCV(estimator=logreg, params, cv=4)                                                                                                                                                   
  best_model = &lt;somehow get the model GridSearchCV has picked&gt;
  best_model.fit(X_train,y_train)  
  y_pred = best_model.predict(X_test)
  </code></pre>