如何使用MinMaxScaler sklearn对训练数据和测试数据进行归一化

16

所以,我有一个疑问并一直在寻找答案。问题是当我使用时,

from sklearn import preprocessing
min_max_scaler = preprocessing.MinMaxScaler()

df = pd.DataFrame({'A':[1,2,3,7,9,15,16,1,5,6,2,4,8,9],'B':[15,12,10,11,8,14,17,20,4,12,4,5,17,19],'C':['Y','Y','Y','Y','N','N','N','Y','N','Y','N','N','Y','Y']})

df[['A','B']] = min_max_scaler.fit_transform(df[['A','B']])
df['C'] = df['C'].apply(lambda x: 0 if x.strip()=='N' else 1)

在此之后,我会训练和测试模型(AB 作为特征,C 作为标签)并获得一些准确率。现在我的疑问是,当我需要预测新数据集的标签时会发生什么。比方说,

df = pd.DataFrame({'A':[25,67,24,76,23],'B':[2,54,22,75,19]})

因为当我对列进行标准化时,AB的值将根据新数据而不是模型训练所使用的数据进行更改。因此,现在经过数据准备步骤后,我的数据如下。

data[['A','B']] = min_max_scaler.fit_transform(data[['A','B']])

根据df [['A','B']]MaxMin值,AB的值将发生变化。df [['A','B']]的数据准备是基于df [['A','B']]Min Max

不同数字之间如何进行有效的数据准备?我不明白这里的预测将如何正确。


如果您想使用已训练的模型,就必须使用相同的缩放器...保存缩放器并重新应用它。 - Uvar
2个回答

57

您应该使用训练数据来拟合MinMaxScaler,然后在进行预测之前将缩放器应用于测试数据。


总结:

  • 步骤1:在训练数据上拟合缩放器
  • 步骤2:使用缩放器转换训练数据
  • 步骤3:使用转换后的训练数据拟合预测模型
  • 步骤4:使用缩放器转换测试数据
  • 步骤5:使用训练好的模型(步骤3) 和转换后的测试数据(步骤4) 进行预测.

使用您的数据的示例:

from sklearn import preprocessing
min_max_scaler = preprocessing.MinMaxScaler()
#training data
df = pd.DataFrame({'A':[1,2,3,7,9,15,16,1,5,6,2,4,8,9],'B':[15,12,10,11,8,14,17,20,4,12,4,5,17,19],'C':['Y','Y','Y','Y','N','N','N','Y','N','Y','N','N','Y','Y']})
#fit and transform the training data and use them for the model training
df[['A','B']] = min_max_scaler.fit_transform(df[['A','B']])
df['C'] = df['C'].apply(lambda x: 0 if x.strip()=='N' else 1)

#fit the model
model.fit(df['A','B'])

#after the model training on the transformed training data define the testing data df_test
df_test = pd.DataFrame({'A':[25,67,24,76,23],'B':[2,54,22,75,19]})

#before the prediction of the test data, ONLY APPLY the scaler on them
df_test[['A','B']] = min_max_scaler.transform(df_test[['A','B']])

#test the model
y_predicted_from_model = model.predict(df_test['A','B'])

使用鸢尾花数据的示例:

import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import SVC

data = datasets.load_iris()
X = data.data
y = data.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)

model = SVC()
model.fit(X_train_scaled, y_train)

X_test_scaled = scaler.transform(X_test)
y_pred = model.predict(X_test_scaled)

希望这可以帮助到您。

此外,您也可以查看我的这篇文章: https://towardsdatascience.com/everything-you-need-to-know-about-min-max-normalization-in-python-b79592732b79


1
它使用训练集中的X_minX_max(用于拟合min_max_scaler的那个训练集)。 - FlorianGD
1
@Tia,这里的XminXmax是从训练集中计算出来的,然后对训练数据进行归一化处理,最后使用相同的值对测试数据进行归一化处理。 - seralouk
5
如果y_train数据也有很大的尺度,那么在预测后应该如何进行纠正?在这种情况下,最好的方法是什么? - cdvv7788
4
MinMaxScaler假设训练数据包含X的最大值。如果我的测试集或者预测未来数据集中的值比MinMaxScaler拟合时使用的值要大得多,它能处理吗? - csteel
那不应该是个问题。可能会发生变化,但是不会有任何影响。 - seralouk
显示剩余3条评论

2
最好的方法是训练并保存MinMaxScaler模型,并在需要时加载相同的模型。 保存模型:
df = pd.DataFrame({'A':[1,2,3,7,9,15,16,1,5,6,2,4,8,9],'B':[15,12,10,11,8,14,17,20,4,12,4,5,17,19],'C':['Y','Y','Y','Y','N','N','N','Y','N','Y','N','N','Y','Y']})
df[['A','B']] = min_max_scaler.fit_transform(df[['A','B']])  
pickle.dump(min_max_scaler, open("scaler.pkl", 'wb'))

正在加载保存的模型:

scalerObj = pickle.load(open("scaler.pkl", 'rb'))
df_test = pd.DataFrame({'A':[25,67,24,76,23],'B':[2,54,22,75,19]})
df_test[['A','B']] = scalerObj.transform(df_test[['A','B']])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接