如何通过 StandardScaler 使用 fit 和 transform 训练和测试数据

Posted

技术标签:

【中文标题】如何通过 StandardScaler 使用 fit 和 transform 训练和测试数据【英文标题】:How to use fit and transform for training and testing data with StandardScaler 【发布时间】:2020-03-24 20:44:45 【问题描述】:

如下面的代码所示,我使用 StandardScaler.fit() 函数来拟合(即从特征中计算均值和方差)训练数据集。然后,我调用“.transform()”函数来缩放特征。我在doc 和here 中发现我应该只使用“.transform()”来转换测试数据集。就我而言,我正在尝试实现异常检测模型,以便所有训练数据集都来自一个目标用户,而所有测试数据集都来自多个其他异常用户。我的意思是,我们有“n”个用户,我们使用来自目标用户的一类数据集样本来训练模型,同时我们在从所有其他“n-1”个异常用户中随机选择的新异常样本上测试训练后的模型。

训练数据集大小:(4816, 158) =>(样本数,特征数) 测试数据集大小:(2380、158) 问题是,当我对训练数据集使用 fit() 然后使用“transform()”,对测试数据集使用“transform()”时,模型给出了不好的结果。但是,只有当我对训练和测试数据集使用“fit_transform()”而不是仅对测试数据集使用“transform()”时,该模型才能给出良好的结果。

我的问题: 我是否应该遵循 StandardScaler 的文档,以便测试数据集必须仅使用“.transform()”而不使用 fit() 函数进行转换?或者它取决于数据集,以便我可以将“fit_transform()”函数用于训练和测试数据集?

是否可以将“fit_transform”用于训练和测试数据集?

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler


# After preparing and splitting the training and testing dataset, we got
X_train # from only the targeted user
X_test  # from other "n-1" anomaly users

# features selection using VarianceThreshold on training set
 sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
 X_train= sel.fit_transform(X_train)
#Normalization using StandardScaler
 scaler = StandardScaler().fit(X_train)
 normalized_X_train = scaler.transform(X_train)
 set_printoptions(precision=3)
# features selection using VarianceThreshold on testing set

 X_test= sel.transform(X_test)
#Normalization using StandardScaler

 normalized_X_test = scaler.transform(X_test)
 set_printoptions(precision=3)

【问题讨论】:

我应该对测试数据使用什么,“fit_transform()”还是只使用“transform()”? 您的意思是我应该对训练数据使用“fit_transform()”,但对于测试数据,我只使用“fit()”而不使用转换?请问你确定吗? @prhmma 是错误的,你应该只在测试数据上使用transformX_train_scaled = scaler.fit_transform(X_train);X_test_scaled = scaler.transform(X_test) 永远,永远,永远,永远,在测试数据上调用 fit @amdex。是的,你是对的。我测试了prhmma的答案,它是错误的。但是,我的问题仍然没有回答。如果我对训练和测试数据集都使用“fit_transform”,是否可以? 【参考方案1】:

当您想要转换数据时,您应该声明它。 喜欢:

data["afs"]=data["afs"].transform()

【讨论】:

【参考方案2】:

你上面的做法是正确的。原则上,您不应在测试数据上使用fit,而应仅在火车数据上使用。在测试数据上使用fit_transform 获得“更好”的结果这一事实并不表示任何真正的性能提升。换句话说,通过在测试数据上使用fit,您将失去对模型对未知数据的预测能力发表有意义的言论的能力。

这里的主要教训是,一旦违反了方法约束(即训练-测试分离),任何测试性能的提升都是毫无意义的。使用fit_transform 可能会获得更高的分数,但这些已经没有任何意义了。

【讨论】:

【参考方案3】:

我是否应该遵循 StandardScaler 的文档,以便测试数据集必须仅使用不使用 fit() 函数的“.transform()”进行转换?或者它取决于数据集,以便我可以将“fit_transform()”函数用于训练和测试数据集?

当您为测试集重新训练定标器时,您将对输入特征有不同的依赖性。原始算法将根据您的训练 sacling 的拟合进行拟合。如果您重新训练它,这将被覆盖,并且您正在伪造算法的测试数据输入。

所以答案是必须只进行转换。

【讨论】:

以上是关于如何通过 StandardScaler 使用 fit 和 transform 训练和测试数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PySpark 中使用 StandardScaler 标准化测试数据集?

如何在不使用 StandardScaler 的情况下标准化 PySpark 中的列?

sklearn.preprocessing.StandardScaler 离线使用 不使用pickle如何做

为啥在 GridSearchCV 中使用 StandardScaler 时会得到不同的结果?

如何在列子集上实现 PySpark StandardScaler?

如何解决 StandardScaler 值错误