4

我在sklearn中尝试了Robustscaler,发现结果和公式不一样。

sklearn中Robustscaler的公式为:

图 1. 计算 Robustscaler 的公式

我有一个如下所示的矩阵:

图 2. 测试矩阵

我测试功能一(第一行和第一列)中的第一个数据。缩放值应该是(1-3)/(5.5-1.5) = -0.5。但是,sklearn 的结果是-0.67. 有谁知道哪里计算不正确?

使用 sklearn 的代码如下:

import numpy as np
from sklearn.preprocessing import RobustScaler
x=[[1,2,3,4],[4,5,6,7],[7,8,9,10],[2,1,1,1]]
scaler = RobustScaler(quantile_range=(25.0, 75.0),with_centering=True)
x_new = scaler.fit_transform(x)
print(x_new)
4

1 回答 1

3

从 RobustScaler文档(强调添加):

通过计算训练集中样本的相关统计数据,居中和缩放在每个特征上独立发生。

即中位数和 IQR 数量是按列计算的,而不是针对整个数组。

澄清后,让我们手动计算第一列的缩放值:

import numpy as np

x1 = np.array([1, 4, 7, 2]) # your 1st column here

q75, q25 = np.percentile(x1, [75 ,25])
iqr = q75 - q25

x1_med = np.median(x1)

x1_scaled = (x1-x1_med)/iqr
x1_scaled
# array([-0.66666667,  0.33333333,  1.33333333, -0.33333333])

这与您自己的第一列相同,x_new由 scikit-learn 计算得出:

# your code verbatim:
from sklearn.preprocessing import RobustScaler
x=[[1,2,3,4],[4,5,6,7],[7,8,9,10],[2,1,1,1]]
scaler = RobustScaler(quantile_range=(25.0, 75.0),with_centering=True)
x_new = scaler.fit_transform(x)
print(x_new)
# result
[[-0.66666667 -0.375      -0.35294118 -0.33333333]
 [ 0.33333333  0.375       0.35294118  0.33333333]
 [ 1.33333333  1.125       1.05882353  1.        ]
 [-0.33333333 -0.625      -0.82352941 -1.        ]]

np.all(x1_scaled == x_new[:,0])
# True

对于其余的列(特征)也是如此 - 在缩放它们之前,您需要分别计算它们中的每一个的中值和 IQR 值。

更新(评论后):

正如维基百科关于四分位数的条目中所指出的:

对于离散分布,在选择四分位数上没有普遍的共识

另请参阅相关参考资料,统计包中的样本分位数

统计计算机软件包中的样本分位数有大量不同的定义

深入研究np.percentile此处使用的文档,您会看到不少于五 (5) 种不同的插值方法,并且并非所有方法都产生相同的结果(另请参阅上面链接的 Wikipedia 条目中演示的 4 种不同方法); 以下是这些方法及其在x1上面定义的数据中的结果的快速演示:

np.percentile(x1, [75 ,25]) # interpolation='linear' by default
# array([4.75, 1.75])

np.percentile(x1, [75 ,25], interpolation='lower')
# array([4, 1])

np.percentile(x1, [75 ,25], interpolation='higher')
# array([7, 2])

np.percentile(x1, [75 ,25], interpolation='midpoint')
# array([5.5, 1.5])

np.percentile(x1, [75 ,25], interpolation='nearest')
# array([4, 2])

除了没有两种方法产生相同结果这一事实之外,您在自己的计算中使用的定义也应该很明显对应于interpolation='midpoint',而默认的 Numpy 方法是interpolation='linear'. 正如 Ben Reiniger 在下面的评论中正确指出的那样,在RobustScaler的源代码中实际使用的是默认设置(我在这里使用的能够处理值np.nanpercentile的变体 pf ) 。np.percentilenaninterpolation='linear'

于 2021-02-06T14:12:24.643 回答