为啥交叉验证的性能比测试差?

Posted

技术标签:

【中文标题】为啥交叉验证的性能比测试差?【英文标题】:Why Cross Validation performs poorer than testing?为什么交叉验证的性能比测试差? 【发布时间】:2019-11-09 16:37:14 【问题描述】:

在以下代码中,我使用 X_test(特征)和 y_test(标签)数据拟合 LogisticRegressionCV 模型。

然后,使用我应用cross_val_predict 10 倍的模型来评估使用 CV 的性能。我计算了两种不同的AUC 分数,一种使用roc_auc_score 方法进行预测,另一种使用auc 方法进行概率。

#CV LOGISTIC REGRESSION
classifier = linear_model.LogisticRegressionCV(penalty='l1',class_weight='balanced', tol=0.01, Cs=[0.1],
                                               max_iter=4000, solver='liblinear', random_state = 42, cv=10) 
classifier.fit(X_test, y_test);

predicted = sklearn.model_selection.cross_val_predict(classifier, X_test, y_test, cv=10)     
print ("AUC1:".format(sklearn.metrics.roc_auc_score(y_test, predicted)))#np.average(scores)))

probas_ = sklearn.model_selection.cross_val_predict(classifier, X_test, y_test, cv=10, method='predict_proba')
fpr, tpr, thresholds = sklearn.metrics.roc_curve(y_test, probas_[:, 1])
roc_auc = sklearn.metrics.auc(fpr, tpr)
print ("AUC2  :".format(roc_auc))

AUC 分数分别为 0.624 和 0.654。

然后,我这次使用GridSearchCV 构建另一个 LogisticRegression 模型。该模型使用相同的训练数据(在 CV 中使用)进行训练,但这次它预测的是测试数据:

## GRIDSEARCHCV LOGISTIC REGRESSION   
param_grid='C': np.logspace(-2, 2, 40)

# Create grid search object
clf = sklearn.model_selection.GridSearchCV(linear_model.LogisticRegression(penalty='l1', 
                                                                           class_weight='balanced',
                                                                           solver = 'liblinear',
                                                                           max_iter=4000, 
                                                                           random_state = 42), 
                                           param_grid = param_grid, 
                                           cv = 5, 
                                           scoring = 'roc_auc', 
                                           verbose=True,
                                           n_jobs=-1)    
best_clf = clf.fit(X_train, y_train)  
predicted = best_clf.predict(X_test)     
print ("AUC1:".format(best_clf.best_score_))

probas_ = best_clf.predict_proba(X_test)   
fpr, tpr, thresholds = sklearn.metrics.roc_curve(y_test, probas_[:, 1])
roc_auc = sklearn.metrics.auc(fpr, tpr)
print ("AUC2  :".format(roc_auc))

这次的 AUC 分数分别为 0.603 和 0.688。

也就是说,根据使用的 AUC 分数,一个优于另一个。 This post 推荐我在这里报告的第二个 AUC 分数。但是,我现在做的是,尽管使用相同的数据对 CV 进行了训练和测试,但它的表现会更差。

有什么想法吗?你认为这正常吗(如果是,为什么)?另外,我想知道我的代码是否看起来不错。感谢您的建议。

【问题讨论】:

【参考方案1】:

好吧,我认为您需要为 CV 使用训练数据而不是测试数据。 您的第一个模型(LGR 分类器)适合 X_test,y_test,您的交叉验证模型('预测)也是如此。

由于测试数据集的实例或数据行数通常少于训练数据集,因此可能只是由于数据量较小,模型拟合不足。

尽量在训练集上做所有这些,测试集通常只用于预测,拟合测试集否认了在未拟合(看不见)数据上检查模型性能的意义。

祝你好运~

【讨论】:

以上是关于为啥交叉验证的性能比测试差?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的交叉验证始终比训练测试分割表现更好?

为啥我们需要在 multiSVM 方法中进行交叉验证来进行图像分类?

为啥 10 倍交叉验证的准确度得分比使用 sklearn 的 90-10 train_test_split 最差?

机器学习系列(二十四)——交叉验证与偏方差权衡

为啥我的交叉验证错误分类错误率与测试数据集成功率相矛盾

5倍交叉验证如何理解