天天看點

ML常用資料預處理方式

1) 标準化(均值移除)

讓樣本矩陣每一列的平均值為0,标準差為1,如三個數a,b,c

平均值:

m = ( a + b + c ) / 3 a ′ = a − m b ′ = b − m c ′ = c − m m = (a+b+c) / 3 \\ a' = a - m \\ b' = b - m \\ c' = c - m \\ m=(a+b+c)/3a′=a−mb′=b−mc′=c−m

預處理後的平均值為0:

m ′ = ( a ′ + b ′ + c ′ ) / 3 = ( ( a + b + c ) − 3 m ) = 0 m' = (a'+b'+c')/3 = ((a+b+c)-3m) = 0 \\ m′=(a′+b′+c′)/3=((a+b+c)−3m)=0

标準差:

s = ( ( ( a − m ) 2 + ( b − m ) 2 + ( c − m ) 2 ) / 3 ) a ′ ′ = a ′ / s b ′ ′ = b ′ / s c ′ ′ = c ′ / s s = \sqrt(((a-m)^2 + (b-m)^2 + (c-m)^2)/3) \\ a'' = a'/s b'' = b'/s c'' = c'/s s=(

​((a−m)2+(b−m)2+(c−m)2)/3)a′′=a′/sb′′=b′/sc′′=c′/s

預處理之後的标準差為1:

s ′ ′ = ( a ′ ′ 2 + b ′ ′ 2 + c ′ ′ 2 ) / 3 = ( ( a ′ / s ) 2 + ( b ′ / s ) 2 + ( c ′ / s ) 2 ) / 3 = ( ( a − m ) 2 + ( b − m ) 2 + ( c − m ) 2 ) / 3 s = 1 s'' = \sqrt{(a''^2 + b''^2 + c''^2)/3} = \sqrt{((a'/s)^2 + (b'/s)^2 + (c'/s)^2)/3} = \frac{\sqrt{((a-m)^2 + (b-m)^2 + (c-m)^2)/3}}{s} = 1 s′′=(a′′2+b′′2+c′′2)/3

​=((a′/s)2+(b′/s)2+(c′/s)2)/3

​=s((a−m)2+(b−m)2+(c−m)2)/3

​​=1

import numpy as np
import sklearn.preprocessing as sp
a = np.array([
    [1.0, 2.0, 3.0],
    [4.0, 5.0, 6.0],
    [7.0, 8.0, 9.0]]).astype("float64")
b = sp.scale(a)
print(b.mean(axis=0))
print(b.std(axis=0))
"""
[0. 0. 0.]
[1. 1. 1.]
"""
           

2)範圍縮放

将樣本矩陣中的每一列最小值及最大值設定為相同的區間,如a,b,c三個數,b為最小值,c為最大值,令:

a ′ = a − b b ′ = b − b c ′ = c − b a' = a - b \\ b' = b - b \\ c' = c- b \\ a′=a−bb′=b−bc′=c−b

然後:

a ′ ′ = a ′ / c ′ b ′ ′ = b ′ / c ′ c ′ ′ = c ′ / c ′ a'' = a' / c' \\ b'' = b' / c' \\ c'' = c' / c' \\ a′′=a′/c′b′′=b′/c′c′′=c′/c′

這樣縮放完成時,max{a’’,b’’,c’’} = 1, min{a’’,b’’,c’’} = 0

import sklearn.preprocessing as sp
import numpy as np
a = np.array([
    [1.0, 2.0, 3.0],
    [4.0, 5.0, 6.0],
    [7.0, 8.0, 9.0]]).astype("float64")
obj = sp.MinMaxScaler(feature_range=(0,1))
b = obj.fit_transform(a)
print(b)
"""
[[0.  0.  0. ]
 [0.5 0.5 0.5]
 [1.  1.  1. ]]
"""
           

3)歸一化

用樣本特征值分别除以樣本特征值總和

import numpy as np
import sklearn.preprocessing as sp
a = np.array([
    [-1.0, 2.0, 3.0],
    [4.0, 5.0, 6.0],
    [7.0, 8.0, 9.0]]).astype("float64")
b = sp.normalize(a, norm='l1') # 各特征除以樣本特征絕對值之和
c = sp.normalize(a, norm='l2') # 各特征除以樣本特征二範數
print(b)
print(c)
"""
[[-0.16666667  0.33333333  0.5       ]
 [ 0.26666667  0.33333333  0.4       ]
 [ 0.29166667  0.33333333  0.375     ]]
[[-0.26726124  0.53452248  0.80178373]
 [ 0.45584231  0.56980288  0.68376346]
 [ 0.50257071  0.57436653  0.64616234]]
"""
           

4)二值化

根據事先給定的門檻值,用0和1表示特征值是否超過門檻值

import numpy as np
import sklearn.preprocessing as sp
a = np.array([
    [1.0, 2.0, 3.0],
    [4.0, 5.0, 6.0],
    [7.0, 8.0, 9.0]]).astype("float64")
obj = sp.Binarizer(threshold=4)
b = obj.transform(a)
print(b)
"""
[[0. 0. 0.]
 [0. 1. 1.]
 [1. 1. 1.]]
"""
           

5)獨熱編碼

根據一個特征的個數建立0和1組成的序列,用來對序列中所有的特征值進行編碼,例如如下樣本:

[ 1.0 1.0 1.0 1.0 1.0 2.0 1.0 2.0 4.0 ] \left[ \begin{matrix} 1.0 & 1.0 & 1.0 \\ 1.0 & 1.0 & 2.0\\ 1.0 & 2.0 & 4.0 \\ \end{matrix} \right] ⎣⎡​1.01.01.0​1.01.02.0​1.02.04.0​⎦⎤​

對于第一列,全是1,是以采用一位數字

對于第二列,有1和2,是以采用兩位數字

對于第三列,有1,2,4,是以采用三位數字

import numpy as np
import sklearn.preprocessing as sp

a = np.array([
    [1.0, 1.0, 1.0],
    [1.0, 1.0, 2.0],
    [1.0, 2.0, 4.0]]).astype("float64")

# 定義獨熱編碼器
one_hot_encoder = sp.OneHotEncoder(
    sparse=False,  # 不采用稀疏格式
    dtype='int32',
    categories='auto'
)
b = one_hot_encoder.fit_transform(a)
print(b)
"""
[[1 1 0 1 0 0]
 [1 1 0 0 1 0]
 [1 0 1 0 0 1]]
"""
# 逆向編碼(内部維護着一個字典,存儲編碼和原資料的對應關系)
c = one_hot_encoder.inverse_transform(b)
print(c)
"""
[[1. 1. 1.]
 [1. 1. 2.]
 [1. 2. 4.]]
"""
           

6)标簽編碼

根據字元串形式的特征值在特征序列的位置,為其指定一個數字标簽,用于提供基于數值算法的學習模型

import sklearn.preprocessing as sp
label = ['cat', 'dog', 'sheep',
         'cat', 'sheep', 'dog']
label_encoder = sp.LabelEncoder()
label_normalize = label_encoder.fit_transform(label)
print(label_normalize)
"""
[0 1 2 0 2 1]
"""
# 内部自動維護字典,逆向對應原始資料
reverse_data = label_encoder.inverse_transform(label_normalize)
print(reverse_data)
"""
['cat' 'dog' 'sheep' 'cat' 'sheep' 'dog']
"""
           

OK, 以上就是一些簡單的資料預處理操作,記錄一下隻是為了有需要的時候更快的查一查。

繼續閱讀