有人能给我解释一下标准分级器吗?

我无法理解 sklearn的文档中 StandardScaler呼叫

有人能简单地给我解释一下吗?

256208 次浏览

当您想要比较对应于不同单位的数据时,这非常有用。在这种情况下,您需要删除这些单元。为了以一致的方式对所有数据进行转换,需要将数据转换成方差为单位且序列的平均值为0的方式。

StandardScaler背后的想法是,它将改变你的数据,使其分布的平均值为0,标准差为1。
对于多变量数据,这是按照特性来完成的(换句话说,对于数据的每一列都是独立的)。
考虑到数据的分布,数据集中的每个值都会减去平均值,然后除以整个数据集的标准差(或者多变量情况下的特征)。

在应用 StandardScaler()后,x 中的 每一栏的平均值为0,标准差为1。

公式由本页其他人列出。

基本原理: 有些算法需要这样的数据(参见 Sklearn 医生)。

介绍

我假设您有一个矩阵 X,其中每个 行/行是一个 样本/观察,每个 专栏是一个 变量/特性(顺便说一下,这是任何 sklearn ML 函数的预期输入—— X.shape应该是 [number_of_samples, number_of_features])。


方法的核心

主要思想是对 规范化/标准化,即 μ = 0σ = 1应用任何机器学习模型的 X单独谈之前的特征/变量/列。

StandardScaler() 使特征正常化即每个 的 X,每个人,这样每个列/特征/变量将具有 μ = 0σ = 1


附注: 我发现本页最受欢迎的答案是错误的。 我引用的是“数据集中的每个值将减去样本平均值”——这既不正确也不正确。


参见: 如何以及为什么标准化数据: Python 教程


代码示例

from sklearn.preprocessing import StandardScaler
import numpy as np


# 4 samples/observations and 2 variables/features
data = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
scaler = StandardScaler()
scaled_data = scaler.fit_transform(data)


print(data)
[[0, 0],
[1, 0],
[0, 1],
[1, 1]])


print(scaled_data)
[[-1. -1.]
[ 1. -1.]
[-1.  1.]
[ 1.  1.]]

验证每个特性(列)的平均值为0:

scaled_data.mean(axis = 0)
array([0., 0.])

验证每个特性(列)的 std 为1:

scaled_data.std(axis = 0)
array([1., 1.])

附录: 数学

enter image description here


更新08/2020 : 关于 False/True的输入参数 with_meanwith_std,我在这里提供了一个答案: < a href = “ https://stackoverflow./a/57381708/5025009”> “ with _ std = False 或 True”和“ with _ mean = False 或 True”之间的标准定标器差异

标准定标器执行 标准化的任务。数据集通常包含不同规模的变量。例如,Employee 数据集将包含值为 按20-70打分的 AGE 列和值为 比例尺10000-80000的 SALARY 列。由于这两个栏目的规模不同,在建立机器学习模型时,它们被标准化为具有共同的规模。

上面的答案很棒,但是我需要一个简单的例子来缓解我过去的一些担忧。我想确保它确实是分别对待每个专栏。我现在放心了,找不到什么样的例子引起了我的关注。如上所述,所有列 ARE分别按比例缩放。

密码

import pandas as pd
import scipy.stats as ss
from sklearn.preprocessing import StandardScaler




data= [[1, 1, 1, 1, 1],[2, 5, 10, 50, 100],[3, 10, 20, 150, 200],[4, 15, 40, 200, 300]]


df = pd.DataFrame(data, columns=['N0', 'N1', 'N2', 'N3', 'N4']).astype('float64')


sc_X = StandardScaler()
df = sc_X.fit_transform(df)


num_cols = len(df[0,:])
for i in range(num_cols):
col = df[:,i]
col_stats = ss.describe(col)
print(col_stats)

输出

DescribeResult(nobs=4, minmax=(-1.3416407864998738, 1.3416407864998738), mean=0.0, variance=1.3333333333333333, skewness=0.0, kurtosis=-1.3599999999999999)
DescribeResult(nobs=4, minmax=(-1.2828087129930659, 1.3778315806221817), mean=-5.551115123125783e-17, variance=1.3333333333333337, skewness=0.11003776770595125, kurtosis=-1.394993095506219)
DescribeResult(nobs=4, minmax=(-1.155344148338584, 1.53471088361394), mean=0.0, variance=1.3333333333333333, skewness=0.48089217736510326, kurtosis=-1.1471008824318165)
DescribeResult(nobs=4, minmax=(-1.2604572012883055, 1.2668071116222517), mean=-5.551115123125783e-17, variance=1.3333333333333333, skewness=0.0056842140599118185, kurtosis=-1.6438177182479734)
DescribeResult(nobs=4, minmax=(-1.338945389819976, 1.3434309690153527), mean=5.551115123125783e-17, variance=1.3333333333333333, skewness=0.005374558840039456, kurtosis=-1.3619131970819205)

注意:

Stats 模块正确地报告了“ sample”方差,该方差在分母中使用(n-1)。“总体”方差将在分母中使用 n 来计算方差。为了更好地理解,请参阅下面的代码,其中使用了上述数据集第一列的缩放数据:

密码

import scipy.stats as ss


sc_Data = [[-1.34164079], [-0.4472136], [0.4472136], [1.34164079]]
col_stats = ss.describe([-1.34164079, -0.4472136, 0.4472136, 1.34164079])
print(col_stats)
print()


mean_by_hand = 0
for row in sc_Data:
for element in row:
mean_by_hand += element
mean_by_hand /= 4


variance_by_hand = 0
for row in sc_Data:
for element in row:
variance_by_hand += (mean_by_hand - element)**2
sample_variance_by_hand = variance_by_hand / 3
sample_std_dev_by_hand = sample_variance_by_hand ** 0.5


pop_variance_by_hand = variance_by_hand / 4
pop_std_dev_by_hand = pop_variance_by_hand ** 0.5


print("Sample of Population Calcs:")
print(mean_by_hand, sample_variance_by_hand, sample_std_dev_by_hand, '\n')
print("Population Calcs:")
print(mean_by_hand, pop_variance_by_hand, pop_std_dev_by_hand)

输出

DescribeResult(nobs=4, minmax=(-1.34164079, 1.34164079), mean=0.0, variance=1.3333333422778562, skewness=0.0, kurtosis=-1.36000000429325)


Sample of Population Calcs:
0.0 1.3333333422778562 1.1547005422523435


Population Calcs:
0.0 1.000000006708392 1.000000003354196

下面是一个简单的工作示例,解释了标准化计算是如何工作的。理论部分已经在其他答案中得到了很好的解释。

>>>import numpy as np
>>>data = [[6, 2], [4, 2], [6, 4], [8, 2]]
>>>a = np.array(data)


>>>np.std(a, axis=0)
array([1.41421356, 0.8660254 ])


>>>np.mean(a, axis=0)
array([6. , 2.5])


>>>from sklearn.preprocessing import StandardScaler
>>>scaler = StandardScaler()
>>>scaler.fit(data)
>>>print(scaler.mean_)


#Xchanged = (X−μ)/σ  WHERE σ is Standard Deviation and μ is mean
>>>z=scaler.transform(data)
>>>z

计算

正如你在输出中看到的,平均值是[6. ,2.5] ,标准差是[1.41421356,0.8660254]

数据是(0,1)位置是2 标准化 = (2-2.5)/0.8660254 = -0.57735027

(1,0)位置的数据为4 标准化 = (4-6)/1.41421356 = -1.414

标准化后的结果

enter image description here

标准化后检验平均值和标准偏差

enter image description here

注意: -2.77555756 e-17非常接近0。

参考文献

  1. 用异常值比较不同定标器对数据的影响

  2. 标准化和规范化有什么区别?

  3. 使用 sklearn 标准定标器缩放的数据的平均值不是零

我们按行应用 StandardScalar()

因此,对于列中的每一行(我假设您使用的是熊猫数据框架) :

x_new = (x_original - mean_of_distribution) / std_of_distribution

几点-

  1. 我们把它除以分布的标准差(distr。).类似地,您可以猜测 MinMaxScalar()

  2. 在应用 StandardScalar()之后,原始分布保持不变。这是一个常见的误解,分布变成正态分布。我们只是把范围压缩成[0,1]。