【问题标题】:Is it fair enough to make model evaluation based on just "train_test_split"?仅基于“train_test_split”进行模型评估是否足够公平?
【发布时间】: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

我们在这里看到了什么?我们在这些结果中得到了相当大的差异,加上更高的整体平均值。所以,在这一点上,我完全失去了它。我的问题是:

  1. 我们能否在整个数据集上使用cross_val_score 来评估我们最终评估结果的公平性(?)?

    • 如果可以,为什么train_test_split 可以让我们更清楚地了解实际分数,而train_test_split 却只使用一个分数?
    • 如果我们不能,那是什么原因?
  2. 看起来我们实际上没有任何指标的任何“最终”结果,因为我们总是可以根据训练/测试拆分获得一些不同分数的池。那么,在这种情况下,我们如何才能做出真正的商业决策呢?

【问题讨论】:

    标签: machine-learning cross-validation train-test-split


    【解决方案1】:

    取决于数据集但最首选的方法,因为它使您的模型有机会在多个训练测试拆分上进行训练。这可以让您更好地了解您的模型在看不见的数据上的表现如何。假设,您进行 10 倍交叉验证,数据集将分为 10 组,模型将单独训练和测试 10 次,因此每个组将有机会成为测试集,但在训练测试拆分中,有一次。 当您有一个非常大的数据集并且您开始在数据科学项目中构建初始模型时,训练测试拆分方法非常适合。请记住,由于交叉验证使用多个训练测试拆分,因此与使用保持方法相比,它需要更多的计算能力和时间来运行。

    【讨论】:

    • 谢谢,我知道交叉验证需要更多资源,但这并不能改变我们的“最终”得分/预测很大程度上取决于 train_test_split 如何拆分整个数据集的情况。我的观点是,如果我们在分裂时足够幸运,那么我们会得到一个结果,但如果我们不小心没有,我们会得到一个完全不同的结果。我的理解正确吗?
    • 是的,如果您有时间紧迫并部署您的项目,那么您应该应用训练测试拆分 .cross_val_score 和 train_test_split 分数有点差异值分数导致交叉验证在整个数据集中应用多次 train_test_split 和需要时间计算。
    • 如果我们使用train_test_split.cross_val_score().mean() 得到不同的价值分数,我们应该选择哪一个作为基础结果来继续改进我们的模型?我的第二个问题是:在做出业务决策时应该选择哪个分数?为什么会这样?
    • 假设如果train test split score 74.5 and cross val score 72 那么你可以应用train test split。如果有很大的差异,这意味着你的数据集没有很好的预处理,清理和特征工程。意味着存在异常值,缺失值等你知道我的意思。顺便说一句,在行业中,大多数人更喜欢火车奶嘴分割用于决策和交叉 val 分数以检查你的模型是否适合。
    • 很多技术,首先在应用于 cross_validation 之前检查偏度和分布。如果分布良好或偏度则继续前进,否则当您预测模型独立特征和依赖特征相关性不好的可能性更高时预测模型应该是完全相关的。
    猜你喜欢
    • 2017-07-25
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多