使用最佳参数构建模型时 GridsearchCV 最佳分数下降

Posted

技术标签:

【中文标题】使用最佳参数构建模型时 GridsearchCV 最佳分数下降【英文标题】:GridsearchCV best score drop when using the best parameters to build model 【发布时间】:2019-07-24 11:49:10 【问题描述】:

我正在尝试使用 Grid Search CV 为我的逻辑回归估计器找到一组最佳超参数,并使用管道构建模型:

我的问题是在尝试使用我通过的最佳参数时 grid_search.best_params_建立Logistic Regression模型,准确率和我得到的不一样

grid_search.best_score_ 

这是我的代码

x=tweet["cleaned"]
y=tweet['tag']

X_train, X_test, Y_train, Y_test = model_selection.train_test_split(x, y, test_size=.20, random_state=42)

pipeline = Pipeline([
('vectorizer',TfidfVectorizer()),
('chi', SelectKBest()),
('classifier', LogisticRegression())])

grid = 
'vectorizer__ngram_range': [(1, 1), (1, 2),(1, 3)],
'vectorizer__stop_words': [None, 'english'],
'vectorizer__norm': ('l1', 'l2'),
'vectorizer__use_idf':(True, False), 
'vectorizer__analyzer':('word', 'char', 'char_wb'),
'classifier__penalty': ['l1', 'l2'],
'classifier__C': [1.0, 0.8],
'classifier__class_weight': [None, 'balanced'],
'classifier__n_jobs': [-1],
'classifier__fit_intercept':(True, False),


grid_search = GridSearchCV(pipeline, param_grid=grid, scoring='accuracy', n_jobs=-1, cv=10)
grid_search.fit(X_train,Y_train)

当我得到最好的成绩和使用婴儿车时

print(grid_search.best_score_)
print(grid_search.best_params_)

结果是

0.7165160230073953 
'classifier__C': 1.0, 'classifier__class_weight': None, 'classifier__fit_intercept': True, 'classifier__n_jobs': -1, 'classifier__penalty': 'l1', 'vectorizer__analyzer': 'word', 'vectorizer__ngram_range': (1, 1), 'vectorizer__norm': 'l2', 'vectorizer__stop_words': None, 'vectorizer__use_idf': False

现在如果我使用这些参数来构建我的模型

pipeline = Pipeline([
('vectorizer',TfidfVectorizer(ngram_range=(1, 1),stop_words=None,norm='l2',use_idf= False,analyzer='word')),
('chi', SelectKBest(chi2,k=1000)),
('classifier', LogisticRegression(C=1.0,class_weight=None,fit_intercept=True,n_jobs=-1,penalty='l1'))])

 model=pipeline.fit(X_train,Y_train) 
 print(accuracy_score(Y_test, model.predict(X_test)))

结果下降到 0.68。

另外,这是一项繁琐的工作,所以我怎样才能将最佳参数传递给模型。我不知道该怎么做(answer),因为我的方式与他略有不同。

【问题讨论】:

refit=True 允许您使用带有 cv_grid 变量的最佳模型。 cv_grid.predict 【参考方案1】:

您在第二个选项中的得分较低的原因是您正在测试集上评估您的管道模型,而您正在使用交叉验证评估您的网格搜索模型(在您的情况下,10 倍分层交叉验证)。这个交叉验证分数是 10 个模型的平均值,每个模型都适合 9/10 的训练数据,并在最后 1/10 的训练数据上进行评估。因此,您不能期望两次评估获得相同的分数。

至于你的第二个问题,你为什么不能做 grid_search.best_estimator_ ?这会从您的网格搜索中获取最佳模型,您可以评估它而无需从头开始重建它。例如:

best_model = grid_search.best_estimator_
best_model.score(X_test, Y_test)

【讨论】:

“小下”部分不准确;正如您正确指出的那样,这些是统计量,当然不会相等,但“小低”部分实际上并不成立。如果您编辑此部分,很高兴为您投票(即只关注为什么不应期望它们相等)... @desertnaut 感谢您指出这一点,它在实践中经常被观察到,但我的措辞使它看起来像是一个断言,但事实并非如此。我只是对其进行了编辑以减少误导【参考方案2】:

我将逻辑回归和 MLPClassifier 都放在了每个分类器之间切换的管道中。我使用 GridSearchCV 来找到分类器之间的最佳参数。我调整了参数,然后为数据选择了最准确的分类器。原来 MLPClassifier 更准确,但在调整逻辑回归的 C 值后,它变得更准确了。

X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.4,random_state=42)

pipeline= Pipeline([
     ('scaler',StandardScaler()),
     #('pca', PCA()),
     ('clf',LogisticRegression(C=5,max_iter=10000, tol=0.1)),
     #('clf',MLPClassifier(hidden_layer_sizes=(25,150,25),  max_iter=800, solver='lbfgs', activation='relu', alpha=0.7, 
     #                 learning_rate_init=0.001,  verbose=False, momentum=0.9, random_state=42))
     ])

 pipeline.fit(X_train,y_train)

 parameter_grid='C':np.linspace(5,100,5)

 grid_rf_class=GridSearchCV(
      estimator=pipeline['clf'],
      param_grid=parameter_grid,
      scoring='roc_auc',
      n_jobs=2,
      cv=5,
      refit=True,
      return_train_score=True)

 grid_rf_class.fit(X_train,y_train)
 predictions=grid_rf_class.predict(X_test)

 print(accuracy_score(y_test,predictions));
 print(grid_rf_class.best_params_)
 print(grid_rf_class.best_score_)

【讨论】:

以上是关于使用最佳参数构建模型时 GridsearchCV 最佳分数下降的主要内容,如果未能解决你的问题,请参考以下文章

拟合 sklearn GridSearchCV 模型

如何确定 GridSearchCV 中每个评分指标的最佳参数和最佳分数

ValueError 在 Scikit 中找到最佳超参数时使用 GridSearchCV 学习 LogisticRegression

如何使用GridSearchCV获取所有模型(每组参数一个)?

GridSearchCV 的替代方法,用于查找 SVM 模型的参数

测试准确度分数高于 GridSearchCV 中的最佳分数