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

时间:2019-03-02 18:29:30

标签: machine-learning scikit-learn pipeline grid-search

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

我的问题是,当尝试使用获得的最佳参数时 grid_search.best_params_构建Logistic回归模型,其准确性与我所得到的准确性不同

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)。

2 个答案:

答案 0 :(得分:3)

在第二个选项中得分较低的原因是,您正在评估测试集上的管道模型,而您正在使用交叉验证(在您的情况下为10倍分层交叉验证)。此交叉验证分数是根据火车数据的9/10分别拟合并在该火车数据的最后1/10上进行评估的10个模型的平均值。因此,您不能期望两次评估都得到相同的分数。

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

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

答案 1 :(得分:0)

我将 Logistic 回归和 MLPClassifier 放在每个分类器之间的管道切换中。我使用 GridSearchCV 来找到分类器之间的最佳参数。我调整了参数,然后为数据选择了最准确的分类器。原本MLPClassifier更准确,但在为logistic回归调整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_)