You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MinMaxScaler与手动计算结果不符的原因排查

问题:MinMaxScaler手动计算与sklearn结果不一致的原因?

我在调试sklearn的MinMaxScaler时,尝试通过手动计算验证其工作逻辑,使用如下数组进行归一化处理:

array = [[0, -1.73, -1.73, -2.0, -2.0, -2.0, -1.73], 
        [-1.73, 0, -1.41, -1.73, -1.73, -1.73, -1.41], 
        [-1.73, -1.41, 0, -1.73, -1.73, -1.73, -0.0], 
        [-2.0, -1.73, -1.73, 0, -1.41, -1.41, -1.73], 
        [-2.0, -1.73, -1.73, -1.41, 0, -0.0, -1.73], 
        [-2.0, -1.73, -1.73, -1.41, -0.0, 0, -1.73], 
        [-1.73, -1.41, -0.0, -1.73, -1.73, -1.73, 0]]

我认为该数据的最小值为-2.0,最大值为0。按照sklearn官方文档给出的MinMaxScaler公式x' = (x-min)/ (max - min)手动计算时,-1.73的结果应为0.135:

x' = (-1.73-(-2)) / (0 - (-2)) 
x' = 0.135

但运行以下代码后:

from sklearn.preprocessing import MinMaxScaler
import numpy as np

X = np.array([
[0, -1.73, -1.73, -2.0, -2.0, -2.0, -1.73], 
[-1.73, 0, -1.41, -1.73, -1.73, -1.73, -1.41], 
[-1.73, -1.41, 0, -1.73, -1.73, -1.73, -0.0], 
[-2.0, -1.73, -1.73, 0, -1.41, -1.41, -1.73], 
[-2.0, -1.73, -1.73, -1.41, 0, -0.0, -1.73], 
[-2.0, -1.73, -1.73, -1.41, -0.0, 0, -1.73], 
[-1.73, -1.41, -0.0, -1.73, -1.73, -1.73, 0]
])

# 创建MinMaxScaler实例
scaler = MinMaxScaler()

# 拟合并转换数据
X_scaled = scaler.fit_transform(X)

# 打印缩放后的数据
print(X_scaled)

得到的结果数组中部分-1.73被缩放为0:

[[1.        0.        0.        0.        0.        
0.        0.       ]
 [0.135     1.        0.1849711 0.135     0.135     
0.135     0.1849711]
 [0.135     0.1849711 1.        0.135     0.135     
0.135     1.       ]
 [0.        0.        0.        1.        0.295     
0.295     0.       ]
 [0.        0.        0.        0.295     1.        
1.        0.       ]
 [0.        0.        0.        0.295     1.        
1.        0.       ]
 [0.135     0.1849711 1.        0.135     0.135     
0.135     1.       ]]

请问我的手动计算与sklearn实现的差异点在哪里?为什么部分-1.73会被缩放为0?


核心原因:MinMaxScaler默认按列归一化,而非全局

你犯了一个关键错误:默认配置下,MinMaxScaler是对每一列独立计算min和max,再单独归一化该列的数据,并非用整个数据集的全局min和max处理所有元素。

我们针对你的数据验证这一点:

  • 看第二列原始数据:[-1.73, 0, -1.41, -1.73, -1.73, -1.73, -1.41],这一列的最小值是-1.73,最大值是0。对该列的-1.73套用公式计算:(-1.73 - (-1.73))/(0 - (-1.73)) = 0,这就是你看到部分-1.73被缩放为0的原因。
  • 再看第一列原始数据:[0, -1.73, -1.73, -2.0, -2.0, -2.0, -1.73],该列min是-2.0,max是0,所以其中的-1.73计算后为0.135,和你手动结果一致。
  • 同理,第四列、第五列的min是-2.0、max是0,所以这些列的-1.73计算后也是0.135。

如何实现全局归一化

如果需要用整个数据集的min和max做归一化,需要先将数据扁平化,归一化后再恢复原形状:

from sklearn.preprocessing import MinMaxScaler
import numpy as np

X = np.array([
[0, -1.73, -1.73, -2.0, -2.0, -2.0, -1.73], 
[-1.73, 0, -1.41, -1.73, -1.73, -1.73, -1.41], 
[-1.73, -1.41, 0, -1.73, -1.73, -1.73, -0.0], 
[-2.0, -1.73, -1.73, 0, -1.41, -1.41, -1.73], 
[-2.0, -1.73, -1.73, -1.41, 0, -0.0, -1.73], 
[-2.0, -1.73, -1.73, -1.41, -0.0, 0, -1.73], 
[-1.73, -1.41, -0.0, -1.73, -1.73, -1.73, 0]
])

# 全局归一化实现
scaler = MinMaxScaler()
# 将数据扁平化为一维数组
X_flat = X.reshape(-1, 1)
# 拟合并转换扁平化数据
X_flat_scaled = scaler.fit_transform(X_flat)
# 恢复原数据形状
X_scaled_global = X_flat_scaled.reshape(X.shape)

print(X_scaled_global)

此时所有-1.73都会被缩放为0.135,和你手动计算的结果完全一致。


内容的提问来源于stack exchange,提问作者Michael Halim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:10:44