如何通过StandardScaler使用拟合和变换来训练和测试数据

时间:2019-11-29 08:57:17

标签: python machine-learning scikit-learn

如下面的代码所示,我正在使用StandardScaler.fit()函数拟合(即,根据特征计算均值和方差)训练数据集。然后,我调用“ .transform()”函数来缩放要素。我在dochere中发现,仅应使用“ .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)

3 个答案:

答案 0 :(得分:1)

  

我应该遵循StandardScaler的文档,以便仅使用不带fit()函数的“ .transform()”来转换测试数据集吗?还是取决于数据集,以便我可以同时使用“ fit_transform()”函数来训练和测试数据集?

为测试集重新培训定标器的那一刻,您将对输入功能有不同的依赖性。原始算法将根据您的训练方式进行拟合。而且,如果您重新训练它,它将被覆盖,并且您正在伪造该算法的测试数据输入。

所以答案是必须

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

上面的操作方式是正确的。原则上,您应该永远不要在测试数据上使用fit,而只能在火车数据上使用fit_transform。使用fit在测试数据上获得“更好”的结果这一事实并不表示任何实际的性能提升。换句话说,通过在测试数据上使用fit_transform,您将无法对模型在未知数据上的预测能力说出有意义的事情。

这里的主要教训是,一旦违反了方法学上的限制(即,火车与测试的分离),测试性能的任何提高都是毫无意义的。使用mcp 'foo.*' 'bar.#1' 可能会获得更高的分数,但是这些不再意味着任何意义。

相关问题