3

这是一个非常小的 sklearn 片段:

logistic = linear_model.LogisticRegression()

pipe = Pipeline(steps=[
    ('scaler_2', MinMaxScaler()),
    ('pca',  decomposition.NMF(6)),     
    ('logistic', logistic),
])

from sklearn.cross_validation import train_test_split   

Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, test_size=0.2)

pipe.fit(Xtrain, ytrain)    
ypred = pipe.predict(Xtest)

我会收到这个错误:

    raise ValueError("Negative values in data passed to %s" % whom)
ValueError: Negative values in data passed to NMF (input X)

根据这个问题: Scaling test data to 0 and 1 using MinMaxScaler

我知道这是因为

这是因为我的测试数据中的最小值低于训练数据,其中 min max scaler 是合适的

但我想知道,这是一个错误吗?MinMaxScaler(所有缩放器)似乎应该在我进行预测之前应用,它不应该依赖于以前拟合的训练数据,对吗?

或者我怎样才能正确地使用带有管道的预处理缩放器?

谢谢。

4

2 回答 2

3

这不是错误。将缩放器添加到管道的主要原因是防止将测试集中的信息泄漏到模型中。当您将管道拟合到训练数据时,会MinMaxScaler保留训练数据的最小值和最大值。它将使用这些值来缩放它可能看到的任何其他数据以进行预测。正如您还强调的那样,这个最小值和最大值不一定是测试数据集的最小值和最大值!因此,当您的测试集的最小值小于训练集中的最小值时,您的训练集中可能会出现一些负值。您需要一个不会给您负值的定标器。例如,您可以使用sklearn.preprocessing.StandardScaler. 确保您设置了参数with_mean = False。这样,它不会在缩放之前将数据居中,而是将您的数据缩放到单位方差。

于 2016-08-28T19:25:04.440 回答
0

如果你的数据是固定的并且采样是正确的,你可以假设你的测试集在很大程度上类似于你的训练集。

因此,您可以预期测试集上的 min/max 接近于训练集上的 min/max,除了少数“异常值”。

为了减少在测试集上使用 MinMaxScaler 产生负值的机会,只需将数据缩放到 (0,1) 范围,但确保您为变压器留出了一些“安全空间”,如下所示:

MinMaxScaler(feature_range=(1,2))
于 2017-11-12T03:03:30.027 回答