迭代许多随机训练和测试集拆分直到达到高精度是不好的做法吗?



假设我使用以下代码进行迭代,直到获得我满意的准确性:

from sklearn.model_selection import train_test_split
x, y = # ... read in some data set ...
c = 3000 # iterate over some arbitrary range
for i in range(c):
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=i)
model = # ... initialize some classifier of choice ...
model.fit(x_train, y_train)
p = model.predict(x_test)
p = np.round(p).reshape(-1)
test_accuracy = np.mean(p == y_test) * 100

对于特定的数据集和范围,比如说我构建了一个分类器,使训练准确率为97%,测试准确率为96%。我真的能声称这个模型准确率为96%吗?对于相同的范围和数据集,我还可以构建一个分类器,使训练准确率和测试准确率分别低至99%和70%。

既然我根据测试集的准确性选择了random_state,那么测试集在这里真的是验证集吗?我不知道为什么,但我认为声称第一个模型的准确率为96%是不正确的。相反,我应该怎么做才能对模型的准确性做出正确的声明?

迭代许多随机训练&测试集分裂,直到达到高精度?

是的,这是不好的做法。您应该根据从未对模型进行过训练的数据进行评估,如果您多次训练以找到最佳训练/测试划分,情况就不会如此。

在训练模型之前,你可以先放一个测试集。然后,您可以创建任意数量的训练/验证拆分,并多次训练模型。您将在测试集上进行评估,而模型从未在该测试集上训练过。

您还可以查看嵌套的交叉验证。

Kinda。交叉验证与您所描述的内容类似。这就是训练/测试划分是随机的,每次都训练模型。除了引用的最终值是平均测试精度,而不仅仅是最好的。这类事情是在棘手的情况下完成的,例如使用非常小的数据集。

从大局来看,测试数据应该代表训练数据,反之亦然。当然,你可以这样做,但如果非典型的"奇怪"案例隐藏在你的训练集中,而测试集中充满了简单的案例(例如,MNIST只有数字0(,那么你就没有真正取得任何成就。你只是在欺骗自己。

最新更新