浅谈sklearn中的数据预处理

前言

sklearn 中的 sklearn.preprocessing 中提供了数据预处理的相关函数,本文将主要围绕特征缩放来展开讲解。

一、标准化(StandardScaler)

设数据矩阵为

X

=

[

x

1

T

x

2

T

x

n

T

]

X= begin{bmatrix} boldsymbol{x}_1^{mathrm T} \ boldsymbol{x}_2^{mathrm T} \ vdots \ boldsymbol{x}_n^{mathrm T} end{bmatrix}

X=x1Tx2TxnT

其中

x

i

=

(

x

i

1

,

x

i

2

,


,

x

i

d

)

T

boldsymbol{x}_i=(x_{i1}, x_{i2},cdots,x_{id})^{mathrm T}

xi=(xi1,xi2,,xid)T 为特征向量。

在进行下一步之前,我们有必要先引入数据矩阵的均值和标准差。

我们知道,对于数据向量

a

=

(

a

1

,


,

a

n

)

T

boldsymbol{a}=(a_1,cdots,a_n)^{mathrm T}

a=(a1,,an)T 而言(这里的向量可以理解成一组数据,之所以称之为向量,是为了方便后续的表述),其均值和标准差分别为:

μ

(

a

)

=

a

1

+

+

a

n

n

,

σ

(

a

)

=

(

1

n

a

μ

(

a

)

2

)

1

/

2

,


  

μ

(

a

)

=

(

μ

(

a

)

,


,

μ

(

a

)

n

)

T

mu(boldsymbol{a})=frac{a_1+cdots+a_n}{n},quadsigma(boldsymbol a)=left(frac1n Vert boldsymbol{a}-boldsymbol{mu}(boldsymbol{a})Vert^2right)^{1/2},quad 其中 ;boldsymbol{mu}(boldsymbol{a})=(underbrace{mu(boldsymbol{a}),cdots, mu(boldsymbol{a})}_{n 个})^{mathrm T}

μ(a)=na1++an,σ(a)=(n1aμ(a)2)1/2,μ(a)=(n

μ(a),,μ(a))T

我们将

X

X

X 写成行向量的形式:

X

=

(

a

1

,

a

2

,


,

a

d

)

X =(boldsymbol{a}_1,boldsymbol{a}_2,cdots,boldsymbol{a}_d)

X=(a1,a2,,ad),其中每个

a

i

boldsymbol{a}_i

ai 均为列向量,因此

μ

(

X

)

=

(

μ

(

a

1

)

,

μ

(

a

2

)

,


,

μ

(

a

d

)

)

T

σ

(

X

)

=

(

σ

(

a

1

)

,

σ

(

a

2

)

,


,

σ

(

a

d

)

)

T

begin{aligned} mu(X)&=(mu(boldsymbol{a}_1),mu(boldsymbol{a}_2),cdots,mu(boldsymbol{a}_d))^{mathrm T} \ sigma(X)&=(sigma(boldsymbol{a}_1),sigma(boldsymbol{a}_2),cdots,sigma(boldsymbol{a}_d))^{mathrm T} end{aligned}

μ(X)σ(X)=(μ(a1),μ(a2),,μ(ad))T=(σ(a1),σ(a2),,σ(ad))T

设对

X

X

X 进行标准化后得到

Z

Z

Z,利用 numpy 的广播机制,

Z

Z

Z 有如下形式

Z

=

(

z

1

,

z

2

,


,

z

d

)

,


  

z

i

=

a

i

μ

(

a

i

)

σ

(

a

i

)

,
    

i

=

1

,

2

,


,

d

Z=(boldsymbol{z}_1,boldsymbol{z}_2,cdots,boldsymbol{z}_d),quad 其中; boldsymbol{z}_i=frac{boldsymbol{a}_i-mu(boldsymbol{a}_i)}{sigma(boldsymbol{a}_i)},;;i=1,2,cdots,d

Z=(z1,z2,,zd),zi=σ(ai)aiμ(ai),i=1,2,,d

当然

Z

Z

Z 可以更为简洁地表成

Z

=

X

μ

(

X

)

T

σ

(

X

)

T

Z=frac{X-mu(X)^{mathrm T}}{sigma(X)^{mathrm T}}

Z=σ(X)TXμ(X)T


查看

X

X

X 的均值,方差和标准差:

from sklearn.preprocessing import StandardScaler
import numpy as np

# 数据矩阵
X = np.array([
    [1, 3],
    [0, 1]
])
# 创建一个scaler实例并将数据传入该实例中
scaler = StandardScaler().fit(X)
# 查看X的的均值,方差和标准差
print(scaler.mean_)  # [0.5 2. ]
print(scaler.var_)  # [0.25 1.  ]
print(scaler.scale_)  # [0.5 1. ]

之所以标准差为 scale_,是因为标准差控制着我们数据的缩放程度。需要注意的是,如果数据矩阵的某一列方差为

0

0

0,则 scale_

1

1

1,即这一列不进行缩放。

X

X

X 进行标准化,只需要使用 transfrom() 方法:

X = np.array([
    [243, 80],
    [19, 47]
])
scaler = StandardScaler().fit(X)
# 进行缩放
X_scaled = scaler.transform(X)
# [[ 1.  1.]
#  [-1. -1.]]

查看 X_scaled 的均值和标准差:

print(X_scaled.mean(axis=0))
# [0. 0.]
print(X_scaled.std(axis=0))
# [1. 1.]

可以看到 X_scaled 均值为

0

boldsymbol 0

0, 标准差为

1

boldsymbol 1

1,即

X

X

X 已经标准化。

当然我们也可以用 scaler 去标准化新的样本,标准化过程采用

X

X

X 的均值和标准差:

X = np.array([
    [243, 80],
    [19, 47]
])
scaler = StandardScaler().fit(X)
# 缩放新的样本
print(scaler.transform([[2, 3]]))
# [[-1.15178571 -3.66666667]]

二、归一化(MinMaxScaler)

X

X

X 进行归一化就是将

X

X

X 中的所有元素缩放至

[

0

,

1

]

[0,1]

[0,1] 内。具体过程如下:

a

i

=

min

(

x

1

i

,

x

2

i

,


,

x

n

i

)

,

a

i

=

max

(

x

1

i

,

x

2

i

,


,

x

n

i

)

X

=

(

a

1

,

a

2

,


,

a

d

)

T

,

X

=

(

a

1

,

a

2

,


,

a

d

)

T

underline{boldsymbol{a}_i}=min(x_{1i},x_{2i},cdots,x_{ni}),quad overline{boldsymbol{a}_i}=max(x_{1i},x_{2i},cdots,x_{ni}) \ \ underline{X}=(underline{boldsymbol{a}_1},underline{boldsymbol{a}_2},cdots,underline{boldsymbol{a}_d})^{mathrm{T}},quad overline{X}=(overline{boldsymbol{a}_1},overline{boldsymbol{a}_2},cdots,overline{boldsymbol{a}_d})^{mathrm{T}}

ai=min(x1i,x2i,,xni),ai=max(x1i,x2i,,xni)X=(a1,a2,,ad)T,X=(a1,a2,,ad)T

X

X

X 进行归一化后得到

Z

Z

Z,利用 numpy 的广播机制,我们有

Z

=

X

X

T

X

T

X

T

Z=frac{X-underline{X}^{mathrm T}}{overline{X}^{mathrm T}-underline{X}^{mathrm T}}

Z=XTXTXXT


先用 make_blobs() 生成斑点数据集:

from sklearn.preprocessing import MinMaxScaler
from sklearn.datasets import make_blobs

X, _ = make_blobs(n_samples=6, centers=2, random_state=27)
print(X)
# [[ 5.93412904  6.82960749]
#  [-1.66484812  6.53450678]
#  [-1.26216614  6.23733539]
#  [ 5.26739446  7.73680694]
#  [-0.66451524  7.50872847]
#  [ 4.14680663  6.35238034]]

X

X

X 进行归一化:

scaler = MinMaxScaler().fit(X)
print(scaler.transform(X))
# [[1.         0.39498722]
#  [0.         0.19818408]
#  [0.0529916  0.        ]
#  [0.91225996 1.        ]
#  [0.13164046 0.8478941 ]
#  [0.76479434 0.07672366]]

如果我们想将

X

X

X 中的元素缩放至

(

1

,

2

)

(1, 2)

(1,2) 区间内,只需要:

scaler = MinMaxScaler((1, 2)).fit(X)
print(scaler.transform(X))
# [[2.         1.39498722]
#  [1.         1.19818408]
#  [1.0529916  1.        ]
#  [1.91225996 2.        ]
#  [1.13164046 1.8478941 ]
#  [1.76479434 1.07672366]]

三、正则化(Normalizer)

X

X

X 进行正则化也就是对其中的每个样本(每一行)进行正则化,即将每个样本的范数化为单位范数。具体过程如下:

x

i

:

=

x

i

x

i

p

,

i

=

1

,

2

,


,

n

,

p

=

1

,

2

,

boldsymbol{x}_i:=frac{boldsymbol{x}_i}{Vert boldsymbol{x}_iVert_p},quad i=1,2,cdots,n,quad p=1,2,infty

xi:=xipxi,i=1,2,,n,p=1,2,

p

=

1

p=1

p=1 时即为 L1 范数,

p

=

2

p=2

p=2 时即为 L2 范数,

p

=

p=infty

p= 时为无穷(最大)范数。Normalizer 默认采用 L2 范数。


X

X

X 进行 L2 正则化:

from sklearn.preprocessing import Normalizer
import numpy as np

X = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8]
])
scaler = Normalizer().fit(X)
print(scaler.transform(X))
# [[0.18257419 0.36514837 0.54772256 0.73029674]
#  [0.37904902 0.45485883 0.53066863 0.60647843]]

如果要采用最大范数或 L1 范数,只需要:

scaler = Normalizer('max').fit(X)
print(scaler.transform(X))
# [[0.25  0.5   0.75  1.   ]
#  [0.625 0.75  0.875 1.   ]]

scaler = Normalizer('l1').fit(X)
print(scaler.transform(X))
# [[0.1        0.2        0.3        0.4       ]
#  [0.19230769 0.23076923 0.26923077 0.30769231]]

四、绝对值最大标准化(MaxAbsScaler)

X

X

X 进行绝对值最大标准化即对

X

X

X 的每一列,根据其最大绝对值进行缩放。具体过程如下:

M

a

x

A

b

s

(

a

i

)

=

max

(

x

1

i

,

x

2

i

,


,

x

n

i

)

,

M

a

x

A

b

s

(

X

)

=

(

M

a

x

A

b

s

(

a

1

)

,


,

M

a

x

A

b

s

(

a

d

)

)

T

mathrm{MaxAbs}(boldsymbol{a_i})=max(|x_{1i}|,|x_{2i}|,cdots,|x_{ni}|),quad mathrm{MaxAbs}(X)=(mathrm{MaxAbs}(boldsymbol{a}_1),cdots, mathrm{MaxAbs}(boldsymbol{a}_d))^{mathrm T}

MaxAbs(ai)=max(x1i,x2i,,xni),MaxAbs(X)=(MaxAbs(a1),,MaxAbs(ad))T

X

X

X 进行绝对值最大标准化后得到

Z

Z

Z,利用 numpy 的广播机制,有

Z

=

X

M

a

x

A

b

s

(

X

)

T

Z=frac{X}{mathrm{MaxAbs}(X)^{mathrm T}}

Z=MaxAbs(X)TX


X

X

X 进行绝对值最大标准化:

from sklearn.preprocessing import MaxAbsScaler
import numpy as np

X = np.array([
    [1, -1, 2],
    [2, 0, 0],
    [0, 1, -1]
])
scaler = MaxAbsScaler().fit(X)
print(scaler.transform(X))
# [[ 0.5 -1.   1. ]
#  [ 1.   0.   0. ]
#  [ 0.   1.  -0.5]]

五、二值化(Binarizer)

X

X

X 进行二值化就是设定一个阈值,

X

X

X大于该阈值的元素置为

1

1

1小于等于该阈值的元素置为

0

0

0

Binarizer 默认的阈值为

0

0

0


X

X

X 进行二值化:

from sklearn.preprocessing import Binarizer
import numpy as np

X = np.array([
    [1, -1, 2],
    [2, 0, 0],
    [0, 1, -1]
])
transformer = Binarizer().fit(X)
print(transformer.transform(X))
# [[1 0 1]
#  [1 0 0]
#  [0 1 0]]

若将阈值调为

1

1

1,则结果变成:

transformer = Binarizer(threshold=1).fit(X)
print(transformer.transform(X))
# [[0 0 1]
#  [1 0 0]
#  [0 0 0]]

事实上,利用 numpy 的特性,我们可以只用 numpy 完成这些操作:

import numpy as np

def binarizer(X, threshold):
    Y = X.copy()
    Y[Y > threshold] = 1
    Y[Y <= threshold] = 0
    return Y


X = np.array([
    [1, -1, 2], 
    [2, 0, 0], 
    [0, 1, -1]
])
print(binarizer(X, 0))
# [[1 0 1]
#  [1 0 0]
#  [0 1 0]]

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>