对于二进制分类问题,使用5倍cv的手动实现,我计算了每个验证折叠的AUC(使用每个折叠的预测概率),并得到了0.870, 0.854, 0.886, 0.940, 0.921
的分数。然后,我使用所有预测的概率来计算AUC,但得到的AUC为0.756
。通过使用cross_val_score
和cross_val_predict
的sklearn的实现,我得到了类似的结果。
为什么会这样?一组预测概率(例如在第一个验证倍数中)如何为我提供较高的验证倍数AUC,但是与其他预测概率结合使用时,我的总AUC却较低?
这似乎与here问的一个问题有关,为什么不宜使用cross_validate_predict
的预测来计算指标,但是(下面)对已接受答案的解释并没有帮助我困惑AUC分数会如何变化:
cross_val_score似乎说它在所有折痕上取平均值,而cross_val_predict将单个折痕和不同的模型(而不是全部)分组,因此也不一定能一概而论
有关我用来获得这些结果的代码,请参见下文。
手动实施:
splitter = StratifiedKFold(n_splits = 5, shuffle = False)
predictions = pd.DataFrame({'actuals': y, 'probabilities': 0})
for i, (train_index, validate_index) in enumerate(splitter.split(X, y)):
X_train, y_train, X_validate, y_validate = X.iloc[train_index], y.iloc[train_index], X.iloc[validate_index], y.iloc[validate_index]
classifier.fit(X_train, y_train)
probs = model.predict_proba(X_validate)[:,1]
print(roc_auc_score(y_validate, probs))
out = pd.DataFrame({'probabilities': probs}, index = X.index[validate_index])
predictions.update(out)
auc = roc_auc_score(y_true = predictions.actuals.values, y_score = predictions.probabilities.values)
print(auc)
Sci-kit实现:
scores = cross_val_score(classifier, X, y, scoring = 'roc_auc', cv = splitter)
np.mean(scores)
predictions = cross_val_predict(classifier, X, y, method = 'predict_proba', cv = splitter)
roc_auc_score(y, predictions[:,1])
所以人们可以继续研究,我也尝试使用具有logistic回归的乳腺癌数据集来重现这种差异,但是请注意,我无法使用如此简单的数据集来产生差异。
import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_val_score, cross_val_predict
from sklearn.metrics import roc_auc_score
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns = data.feature_names)
y = pd.Series(data.target)
classifier = LogisticRegression()
splitter = StratifiedKFold(n_splits = 5, shuffle = False)
scores = cross_val_score(classifier, X, y, scoring = 'roc_auc', cv = splitter)
scores
predictions = cross_val_predict(classifier, X, y, method = 'predict_proba', cv = splitter)
roc_auc_score(y, predictions[:,1])