【发布时间】:2021-11-26 12:48:45
【问题描述】:
我对模型评估、解释其结果和使用cross_val_score 感到非常困惑。我不明白为什么对测试集的评估通常被认为是最终和可靠的结果,而如果我们只是选择其他拆分,我们将得到一个不同的值,它可能比前一个更差(或更好) .下面,我将用一个例子来说明我在说什么,然后我会问一些更精确的问题。
*我使用了来自Jason Brownlee的数据集:https://github.com/jbrownlee/Datasets/blob/master/pima-indians-diabetes.data.csv
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.csv'
df = pd.read_csv(url, names=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'Target'], header=None)
X, y = df.drop('Target', axis=1), df['Target']
这是我们的目标分布:
X_rest, X_test, y_rest, y_test = train_test_split(X, y, test_size=0.3,
random_state=777, stratify=y)
X_train, X_val, y_train, y_val = train_test_split(X_rest, y_rest, test_size=0.25,
random_state=777, stratify=y_rest)
检查样本的大小:
Train size: 52.3 %
Val size: 17.6 %
Test size: 30.1 %
调整超参数:
base_model = LogisticRegression(random_state=777, max_iter=2000)
params = {
'C': np.arange(0, 5, 0.1)
}
grdSrch = GridSearchCV(base_model, params, scoring='average_precision', cv=5)
grdSrch.fit(X_val, y_val)
print(f'Best params: {grd.best_params_}')
最佳参数:{'C': 2.5}
使用最佳参数训练模型并获得average_precision_score 值:
model = LogisticRegression(C=grdSrch.best_params_['C'], random_state=777, max_iter=2000)
model.fit(X_train, y_train)
y_pred_scores = model.predict_proba(X_test)[:, 1]
print(f'Avg. precision: {average_precision_score(y_test, y_pred_scores)}')
平均精度:0.7067839537770597
现在,我想确保结果不会因为一些出乎意料的好训练/测试拆分而导致不公平。我为此使用cross_val_score:
res_ = cross_val_score(LogisticRegression(C=grd.best_params_['C'], random_state=777, max_iter=2000),
X,
y,
scoring='average_precision',
cv=StratifiedKFold(n_splits=15, shuffle=True))
print(res_)
print()
print(f'Mean score: {np.round(res_.mean(), 4)}')
然后我得到:
[0.7779402 0.69200873 0.63972188 0.82368544 0.6044146 0.70668374
0.85022563 0.79848536 0.60740097 0.68802039 0.92567494 0.84554528
0.61855088 0.78731357 0.79852637]
Mean score: 0.7443
我们在这里看到了什么?我们在这些结果中得到了相当大的差异,加上更高的整体平均值。所以,在这一点上,我完全失去了它。我的问题是:
-
我们能否在整个数据集上使用
cross_val_score来评估我们最终评估结果的公平性(?)?- 如果可以,为什么
train_test_split可以让我们更清楚地了解实际分数,而train_test_split却只使用一个分数? - 如果我们不能,那是什么原因?
- 如果可以,为什么
-
看起来我们实际上没有任何指标的任何“最终”结果,因为我们总是可以根据训练/测试拆分获得一些不同分数的池。那么,在这种情况下,我们如何才能做出真正的商业决策呢?
【问题讨论】:
标签: machine-learning cross-validation train-test-split