使用MinMaxScaler缩放列后结果全为0的原因解析
为什么用MinMaxScaler对DataFrame列缩放后结果全为0,但逆变换能还原?
我在使用MinMaxScaler对DataFrame的每一列做缩放处理时,发现每列的缩放结果全部为0。例如以下示例中,df_test_1完成缩放后所有值均为0,但通过inverse_transform仍能还原为原始数值,请问为何缩放结果会全为0?
示例代码
from sklearn.preprocessing import MinMaxScaler import pandas as pd df_dict={'A':[-1,-0.5,0,1],'B':[2,6,10,18]} df_test=pd.DataFrame(df_dict) print('original scale data') print(df_test) scaler_model_list=[] df_test_1=df_test.copy() for col in df_test.columns: scaler = MinMaxScaler() scaler_model_list.append(scaler) # 保存每个列的scaler,后续用于逆变换 df_test_1.loc[:,col]=scaler.fit_transform(df_test_1.loc[:,col].values.reshape(1,-1))[0] print('after finishing scaling') print(df_test_1) print('after inverse transformation') print(scaler_model_list[0].inverse_transform(df_test_1.iloc[:,0].values.reshape(1,-1))) print(scaler_model_list[1].inverse_transform(df_test_1.iloc[:,1].values.reshape(1,-1)))
运行输出
original scale data A B 0 -1.0 2 1 -0.5 6 2 0.0 10 3 1.0 18 after finishing scaling A B 0 0.0 0 1 0.0 0 2 0.0 0 3 0.0 0 after inverse transformation [[-1. -0.5 0. 1. ]] [[ 2. 6. 10. 18.]]
问题原因
问题出在数据维度的处理上:
MinMaxScaler要求输入数据格式为(n_samples, n_features),即每行一个样本、每列一个特征。- 你把列数据
reshape(1,-1),相当于把整列4个值当成1个样本的4个特征,而非4个样本的1个特征。 - 对于每个单独的“特征”(原数据的单个元素),它的最大值和最小值都是自身,
MinMaxScaler为避免除以0错误,会将这类特征的所有值缩放为0。 - 逆变换时,每个scaler都保存了对应“特征”的原始min和max,因此能正确还原原始数值。
修正方法
把列数据的reshape改为(-1,1),让数据符合(n_samples, n_features)的格式:
from sklearn.preprocessing import MinMaxScaler import pandas as pd df_dict={'A':[-1,-0.5,0,1],'B':[2,6,10,18]} df_test=pd.DataFrame(df_dict) print('original scale data') print(df_test) scaler_model_list=[] df_test_1=df_test.copy() for col in df_test.columns: scaler = MinMaxScaler() scaler_model_list.append(scaler) # 修正reshape为(-1,1),表示4个样本、1个特征 df_test_1.loc[:,col]=scaler.fit_transform(df_test_1.loc[:,col].values.reshape(-1,1))[:,0] print('after finishing scaling') print(df_test_1) print('after inverse transformation') print(scaler_model_list[0].inverse_transform(df_test_1.iloc[:,0].values.reshape(-1,1))) print(scaler_model_list[1].inverse_transform(df_test_1.iloc[:,1].values.reshape(-1,1)))
修正后输出
original scale data A B 0 -1.0 2 1 -0.5 6 2 0.0 10 3 1.0 18 after finishing scaling A B 0 0.0 0.00 1 0.2 0.25 2 0.4 0.50 3 1.0 1.00 after inverse transformation [[-1. ] [-0.5] [ 0. ] [ 1. ]] [[ 2.] [ 6.] [10.] [18.]]
内容的提问来源于stack exchange,提问作者roudan
相关产品推荐
相关产品推荐

