使用sklearn StandardScaler标准化数组时结果全为0的问题求助
大家好,我最近在用sklearn的StandardScaler做数据标准化时遇到了一个棘手的问题——处理后的结果居然全是0,完全和我预期的不一样,有没有大佬能帮我排查下问题呀?
先给大家贴一下我的代码:
from sklearn.preprocessing import StandardScaler import numpy as np data = np.array([[11.2, 18.5, 78.3, 451.00, 0.092, 0.081, 0.031, 0.042, 0.19, 0.062, 0.33, 1.37, 2.33, 27.2, 0.0075, 0.016, 0.015, 0.010, 0.012, 0.0031, 14.8, 28.6, 92.3, 632.1, 0.17, 0.32, 0.26, 0.21, 0.38, 0.0943]]) std = StandardScaler() std.fit(data) data_std = std.transform(data) print(data_std)
运行这段代码后,输出的结果是:
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
- 0.]]
但我期望得到的标准化结果应该是这样的:
[[-0.81040387 -0.20004863 -0.54257553 -0.55723686 -0.35369336 -0.45358275
-0.7203131 -0.18436828 0.29230371 -0.15060502 -0.25696325 0.31089387
-0.25053599 -0.27024164 0.21836384 -0.52674695 -0.54547784 -0.30526892
-1.03329333 -0.26720427 -0.29416565 0.44484725 -0.43381103 -0.4236021
1.64341685 0.37871516 -0.09310786 1.3929505 1.38677111 0.53231628]]
问题原因分析
其实问题出在数据的维度定义上!你当前的data是一个仅包含1行的二维数组,也就是样本数只有1个。而StandardScaler的标准化逻辑是:对每一列(每个特征),计算该特征在所有样本中的均值和标准差,再用公式(x - 均值) / 标准差完成标准化。
当某一列只有1个样本数据时,该特征的标准差为0(单个数据点没有波动),用0做除数的话,结果自然全是0了。
解决方案
根据你期望的结果来看,你应该是想把这30个数值当作30个独立的样本(每个样本仅含1个特征),所以需要把数据调整为30行1列的格式,这样每个特征(这里只有1个特征)就有30个样本数据,标准差不为0,标准化后就能得到你想要的结果。
修改后的代码如下:
from sklearn.preprocessing import StandardScaler import numpy as np # 将数据转换为30行1列的数组,每行代表一个样本 data = np.array([[11.2], [18.5], [78.3], [451.00], [0.092], [0.081], [0.031], [0.042], [0.19], [0.062], [0.33], [1.37], [2.33], [27.2], [0.0075], [0.016], [0.015], [0.010], [0.012], [0.0031], [14.8], [28.6], [92.3], [632.1], [0.17], [0.32], [0.26], [0.21], [0.38], [0.0943]]) std = StandardScaler() # 用fit_transform一步完成拟合和转换 data_std = std.fit_transform(data) # 将结果转换为1行30列的格式,和期望输出一致 print(data_std.flatten().reshape(1, -1))
运行这段代码后,输出的结果就和你期望的完全匹配啦!
总结一下:使用StandardScaler时,一定要保证每个特征对应的样本数至少为2,否则会因为标准差为0导致标准化结果全为0,正确定义数据的样本-特征维度是关键。
备注:内容来源于stack exchange,提问作者PotatoandSweetPotato

