cross_validate得到的auc和RocCurveDisplay的值不同

问题描述 投票:0回答:1

在训练随机森林分类器后,我尝试了两种计算 AUC 分数的方法。第一个是从 cross_validate 函数获取指标:

numeric_transformer = make_pipeline(
    IterativeImputer(estimator=RandomForestRegressor(),random_state=0),
    StandardScaler()
)
preprocessor = make_column_transformer(
    (numeric_transformer, numeric_cols)
)


pipe = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('clf', RandomForestClassifier())
])

scoring = {
    'AUC': 'roc_auc', 
    'ACCURACY': 'accuracy',
    'F1_SCORE': 'f1',
    'PRECISION': 'precision',
    'RECALL': 'recall'
}
print(scoring)

cv = StratifiedKFold(n_splits=5)
cv_scores_RF = cross_validate(pipe, X, y, cv=cv, scoring=scoring, return_estimator=True)

print("Random forest metrics")
print(f"AUC: {abs(cv_scores_RF['test_AUC']).mean()}")
print(f"ACCURACY: {cv_scores_RF['test_ACCURACY'].mean()}")
print(f"F1 SCORE: {abs(cv_scores_RF['test_F1_SCORE']).mean()}")
print(f"PRECISION: {abs(cv_scores_RF['test_PRECISION']).mean()}")
print(f"RECALL: {abs(cv_scores_RF['test_RECALL']).mean()}")

通过上面的代码,我获得了 0.72 的 AUC。

然后我用函数 RocCurveDisplay 绘制了 ROC 曲线:

import matplotlib.pyplot as plt
from sklearn.metrics import RocCurveDisplay


plt.figure(figsize=(8, 6))


tprs = []
aucs = []


for i, estimator in enumerate(cv_scores_RF['estimator']):
    viz = RocCurveDisplay.from_estimator(estimator, X, y, ax=plt.gca(), name=f'ROC fold {i+1}')
    
    roc_auc = auc(viz.fpr, viz.tpr)
    aucs.append(roc_auc)

    interp_tpr = np.interp(mean_fpr, viz.fpr, viz.tpr)
    interp_tpr[0] = 0.0
    tprs.append(interp_tpr)

mean_tpr = np.mean(tprs, axis=0)
mean_auc = np.mean(aucs)

plt.plot(mean_fpr, mean_tpr, color='b', linestyle='--', lw=2, label=f'Mean ROC (AUC = {mean_auc:.2f})')

plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC) - RF')
plt.legend(loc='lower right')

plt.show()

print(f"Mean AUC: {mean_auc:.2f}")

但是绘制曲线,我在图中得到的 AUC 是 0.97。为什么会出现这种情况?

我期望得到类似的值,例如我将分类器更改为 SVM,也得到了不同的值。从 cross_validate 获得的指标中,我得到了 0.53 AUC,但从 RocCurveDisplay 中得到了 0.71。还尝试使用朴素贝叶斯,在这种情况下,我得到了非常相似的值,分别为 0.66 和 0.68。

python machine-learning random-forest cross-validation roc
1个回答
0
投票

主要问题是你的第二种方法计算整个数据集上每个折叠模型的 AUC:

    viz = RocCurveDisplay.from_estimator(estimator, X, y, ax=plt.gca(), name=f'ROC fold {i+1}')

由于这包括模型训练所用的数据折叠,因此分数存在乐观偏差。

© www.soinside.com 2019 - 2024. All rights reserved.