假设我在一个机器学习问题中有3个数据集。
训练数据集
:用于估计机器学习模型参数(训练)
测试数据集
:用于评估训练后的模型,计算训练模型的准确性
预测数据集
:仅在模型部署后用于预测
我没有评估数据集
,并且使用带有k折交叉验证的网格搜索来寻找最佳模型。
此外,我有以下两个Python脚本:
train.py
:用于训练和测试机器学习模型,加载训练和测试数据集,保存训练后的模型,最佳模型由网格搜索找到。
predict.py
:用于加载预训练模型 & 加载预测数据集,预测模型输出并计算准确性。
在train.py
中开始训练过程之前,我使用MinMaxScaler如下:
from sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler()scaler.fit(x_train) # 仅在训练数据集上拟合x_train_norm = scaler.transform(x_train)x_test_norm = scaler.transform(x_test)
在predict.py
中,加载预测数据集后,我需要使用相同的数据预处理如下:
from sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler()scaler.fit(x_predict) x_predict_norm = scaler.transform(x_predict)
如上所见,预测数据集上同时进行了拟合和转换。然而,在train.py
中,拟合是在训练数据集上进行的,同一个MinMaxScaler被用于转换测试数据集。
我的理解是,测试数据集是对模型在部署后应该预测的真实数据的模拟。因此,测试和预测数据集的数据预处理应该相同。
我认为在train.py
中应该为训练和测试数据集使用单独的MinMaxScaler,如下所示:
from sklearn.preprocessing import MinMaxScalerscaler_train = MinMaxScaler()scaler_test = MinMaxScaler()scaler_train.fit(x_train) # 仅在训练数据集上拟合x_train_norm = scaler_train.transform(x_train)scaler_test.fit(x_test) # 仅在测试数据集上拟合x_test_norm = scaler_test.transform(x_test)
有什么不同之处?
如果我使用上述解释的单独MinMaxScaler,x_test_norm
的值将不同。在这种情况下,x_test_norm
的值在[-1, 1]范围内。然而,如果我使用在训练数据集上拟合的MinMaxScaler来转换测试数据集,x_test_norm
的值可能会超出[-1, 1]范围。
请告诉我你的想法。
回答:
当你运行.transform()
时,MinMax缩放会执行类似于(value - min) / (Max - min)
的操作。值min
和Max
是在你运行.fit()
时定义的。所以答案是 – 是的,你应该在训练数据集上拟合MinMaxScaler,然后在测试数据集上使用它。
试想一下,在训练数据集中,你有一个特征的最大值为100,最小值为10,而在测试数据集中最大值为10,最小值为1。如果你为测试子集训练单独的MinMaxScaler,是的,它会将特征缩放到[-1, 1]范围内,但与训练数据集相比,这些值应该会更低。
此外,关于带有k折交叉验证的网格搜索,你应该使用Pipeline。在这种情况下,网格搜索会自动在k-1
折上拟合MinMaxScaler。这里有一个关于如何组织带有混合类型的pipeline的好例子。