K-fold 交叉验证查询

Posted

技术标签:

【中文标题】K-fold 交叉验证查询【英文标题】:K-fold Cross Validation Queries 【发布时间】:2019-02-19 05:31:23 【问题描述】:

我正在尝试执行 K-Fold Cross Validation 和 GridSearchCV 来优化我的 Gradient Boost 模型——点击链接—— https://www.analyticsvidhya.com/blog/2016/02/complete-guide-parameter-tuning-gradient-boosting-gbm-python/

我对下面的模型报告截图有几个问题:

1) 0.814365的精度是如何计算的?它在脚本中的哪个位置进行训练测试拆分?如果将 cv_folds=5 更改为 cv_folds=any 整数,那么精度仍然是 0.814365。事实上,删除 cv_folds 并输入 performCV=False 也可以提供相同的精度。

(注意我的 sk learn No CV 80/20 train test 的准确度约为 0.79-0.80)

2) 同样,AUC 分数(训练)是如何计算的?这应该是 ROC-AUC 而不是 AUC 吗?我的 sk learn 模型给出的 AUC 约为 0.87。与准确性一样,这个分数似乎是固定的。

3) 为什么平均 CV 分数比 AUC(训练)分数低这么多?看起来他们都在使用 roc_auc(我的 sklearn 模型为 ROC AUC 提供了 0.77)

df = pd.read_csv("123.csv")

target = 'APPROVED'  #item to predict
IDcol = 'ID'


def modelfit(alg, ddf, predictors, performCV=True, printFeatureImportance=True, cv_folds=5):
    #Fit the algorithm on the data
    alg.fit(ddf[predictors], ddf['APPROVED'])

    #Predict training set:
    ddf_predictions = alg.predict(ddf[predictors])
    ddf_predprob = alg.predict_proba(ddf[predictors])[:,1]

    #Perform cross-validation:
    if performCV:
        cv_score = cross_validation.cross_val_score(alg, ddf[predictors], ddf['APPROVED'], cv=cv_folds, scoring='roc_auc')

    #Print model report:
    print ("\nModel Report")
    print ("Accuracy : %f" % metrics.accuracy_score(ddf['APPROVED'].values, ddf_predictions))
    print ("AUC Score (Train): %f" % metrics.roc_auc_score(ddf['APPROVED'], ddf_predprob))

    if performCV:
        print ("CV Score : Mean - %.5g | Std - %.5g | Min - %.5g | Max - %.5g" % (npy.mean(cv_score),npy.std(cv_score),npy.min(cv_score),npy.max(cv_score)))

    #Print Feature Importance:
    if printFeatureImportance:
        feat_imp = pd.Series(alg.feature_importances_, predictors).sort_values(ascending=False)
        feat_imp.plot(kind='bar', title='Feature Importances')
        plt.ylabel('Feature Importance Score')


#Choose all predictors except target & IDcols
predictors = [x for x in df.columns if x not in [target, IDcol]]
gbm0 = GradientBoostingClassifier(random_state=10)
modelfit(gbm0, df, predictors)

【问题讨论】:

这里发生了很多事情。您是否期望在您的代码中,当您调整 cv_folds 时,accuracy_scoreauc 的计算会随着这些折叠而改变并且不会保持不变? @vealkind 准确性和 auc 是固定的不是问题,但我发现了解它们为何固定以及如何计算它们很有用。主要问题是 CV 分数为何如此之低以及为何如此之低。 【参考方案1】:

您的cv_score 看起来很低的主要原因是因为将其与训练准确度进行比较并不是一个公平的比较。您的训练准确度是使用用于拟合模型的相同数据计算的,而cv_score 是交叉验证中测试折叠的平均分数。正如您可以想象的那样,一个模型将使用它已经训练过的数据进行更好的预测,而不是必须根据模型以前从未见过的新数据进行预测。

您的accuracy_scoreauc 计算似乎是固定的,因为您在计算中始终使用相同的输入(ddf["APPROVED"]ddf_predictionsddf_predprob)。 performCV 部分实际上并不转换任何这些数据集,因此如果您使用相同的模型、模型参数和输入数据,您将获得与计算相同的预测。

根据您的 cmets,cv_score 准确度可能低于您的完整测试集的准确度的原因有很多。主要原因之一是当您使用完整的训练集而不是使用每个 cv 折叠的训练数据子集时,您允许您的模型访问更多数据进行训练。如果您的数据大小不是那么大,则尤其如此。如果您的数据集不大,那么这些数据在训练中更重要,可以提供更好的性能。

【讨论】:

好的,这是有道理的,非常感谢。我有最后一个问题。在 cv_score = cross_validation.cross_val_score(alg, ddf[predictors], ddf['APPROVED'], cv=cv_folds,scoring='roc_auc') 行中,如果我将评分更改为 'accuracy' 而不是 'roc_auc',那么平均 cv_score 在 76 左右。为什么这 5 比原来的准确率低,更重要的是哪个准确率本质上更“正确”? 我想说的是,在我们的 sklearn 80/20 训练测试模型上,我们的测试准确度为 0.8,比 76 cv_score 高出不少。 在不了解您的确切问题的所有细节的情况下,很难提供一个很好的答案。我已经更新了这个答案,解释了为什么您的测试准确性可能高于cv_score

以上是关于K-fold 交叉验证查询的主要内容,如果未能解决你的问题,请参考以下文章

Spark K-fold 交叉验证

在 k-Fold 交叉验证中,是不是为 Sklearn 中的每个折叠启动了一个新模型?

在 CARET k-fold 交叉验证分类中更改 SMOTE 参数

我的 r-squared 得分为负数,但我使用 k-fold 交叉验证的准确度得分约为 92%

R语言编写自定义K折交叉验证(k-fold crossValidation)函数使用使用bootstrap包中的crossval函数来交叉验证模型的R方指标验证模型的效能的可靠性和稳定性

k-fold交叉验证确定k-means中的k?