在 Sklearn 管道和交叉验证中使用缩放器

Posted

技术标签:

【中文标题】在 Sklearn 管道和交叉验证中使用缩放器【英文标题】:Using scaler in Sklearn PIpeline and Cross validation 【发布时间】:2020-09-16 09:18:58 【问题描述】:

我之前看到过post,代码如下:

scalar = StandardScaler()
clf = svm.LinearSVC()

pipeline = Pipeline([('transformer', scalar), ('estimator', clf)])

cv = KFold(n_splits=4)
scores = cross_val_score(pipeline, X, y, cv = cv)

我的理解是:当我们应用scaler时,我们应该使用4折中的3计算均值和标准差,然后我们应用均值和标准偏差到所有 4 折。

在上面的代码中,我怎么知道 Sklearn 是遵循同样的策略呢?另一方面,如果 sklearn 没有遵循相同的策略,这意味着 sklearn 将计算所有 4 折的均值/标准差。这是否意味着我不应该使用上述代码?

我确实喜欢上面的代码,因为它可以节省大量时间。

【问题讨论】:

【参考方案1】:

在您给出的示例中,我将使用sklearn.model_selection.train_test_split 添加一个额外的步骤:

folds = 4

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=(1/folds), random_state=0, stratify=y)

scalar = StandardScaler()
clf = svm.LinearSVC()

pipeline = Pipeline([('transformer', scalar), ('estimator', clf)])

cv = KFold(n_splits=(folds - 1))
scores = cross_val_score(pipeline, X_train, y_train, cv = cv)

我认为最好的做法是在调整模型的超参数时只使用训练数据集(即X_train, y_train),而应使用测试数据集(即X_test, y_test)作为最终检查,以确保您的模型不偏向验证折叠。此时,您可以将适合您的训练数据集的 scaler 应用到您的测试数据集。

【讨论】:

感谢您的帮助。抱歉,由于我的声誉,我还不能投票。一旦我有足够的,我会的。【参考方案2】:

是的,这是正确的;这是使用管道的原因之一:所有预处理都只适合训练折叠。


一些参考资料。

用户指南的Section 6.1.1:

安全 通过确保使用相同的样本来训练转换器和预测器,管道有助于避免将测试数据中的统计信息泄漏到交叉验证中的训练模型中。

section 3.1.1 of the User Guide末尾的注释:

保留数据的数据转换 正如在训练中保留的数据上测试预测器很重要一样,预处理(如标准化、特征选择等)和类似的数据转换同样应该从训练集中学习并应用于保留的数据以进行预测: ...代码示例... Pipeline 可以更轻松地组合估算器,在交叉验证下提供此行为: ...

最后,您可以查看cross_val_score 的来源。它调用cross_validate,它在每个训练拆分上克隆并拟合估计器(在本例中为整个管道)。 GitHub link.

【讨论】:

感谢您的回答。那我在哪里可以看到这个实现的逻辑呢? 我添加了一些参考资料。 非常感谢您的帮助。抱歉,我还不能投票。一旦我获得更多声誉,我会这样做。

以上是关于在 Sklearn 管道和交叉验证中使用缩放器的主要内容,如果未能解决你的问题,请参考以下文章

在 sklearn 中使用网格搜索和管道获得正确的交叉验证分数

如何使用 Sklearn 管道进行参数调整/交叉验证?

如何在 sklearn 中编写自定义估算器并对其使用交叉验证?

在 sklearn 中运行 10 倍交叉验证后如何运行 SVC 分类器?

XGBoost 与 GridSearchCV、缩放、PCA 和 sklearn 管道中的 Early-Stopping

sklearn:文本分类交叉验证中的向量化