从 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.percentile
nan
interpolation='linear'