scikit-learn的MinMaxScaler与NumPy实现结果略有不同

8 投票
1 回答
7725 浏览
提问于 2025-04-18 13:09

我对比了scikit-learn库中的Min-Max缩放器和用NumPy手动实现的缩放方法。不过,我发现两者的结果有一点点不同。有没有人能解释一下这是为什么呢?

Min-Max缩放的公式是这样的:

enter image description here

这个公式应该和scikit-learn的公式一样:(X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))

我用这两种方法进行了如下操作:

def numpy_minmax(X):
    xmin =  X.min()
    return (X - xmin) / (X.max() - xmin)

def sci_minmax(X):
    minmax_scale = preprocessing.MinMaxScaler(feature_range=(0, 1), copy=True)
    return minmax_scale.fit_transform(X)

在一个随机样本上:

import numpy as np

np.random.seed(123)

# A random 2D-array ranging from 0-100

X = np.random.rand(100,2)
X.dtype = np.float64
X *= 100 

结果有一点点不同:

from matplotlib import pyplot as plt

sci_mm = sci_minmax(X)
numpy_mm = numpy_minmax(X)

plt.scatter(numpy_mm[:,0], numpy_mm[:,1],
        color='g',
        label='NumPy bottom-up',
        alpha=0.5,
        marker='o'
        )

plt.scatter(sci_mm[:,0], sci_mm[:,1],
        color='b',
        label='scikit-learn',
        alpha=0.5,
        marker='x'
        )

plt.legend()
plt.grid()

plt.show()

enter image description here

1 个回答

14

scikit-learn会把每个特征单独处理。所以,当你想要计算最小值时,需要指定axis=0,否则numpy.min会计算整个数组的最小值,也就是所有元素的最小值,而不是每一列的最小值:

>>> xs
array([[1, 2],
       [3, 4]])
>>> xs.min()
1
>>> xs.min(axis=0)
array([1, 2])

numpy.max也是一样的道理;所以正确的写法应该是:

def numpy_minmax(X):
    xmin =  X.min(axis=0)
    return (X - xmin) / (X.max(axis=0) - xmin)

这样做的话,你就能得到准确的结果:

exact match

撰写回答