特征选择应该在训练测试分割之前还是之后进行?

2024-01-08

实际上,这个问题的可能答案有两个事实是矛盾的:

  1. 传统的答案是在分割之后进行,因为如果之前进行的话,可能会从测试集中泄漏信息。

  2. 矛盾的答案是,如果仅使用从整个数据集中选择的训练集进行特征选择,则特征选择或特征重要性得分顺序可能会随着 Train_Test_Split 的 random_state 的变化而动态变化。如果任何特定工作的特征选择发生变化,则无法进行特征重要性的概括,这是不可取的。其次,如果仅使用训练集进行特征选择,则测试集可能包含某些实例集,这些实例集违背/矛盾仅在训练集上进行的特征选择,因为未分析整体历史数据。此外,只有在给定一组实例而不是单个测试/未知实例时才能评估特征重要性分数。


其实并不难证明为什么使用整个数据集(即在分割训练/测试之前)来选择特征可能会让您误入歧途。下面是一个使用 Python 和 scikit-learn 的随机虚拟数据的演示:

import numpy as np
from sklearn.feature_selection import SelectKBest
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# random data:
X = np.random.randn(500, 10000)
y = np.random.choice(2, size=500)

由于我们的数据X是随机的(500 个样本,10,000 个特征)和我们的标签y是二进制的,我们期望永远不能超过这种设置的基线精度,即 ~ 0.5,或大约 50%。让我们看看当我们应用时会发生什么wrong在分割之前使用整个数据集进行特征选择的过程:

selector = SelectKBest(k=25)
# first select features
X_selected = selector.fit_transform(X,y)
# then split
X_selected_train, X_selected_test, y_train, y_test = train_test_split(X_selected, y, test_size=0.25, random_state=42)

# fit a simple logistic regression
lr = LogisticRegression()
lr.fit(X_selected_train,y_train)

# predict on the test set and get the test accuracy:
y_pred = lr.predict(X_selected_test)
accuracy_score(y_test, y_pred)
# 0.76000000000000001

哇!我们得到76% test二进制问题的准确率,根据基本的统计定律,我们应该得到非常接近 50% 的结果!有人打电话给诺贝尔奖委员会,并且fast...

...当然,事实是我们能够获得这样的测试精度只是因为我们犯了一个非常基本的错误:我们错误地think我们的测试数据是看不见的,但实际上测试数据在特征选择过程中已经被模型构建过程看到了,特别是在这里:

X_selected = selector.fit_transform(X,y)

How 境况不佳我们可以在现实中吗?嗯,不难看出:假设,在我们完成模型之后,我们有deployed它(期望在实践中使用新的未见过的数据达到 76% 的准确率),我们得到了一些really新数据:

X_new = np.random.randn(500, 10000)

当然,没有任何质的变化,即新趋势或任何东西——这些新数据是由完全相同的基本程序生成的。假设我们碰巧知道真正的标签y,如上生成:

y_new = np.random.choice(2, size=500)

当面对这些真正看不见的数据时,我们的模型将如何表现?不难检查:

# select the same features in the new data
X_new_selected = selector.transform(X_new)
# predict and get the accuracy:
y_new_pred = lr.predict(X_new_selected)
accuracy_score(y_new, y_new_pred)
# 0.45200000000000001

嗯,确实如此:我们将模型投入战斗,认为它的准确率约为 76%,但实际上它的表现只是随机猜测......


那么,现在让我们看看correct过程(即首先拆分,然后根据training仅设置):

# split first
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
# then select features using the training set only
selector = SelectKBest(k=25)
X_train_selected = selector.fit_transform(X_train,y_train)

# fit again a simple logistic regression
lr.fit(X_train_selected,y_train)
# select the same features on the test set, predict, and get the test accuracy:
X_test_selected = selector.transform(X_test)
y_pred = lr.predict(X_test_selected)
accuracy_score(y_test, y_pred)
# 0.52800000000000002

在这种情况下,测试精度 0f 0.528 足够接近理论上预测的 0.5(即实际上随机猜测)。

感谢 Jacob Schreiber 提供了简单的想法(检查所有thread https://twitter.com/jmschreiber91/status/1137464236156702720,它包含其他有用的示例),尽管与您在此处询问的情况略有不同(交叉验证):

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

特征选择应该在训练测试分割之前还是之后进行? 的相关文章

  • 如何重现 Ridge(normalize=True) 的行为?

    这段代码 from sklearn pipeline import make pipeline from sklearn preprocessing import StandardScaler from sklearn linear mod
  • libsvm 收缩启发法

    我在 C SVC 模式下使用 libsvm 和 2 次多项式内核 并且需要训练多个 SVM 在训练期间 我训练的一些 SVM 会收到以下一个或什至两个警告 WARNING using h 0 may be faster WARNING re
  • 在 Keras 中连接两个目录迭代器

    假设我有类似以下内容 image data generator ImageDataGenerator rescale 1 255 train generator image data generator flow from director
  • rpart 决策树中的 rel 误差和 x 误差有什么区别? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有一个来自 UCI 机器学习数据库的纯分类数据框https archive ics uci edu ml datasets Diabet
  • 使用 scikit-learn 进行二次采样 + 分类

    我正在使用 Scikit learn 进行二元分类任务 并且我有 0 级 有 200 个观察值 第 1 类 有 50 个观察值 而且因为我有不平衡的数据 我想抽取多数类的随机子样本 其中观察数量与少数类相同 并且希望使用新获得的数据集作为分
  • 如何加速 svm.predict?

    我正在编写一个滑动窗口来提取特征并将其输入到 CvSVM 的预测函数中 然而 我偶然发现 svm predict 函数相对较慢 基本上 窗口以固定的步幅长度在图像比例上滑动穿过图像 遍历图像加上提取每个图像特征的速度 窗口大约需要 1000
  • 大于 2GB 的 Tensorflow 图

    我正在尝试优化一个大型张量流保存模型 其中包含 10MB saving model pb 和 16GB 变量 我尝试冻结我的图表并进行一些进一步的转换 我已按照步骤操作https medium com google cloud optimi
  • 为什么我们应该在 Keras 中对深度学习数据进行标准化?

    我正在 Keras 中测试一些网络架构 以对 MNIST 数据集进行分类 我已经实现了一个类似于 LeNet 的方法 我看到在网上找到的例子中 有一个数据标准化的步骤 例如 X train 255 我在没有这种标准化的情况下进行了测试 我发
  • 为什么平均百分比误差(mape)非常高?

    我已获得代码掌握机器学习 https machinelearningmastery com time series prediction lstm recurrent neural networks python keras 我修改了mod
  • 如何从图像生成 tiff/box 文件以在 Windows 中训练 Tesseract

    我正在尝试在 Windows 中训练 Tesseract 为此我需要一对 tiff box 文件 并且我正在尝试使用 jTessBoxEditor 创建它 但它不接受图像作为输入 我也尝试过 boxFactory 但它无法正常运行 有谁知道
  • 在基本 Tensorflow 2.0 中运行简单回归

    我正在学习 Tensorflow 2 0 我认为在 Tensorflow 中实现最基本的简单线性回归是一个好主意 不幸的是 我遇到了几个问题 我想知道这里是否有人可以提供帮助 考虑以下设置 import tensorflow as tf 2
  • Keras model.summary() 结果 - 了解参数数量

    我有一个简单的神经网络模型 用于使用 Keras Theano 后端 从用 python 编写的 28x28px 图像中检测手写数字 model0 Sequential number of epochs to train for nb ep
  • 如何将体积补丁存储到 HDF5 中?

    我有一个尺寸的体积数据256x128x256 由于内存有限 我无法将整个数据直接输入到 CAFFE 因此 我会随机选择n sample补丁50x50x50从体积数据中提取并将其存储到 HDF5 中 我成功地从原始数据及其标签中随机提取了补丁
  • Keras 错误:预计会看到 1 个数组

    当我尝试在 keras 中训练 MLP 模型时出现以下错误 我使用的是 keras 版本1 2 2 检查模型输入时出错 您输入的 Numpy 数组列表 传递给您的模型的尺寸不是模型预期的尺寸 预期的 查看 1 个数组 但得到以下 12859
  • 将 Scikit-Learn OneHotEncoder 与 Pandas DataFrame 结合使用

    我正在尝试使用 Scikit Learn 的 OneHotEncoder 将 Pandas DataFrame 中包含字符串的列替换为 one hot 编码的等效项 我的下面的代码不起作用 from sklearn preprocessin
  • 如何以干净高效的方式在 pytorch 中获得小批量?

    我试图做一件简单的事情 即使用火炬通过随机梯度下降 SGD 训练线性模型 import numpy as np import torch from torch autograd import Variable import pdb def
  • 使用 sklearn 进行稀疏主成分分析

    我正在尝试从中复制一个应用程序paper https people eecs berkeley edu elghaoui Pubs SPCAhandbookSV pdf 作者下载的地方20个新闻组 http scikit learn org
  • 如何在 python 中使用交叉验证执行 GridSearchCV

    我正在执行超参数调整RandomForest如下使用GridSearchCV X np array df features all features y np array df gold standard labels x train x
  • 神经网络的激活函数选择[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我们可以对神经网络的隐藏层和输出层使用不同的激活函数吗 使用这种方案有什么明显的优势吗 对于网络的最后一层 激活单元也取决于任务 分类
  • 深度学习和传统的人工神经网络机器学习有什么区别? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 您能否简要解释一下两者之间的差异深度学习 https developer nvidia com deep learning和利用神经网

随机推荐