这是一个非常小的sklearn snipplet:
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
我知道这是因为
这是因为我的测试数据中的最低值是 低于列车数据,其中最小最大比例尺适合
但我想知道,这是一个错误吗? MinMaxScaler(所有缩放器)似乎应该在我做预测之前应用,它不应该取决于之前的拟合训练数据,我是对的吗?
或者我怎样才能正确使用Pipeline预处理缩放器?
感谢。
答案 0 :(得分:1)
这不是错误。将缩放器添加到管道的主要原因是为了防止将测试集中的信息泄漏到模型中。当您将管道放入训练数据时,MinMaxScaler
会保留训练数据的最小值和最大值。它将使用这些值来缩放它可能看到的任何其他预测数据。正如您也强调的那样,此最小值和最大值不一定是测试数据集的最小值和最大值!因此,当测试集的最小值小于训练集中的最小值时,训练集中可能会出现一些负值。你需要一个不给你负值的缩放器。例如,您可以使用sklearn.preprocessing.StandardScaler
。确保设置参数with_mean = False
。这样,它不会在缩放之前将数据居中,而是将数据缩放到单位方差。
答案 1 :(得分:0)
如果您的数据是静止的并且采样正确完成,您可以假设您的测试集在很大程度上类似于您的列车。
因此,您可以预期测试集的最小值/最大值接近列车集的最小值/最大值,但少数“异常值”除外。
为了减少在测试装置上使用MinMaxScaler产生负值的可能性,只需将数据缩放到(0,1)范围,但确保为变压器提供了一些“安全空间”,如下所示:
MinMaxScaler(feature_range=(1,2))