Hike News
Hike News

機器學習-特徵工程-特徵預處理

Introduction

  • 特徵預處理通常是對數據進行處理

    通過特定的統計方法(數學方法)數據轉換成演算法要求的數據

  • 特徵預處理

    數值型數據:採用標準縮放 分為歸一化(normalization)標準化(standardization) 兩種,通常也要同時處理缺失值
    類別型的數據:one-hot編碼
    時間類型數據:對時間進行切分

  • 使用sklearn自帶的特徵預處理API進行處理

數據無量綱化

  • 不同規格的數據轉換到同一規格的需求
    • 例如:希望所有數據服從標準正態分佈
  • 不同分佈的數據轉換到某個特定分佈的需求
    • 例如:希望所有值位於1-0之間
      以上兩種需求統稱為無量綱化

效果

  • 梯度和矩陣為核心模型:邏輯回歸,SVM,神經網路等,無量綱化可加快求解速度
  • 距離類模型:KNN,K-means聚類等,無量綱化可提升模型經度
  • 決策樹和樹的集成演算法們,不需無量綱化

sklearn特徵預處理

所有特徵預處理的方法皆收錄在sklearn.preprocessing


歸一化(normalize)

  • 通常對原始數據進行變換把數據映射至預設為[0,1]之間
  • 應用場景:在數萬筆數據中某些特徵都是同等重要時,就需將這幾種特徵歸一化處理,不會使單一特徵完全的影響最終結果
  • 公式:
  • $max$為一系列的最大值;$min$為一系列的最小值
  • $X^”$為最終結果
  • $mx$,$mi$分別為指定區間的預設值,$mx$為1,$mi$為0
  • 使用sklearn.preprocessing.MinMaxScaler

MinMaxScalar(feature_range=(0,1)…)

  • 每個特徵縮放到給定的範圍內(預設[0,1])
  • 可自己更改normalize的範圍(feature_range(最小值,最大值))

fit_transform(X)

  • X: numpy array格式的數據[n_samples, n_features]
  • 返回值:轉換後的同shape的array

inverse_transform(X)

  • X: numpy array格式的數據(歸一化後的數據)
  • 返回值: 歸一化前的數據

流程

  1. 實例化MinMaxScalar
  2. 通過fit_transform轉換

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from sklearn.preprocessing import MinMaxScaler

data = [[90,2,1000,0.8],[120,5,2500,0.75],[45,10,1800,0.38]]

#Normalize
def MMScale():

# 實例化
MM = MinMaxScaler()

# 調用fit_transform
scale_data = MM.fit_transform(data)

print(scale_data)


if __name__ == '__main__':
MMScale()

返回normalize的結果

1
2
3
[[0.6        0.         0.         1.        ]
[1. 0.375 1. 0.88095238]
[0. 1. 0.53333333 0. ]]

tips

  • Normalize方法對於異常點的處理效果不好
    • 異常點可能會改變最大值與最小值造成結果整體大幅的改動,因此穩定性較差
    • 較適合傳統精確小數據的場景
    • 當X中特徵數量非常多時候,fit會報錯並表示數據量太大無法計算
      • 使用partial_fit(X)方法作為訓練的接口

標準化(standardization)

  • 標準化相對歸一化較常見也較常使用
  • 又稱 Z-score normalization

    數據x按均值($mean$)中心化後,再按標準差($\sigma$)縮放
    平均值不容易受到異常點的影響

  • 特點:通過對原始數據進行變換把數據變換到均值為0,標準差為1的範圍內

  • 公式:
    • $\sigma$ 為標準差
    • $\sigma = \sqrt{var}$
  • 使用sklearn.preprocessing.StandardScaler

方差

  • 方差小代表數據叫集中;反之則數據比較離散
  • 如果出現異常點,由於原本就具有一定數據量,少量的異常點對於平均值的影響並不大,使得方差改變較小

StandardScaler(…)

  • 處理之後每列的數據都聚集在$mean$為0附近且$\sigma$標準差為1

fit(X)

生成均值方差

  • X: numpy array格式的數據[n_samples, n_features]

fit_transform(X)

  • X: numpy array格式的數據[n_samples, n_features]
  • 返回值:轉換後同shape的array

mean_

  • 查看原始數據中每列特特徵的平均值

var_

  • 查看原始數據中每列特徵的方差

流程

  1. 實例化StandardScaler
  2. 通過fit_transform轉換

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sklearn.preprocessing import StandardScaler

data = [[90,2,1000,0.8],[120,5,2500,0.75],[45,10,1800,0.38]]

def StdScale():
# 實例化
SS = StandardScaler()

# 調用fit_transform
scale_data = SS.fit_transform(data)

print("Result: \n",scale_data)
print("Mean: \n",SS.mean_)

if __name__ == '__main__':
StdScale()

返回標準化後的矩陣

1
2
3
4
5
6
Result: 
[[ 0.16222142 -1.1111678 -1.25103507 0.83635719]
[ 1.13554995 -0.20203051 1.19664225 0.56943468]
[-1.29777137 1.31319831 0.05439283 -1.40579187]]
Mean:
[8.50000000e+01 5.66666667e+00 1.76666667e+03 6.43333333e-01]

tips

在以有樣本足夠多的情況下比較穩定,適合現代嘈雜大數據的場景

缺失值

處理缺失值只有兩種方法

  1. 刪除
    • 如果每列或者行數據缺失值達到一定的比例,建議放棄整行或整列
    • 如果本身數據量少,較不適合直接刪除
  2. 插補
    • 可以通過每行或者每列的平均值或者中位數來填充(一般都是使用列填補)
  • 使用sklearn.preprocessing.Imputer

Imputer(missing_values=’Nan’,strategy=’mean’,axis=0)

完成缺失值插補

  • missing_values: 對什麼進行填補,預設為Nan值
  • strategy: 填補策略,預設使用平均值
  • axis: 針對行或列進行填補,預設使用列

fit_transform(X)

  • X: numpy array格式的數據[n_samples, n_features]
  • 返回值:轉換後同shape的array
  • 缺失值類型應為np.nan類型,才能填補

流程

  1. 初始化Imputer
    • 指定missing_values
    • 指定填補策略(strategy)
    • 指定針對行或列填補
    • 注意:缺失值也可以是別的指定要替換的值,不一定為Nan
  2. 調用fit_transform

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.preprocessing import Imputer
import numpy as np

HasNanData = [[np.nan,2,1000,0.8],[120,5,np.nan,0.75],[45,10,1800,0.38]]

# 缺失值處理
def fill_nan():
fill = Imputer()
Data = fill.fit_transform(HasNanData)
print(Data)

if __name__ == '__main__':
fill_nan()

填補結果

1
2
3
[[8.25e+01 2.00e+00 1.00e+03 8.00e-01]
[1.20e+02 5.00e+00 1.40e+03 7.50e-01]
[4.50e+01 1.00e+01 1.80e+03 3.80e-01]]

tips

  • np.nan
    • numpy的陣列中可以使用np.nan/np.Nan來代替缺失值
    • np.nan屬於float類型
    • 如果是文件中的缺失值,可以替換成nan,通過np.nan轉化為float型的陣列即可