当只有一个输入时,如何处理MinMaxScaler?

时间:2018-08-22 06:38:01

标签: python pandas scikit-learn

我正在与MinMaxScaler合作。所以下面的输入:

data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]

将在(0,1)范围内进行如下转换:

[[ 0.    0.  ]
 [ 0.25  0.25]
 [ 0.5   0.5 ]
 [ 1.    1.  ]]

现在如何转换单个输入?传递单个输入,例如:

data = [[1,18]]

将进行如下转换:

[[0.,0.]]

原因是,没有Min也没有Max,因此缩放为0。但是,如果我只有一个输入并且要将其传递给机器学习模型(在按比例缩小输入和输出后进行训练),该怎么办?无论缩放前数据中的差异如何,所有输出都是相同的。这绝对是不对的。我在这里可以做什么?有什么方法可以将单个输入表示为不是一系列的0.

这是我在培训过程中所做的:

    X_scaler = MinMaxScaler(feature_range=(0, 1))
    Y_scaler = MinMaxScaler(feature_range=(0, 1))

    # Scale both training inputs and outputs
    X_scaled_training = X_scaler.fit_transform(X_training)
    Y_scaled_training = Y_scaler.fit_transform(Y_training)

    X_scaled_testing = X_scaler.transform(X_testing)
    Y_scaled_testing = Y_scaler.transform(Y_testing)

在训练过程中,我按如下所示反转了模型的值,以获得最终的输出分数:

Y_predicted = Y_scaler.inverse_transform(Y_predicted_scaled)

2 个答案:

答案 0 :(得分:2)

对于您的要求有一些合理的解释。

  • 如果您有兴趣将单个变量用于培训集,则将所有内容缩放为0是一种合理的解释。如果没有某种领域知识或其他信息来源,则最好的猜测就是平均值(或中位数,取决于误差函数的平均值)。
  • 如果您有兴趣将单个变量用于测试集,则问题是您应该使用与训练数据相同的最小/最大缩放比例。由于最小/最大缩放比例的参数已经预先确定,因此您几乎可以肯定不会将新数据缩放为0(如果确实如此,那仍然是正确的选择)。

您想要对测试数据(或生产数据或其他数据)使用相同的最小/最大缩放器的原因是,要使模型概括,它必须在相同的条件下运行像您训练的数据一样。思考机器学习模型的一种方法是,它复制观察到的概率分布。如果对测试数据使用不同的最小/最大缩放器(或预处理中的任何其他步骤),则将使用有关一个概率分布的信息来尝试预测可能完全不同的分布。通常情况下效果不佳。

答案 1 :(得分:0)

尽管问题已经回答,但我将尝试给出一些代码以及一些直觉。我们将使用sklearn的Boston数据集通过线性回归预测具有2个特征的中位数,而不必关心模型是否很好。

import numpy as np
from sklearn.preprocessing import MinMaxScaler
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression

data = load_boston()

X, y = data.data[:,[0, 4]], data.target

我选择了2种特征来预测自有住房的中位价格(目标为1000美元)。

为便于记录,我选择了这些值以使其具有一个最小值,它们分别是按城镇划分的人均犯罪率和一氧化氮的浓度(百万分之几)。

我们将建立一个排除最小值的训练集,以了解发生了什么。

# The minimum values in each column are in row 0 and 286 respectively
indices = [i for i in range(506) if i != 0 and i != 286]

X_train, y_train = X[indices], y[indices]

preproc = MinMaxScaler()

X_train = preproc.fit_transform(X_train)

lin_model = LinearRegression()

lin_model.fit(X_train, y_train)

Out: LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)

让我们检查一下包含先前排除的值的测试集,然后将其与全新MinMaxScaler的结果进行比较。

X_test = X[[0, 286], :]

X_test_scaled = preproc.transform(X_test)
print(X_test_scaled)

[[-3.07978878e-05  3.09128631e-01]
 [ 1.19032713e-04 -8.29875519e-03]]

请注意上面数组中的负值:这将向模型表明这些值低于先前看到的最小值。

expected = y[[0, 286]]
scaled = lin_model.predict(X_test_scaled)
newly_scaled = lin_model.predict(MinMaxScaler().fit_transform(X_test))

print(f"""
target:                         {expected}
with scale from training:       {scaled}
with scale from the new values: {newly_scaled}
"""
)
target:                         [24.  20.1]
with scale from training:       [23.94137825 27.88512316]
with scale from the new values: [15.34941368  3.91320062]

还请注意,使用新定标器预测的值相差很大。


关于只有一个值的问题,正如您所说,我们得到[0,0]。这意味着您放在第一位的任何值,每次都会得到相同的预测。

MinMaxScaler().fit_transform(X[0, :].reshape(1, -1)) #reshape is needed when there is a single sample

Out: array([[0., 0.]])

val = X[0, :].reshape(1, -1)
print(f"intital value: {val}")
newly_scaled = MinMaxScaler().fit_transform(val)
print(f"with the new scaler: {newly_scaled}")
print(f"target: {y[0]}")
print(f"prediction: {lin_model.predict(newly_scaled)}")

intital value: [[0.00632 0.538  ]]
with the new scaler: [[0. 0.]]
target: 24.0
prediction: [27.78476671]

具有另一个值

val = X[161, :].reshape(1, -1)
print(f"intital value: {val}")
newly_scaled = MinMaxScaler().fit_transform(val)
print(f"with the new scaler: {newly_scaled}")
print(f"target: {y[161]}")
print(f"prediction: {lin_model.predict(newly_scaled)}")

intital value: [[1.46336 0.605  ]]
with the new scaler: [[0. 0.]]
target: 50.0
prediction: [27.78476671]

因此,简而言之,您应该重用已定义的预处理,以便根据您的实际数据(以及测试数据和验证数据)训练模型。当您有效地消除输入数据上的所有信息时,请谨慎缩放仅一个样本。