機器學習——數據預處理


數據預處理

數據預處理的過程: 輸入數據 -> 模型 -> 輸出數據

如下圖所示為數據樣本矩陣,則一行一樣本,一列一特征。機器學習中有一個數據預處理的庫,是一個解決機器學習問題的科學計算工具包 sklearn.preprocessing

年齡 學歷 經驗 性別 月薪
25 碩士 2 10000
20 本科 3 8000
... ... ... ... ...

均值移除(標准化)

由於一個樣本的不同特征值差異較大,不利於使用現有機器學習算法進行樣本處理。均值移除可以讓樣本矩陣中的每一列的平均值為0,標准差為1。

例如有一列特征值表示年齡: 17, 20, 23,在不使用庫的情況下,如何使樣本矩陣中的每一列的平均值為0呢?

mean = (17 + 20 + 23)/3 = 20
a' = 17 - 20 = -3
b' =  20 - 20 = 0
c' =  23 - 20 = 3

如何使樣本矩陣中的每一列的標准差為1呢?

s = std(a', b', c') 
[a'/s,  b'/s,  c'/s]

我們可以使用sklearn.processing.scale均值移除函數一步實現,均值移除API:

raw_samples = np.array([
    [17., 100., 4000],
    [20., 80., 5000],
    [23., 75., 5500]])

std_samples = sp.scale(raw_samples)
# [[-1.22474487  1.38873015 -1.33630621]
#  [ 0.         -0.46291005  0.26726124]
#  [ 1.22474487 -0.9258201   1.06904497]]

print(std_samples.mean(axis=0))     # [ 0.00000000e+00 -3.70074342e-17  5.18104078e-16]
print(std_samples.std(axis=0))      # [ 0.00000000e+00 -3.70074342e-17  5.18104078e-16]

范圍縮放

  將樣本矩陣中的每一列的最小值和最大值設定為相同的區間,統一各列特征值的范圍。一般情況下會把特征值縮放至[0, 1]區間。

例如有一列特征值表示年齡: [17, 20, 23],每個元素減去特征值數組所有元素的最小值,即可使一組特征值的最小值為0

$$[17-17, 20-17, 23-17]-->[0, 3, 6]$$

把特征值數組的每個元素除以最大值即可使一組特征值的最大值為1

$$[\frac{0}{6}, \frac{3}{6}, \frac{6}{6}]-->[0, \frac{1}{2}, 1]$$

sklearn.preprocessing.MinMaxScaler范圍縮放API:

# 創建MinMax縮放器
mms = sp.MinMaxScaler(feature_range=(0, 1))
# 調用mms對象的方法執行縮放操作, 返回縮放過后的結果
result = mms.fit_transform(原始樣本矩陣)

案例:

import numpy as np
import sklearn.preprocessing as sp

raw_samples = np.array([[17., 100., 4000],
                        [20., 80., 5000],
                        [23., 75., 5500]])
# 根據給定范圍創建一個范圍縮放器
mms = sp.MinMaxScaler(feature_range=(0, 1))
# 用范圍縮放器實現特征值的范圍縮放
mms_samples = mms.fit_transform(raw_samples)
# [[0.         1.         0.        ]
#  [0.5        0.2        0.66666667]
#  [1.         0.         1.        ]]

歸一化

  把需要處理的數據經過處理后(通過某種算法)限制在一定范圍內。首先歸一化是為了后面數據處理的方便,其次是保正程序運行時收斂加快。同時有些情況每個樣本的每個特征值 具體的值並不重要,但是每個樣本特征值的占比更加重要。歸一化一般來說有兩種做法:

第一種做法將輸入轉化到范圍 [0, 1] 之間

$$y=\frac{x-x_{min}}{x_{max}-x_{min}}$$

公式中$x_{max}$表示輸入值的最大值,$x_{min}$表示輸入值的最小值,這種方法還是會保持輸入大於等於0。這種歸一化一般用於圖像處理

第一種做法將輸入轉化到范圍 [-1, 1] 之間

$$y=\frac{x-x_{avg}}{x_{max}-x_{min}}$$

公式中$x_{avg}$表示輸入值的平均值,那么經過這種歸一化之后,輸入會產生負值。這種歸一化一般用於音頻處理

  我們先來講解第一種歸一化方法

  python Java PHP
2017 10 20 5
2018 8 5 0

變換后的樣本矩陣,每個樣本的特征值絕對值之和為1。

sklearn.preprocessing.normalize(array, norm='l1')

參數:

  • array 原始樣本矩陣
  • norm 范數:
    • l1:l1范數,向量中個元素絕對值之和;
    • l2:l2范數,向量中個元素平方之和

返回歸一化預處理后的樣本矩陣

import numpy as np
import sklearn.preprocessing as sp

raw_samples = np.array([[17., 100., 4000],
                        [20., 80., 5000],
                        [23., 75., 5500]])

# 歸一化預處理
nor_samples = sp.normalize(raw_samples, norm='l1')
# [[0.00412922 0.02428953 0.97158125]
#  [0.00392157 0.01568627 0.98039216]
#  [0.00410861 0.01339764 0.98249375]]
print(abs(nor_samples).sum(axis=1))  # [1. 1. 1.]

標准化

  對原始數據進行縮放處理,限制在一定的范圍內。一般指正態化,即均值為0,方差為1。即使數據不符合正態分布,也可以采用這種方式方法,標准化后的數據有正有負

二值化

有些業務並不需要分析矩陣的詳細完整數據(比如圖像邊緣識別只需要分析出圖像邊緣即可),可以根據一個事先給定的閾值,用0和1表示特征值不高於或高於閾值。二值化后的數組中每個元素非0即1,達到簡化數學模型,較少后面數據計算量的目的。

bin = sklearn.preprocessing.Binarizer(threshold=閾值)  給出閾值, 獲取二值化器

  • 調用transform方法對原始樣本矩陣進行二值化預處理操作

result = bin.transform(原始樣本矩陣)

import numpy as np
import sklearn.preprocessing as sp

raw_samples = np.array([[17., 100., 4000],
                        [20., 80., 5000],
                        [23., 75., 5500]])

bin = sp.Binarizer(threshold=80)  # 根據給定的閾值創建一個二值化器
bin_samples = bin.transform(raw_samples)  # 通過二值化器進行二值化預處理
# [[0. 1. 1.]
#  [0. 0. 1.]
#  [0. 0. 1.]]

獨熱編碼

獨熱編碼獨熱編碼(one-hot encoding)為樣本特征的每個值建立一個由一個1和若干個0組成的序列,用該序列對所有的特征值進行編碼。

也可以理解為將一個值轉化為概率分布的向量,一般用於分類問題。

samples = np.array([[1., 3., 2],
                   [7., 5., 4],
                   [1., 8., 6],
                   [7., 8., 9.]])
兩種數 三種數 四種數
1 3 2
7 5 4
1 8 6
7 3 9

為每一個數字進行獨熱編碼:

1-10   3-100  2-1000
7-01   5-010  4-0100
       8-001       6-0010
                          9-0001
編碼完畢后得到最終經過獨熱編碼后的樣本矩陣
101001000
010100100
100010010
011000001

ohe = sklearn.preprocessing.OneHotEncoder(sparse=是否采用緊縮格式, dtype=數據類型) 創建一個獨熱編碼器

參數:

  • sparse: 是否使用緊縮格式(稀疏矩陣)
  • dtyle: 數據類型

方法:

  • result = ohe.fit_transform(原始樣本矩陣)    對原始樣本矩陣進行處理,返回獨熱編碼后的樣本矩陣。
  • encode_dict = ohe.fit(原始樣本矩陣)       對原始樣本矩陣進行訓練,得到編碼字典
  • result = encode_dict.transform(原始樣本矩陣)  調用encode_dict字典的transform方法 對數據樣本矩陣進行獨熱編碼
import numpy as np
import sklearn.preprocessing as sp

raw_samples = np.array([[17., 100., 4000],
                        [20., 80., 5000],
                        [23., 75., 5500]])

ohe = sp.OneHotEncoder(sparse=False, dtype=int)  # 創建獨熱編碼器
# 方法1
ohe_dict = ohe.fit(raw_samples)
result1 = ohe_dict.transform(raw_samples)
print(result1)
# 方法2
result2 = ohe.fit_transform(raw_samples)
print(result2)
# [[1 0 0 0 0 1 1 0 0]
#  [0 1 0 0 1 0 0 1 0]
#  [0 0 1 1 0 0 0 0 1]]

標簽編碼

根據字符串形式的特征值在特征序列中的位置,為其指定一個數字標簽,用於提供給基於數值算法的學習模型。

lbe = sklearn.preprocessing.LabelEncoder()  獲取標簽編碼器

方法:

  • result = lbe.fit_transform(原始樣本矩陣)    訓練並且為原始樣本矩陣進行標簽編碼
  • samples = lbe.inverse_transform(result)    根據標簽編碼的結果矩陣反查字典 得到原始數據矩陣
import numpy as np
import sklearn.preprocessing as sp

raw_samples = np.array(['audi', 'ford', 'audi', 'toyota', 'ford', 'bmw', 'toyota', 'ford', 'audi'])

lbe = sp.LabelEncoder()
lbe_samples = lbe.fit_transform(raw_samples)
# [0 2 0 3 2 1 3 2 0]
inv_samples = lbe.inverse_transform(lbe_samples)
# ['audi' 'ford' 'audi' 'toyota' 'ford' 'bmw' 'toyota' 'ford' 'audi']

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM