您當前的位置:首頁 > 農業

資料分析|Python特徵工程(5)

作者:由 求知鳥 發表于 農業時間:2020-01-29

OX00 引言

資料和特徵決定了機器學習的上限,而模型和演算法只是逼近這個上限而已。由此可見,

特徵工程在機器學習中佔有相當重要的地位

。在實際應用當中,可以說特徵工程是機器學習成功的關鍵。

特徵做不好,調參調到老。重視調參,少走彎路!

特徵工程又包含了Data PreProcessing(資料預處理)、Feature Extraction(特徵提取)、Feature Selection(特徵選擇)和Feature construction(特徵構造)等子問題,而資料預處理又包括了資料清洗和特徵預處理等子問題。

資料分析|Python特徵工程(5)

OX01 標準化、歸一化與正態分佈化

sklearn中的IRIS(鳶尾花)資料集來對特徵處理功能進行說明:

from sklearn。datasets import load_iris

#匯入IRIS資料集

iris = load_iris()

#特徵矩陣

iris。data

#目標向量

iris。target

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,

2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,

2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

在sklearn中專門的用來資料歸一化的方法:StandardScaler。

from

sklearn。preprocessing

import

StandardScaler

standardScaler

=

StandardScaler

()

# 歸一化的過程跟訓練模型一樣

standardScaler

fit

X_train

standardScaler

mean_

standardScaler

scale_

# 表述資料分佈範圍的變數,替代std_

# 使用transform

X_train_standard

=

standardScaler

transform

X_train

X_test_standard

=

standardScaler

transform

X_test

無量綱化使不同規格的資料轉換到同一規格。常見的無量綱化方法有標準化和歸一化。

1。1 歸一化

最大最小【0,1】歸一化

區間縮放法利用了邊界值資訊,將屬性縮放到[0,1]。

缺點:

這種方法有一個缺陷就是當有新資料加入時,可能導致max和min的變化,需要重新定義;

MinMaxScaler對異常值的存在非常敏感。

import numpy as np

import pandas as pd

#方法一

def autoNorm(dataSet):

norm_data=(dataSet-dataSet。min(axis=0))/(dataSet。max(axis=0)-dataSet。min(axis=0))

return norm_data

train_data=np。arange(16)。reshape(4,4)

print(autoNorm(train_data))

[[0。 0。 0。 0。 ]

[0。33333333 0。33333333 0。33333333 0。33333333]

[0。66666667 0。66666667 0。66666667 0。66666667]

[1。 1。 1。 1。 ]]

Python自帶的【0,1】歸一化

from sklearn import preprocessing

import numpy as np

# 初始化資料,每一行表示一個樣本,每一列表示一個特徵

x = np。array([[ 0。, -3。, 1。],

[ 3。, 1。, 2。],

[ 0。, 1。, -1。]])

# 將資料進行 [0,1] 規範化

min_max_scaler = preprocessing。MinMaxScaler()

minmax_x = min_max_scaler。fit_transform(x)

print (minmax_x)

[[0。 0。 0。66666667]

[1。 1。 1。 ]

[0。 1。 0。 ]]

MaxAbs歸一化

單獨地縮放和轉換每個特徵,使得訓練集中的每個特徵的最大絕對值將為1。0,將屬性縮放到[-1,1]。它不會移動/居中資料,因此不會破壞任何稀疏性。

資料分析|Python特徵工程(5)

缺點:

這種方法有一個缺陷就是當有新資料加入時,可能導致max和min的變化,需要重新定義;

MaxAbsScaler與先前的縮放器不同,絕對值對映在[0,1]範圍內。

在僅有正資料時,該縮放器的行為MinMaxScaler與此類似,因此也存在大的異常值。

from

sklearn。preprocessing

import

MaxAbsScaler

maxAbsScaler

=

MaxAbsScaler

()

fit

X_train

maxAbsScaler

transform

X_train

1。2 標準化

標準化(也叫Z-score standardization,均值為0方差為1)(對列向量處理)

標準化的前提

是特徵值服從正態分佈,標準化後,其轉換成標準正態分佈。

基於原始資料的均值(mean)和標準差(standarddeviation)進行資料的標準化。將A的原始值x使用z-score標準化到x’。z-score標準化方法適用於屬性A的最大值和最小值未知的情況,或有超出取值範圍的離群資料的情況。

資料分析|Python特徵工程(5)

優點:

Z-Score最大的優點就是簡單,容易計算,Z-Score能夠應用於數值型的資料,並且不受資料量級的影響,因為它本身的作用就是消除量級給分析帶來的不便。

缺點:

估算Z-Score需要總體的平均值與方差,但是這一值在真實的分析與挖掘中很難得到,大多數情況下是用樣本的均值與標準差替代;

Z-Score對於資料的分佈有一定的要求,正態分佈是最有利於Z-Score計算的;

Z-Score消除了資料具有的實際意義,A的Z-Score與B的Z-Score與他們各自的分數不再有關係,因此Z-Score的結果只能用於比較資料間的結果,資料的真實意義還需要還原原值;

在存在異常值時無法保證平衡的特徵尺度。

def autoNorm(dataSet):

norm_data=(dataSet-dataSet。mean(axis=0))/dataSet。std(axis=0)

return norm_data

train_data=np。arange(16)。reshape(4,4)

print(autoNorm(train_data))

[[-1。34164079 -1。34164079 -1。34164079 -1。34164079]

[-0。4472136 -0。4472136 -0。4472136 -0。4472136 ]

[ 0。4472136 0。4472136 0。4472136 0。4472136 ]

[ 1。34164079 1。34164079 1。34164079 1。34164079]]

from sklearn import preprocessing

import numpy as np

# 初始化資料

x = np。array([[ 0。, -3。, 1。],

[ 3。, 1。, 2。],

[ 0。, 1。, -1。]])

# 將資料進行 Z-Score 規範化

scaled_x = preprocessing。scale(x)

print (scaled_x)

[[-0。70710678 -1。41421356 0。26726124]

[ 1。41421356 0。70710678 1。06904497]

[-0。70710678 0。70710678 -1。33630621]]

資料標準化的原因:

某些演算法要求樣本具有零均值和單位方差;

需要消除樣本不同屬性具有不同量級時的影響。

歸一化有可能提高精度; 數量級的差異將導致量級較大的屬性佔據主導地位,從而與實際情況相悖(比如這時實際情況是值域範圍小的特徵更重要);

數量級的差異將導致迭代收斂速度減慢; 當使用梯度下降法尋求最優解時,很有可能走“之字型”路線(垂直等高線走),從而導致需要迭代很多次才能收斂;

依賴於樣本距離的演算法對於資料的數量級非常敏感。

1。3 標準化與歸一化對比

相同點:

它們的相同點在於都能取消由於量綱不同引起的誤差;都是一種線性變換,都是對向量X按照比例壓縮再進行平移。

不同點:

目的不同,歸一化是為了消除綱量壓縮到[0,1]區間;

標準化只是調整特徵整體的分佈;

歸一化與最大,最小值有關;

標準化與均值,標準差有關;

歸一化輸出在[0,1]之間;

標準化無限制。

什麼時候用歸一化?什麼時候用標準化?

如果對輸出結果範圍有要求,用歸一化;

如果資料較為穩定,不存在極端的最大最小值,用歸一化;

如果資料存在異常值和較多噪音,用標準化,可以間接透過中心化避免異常值和極端值的影響。

歸一化與標準化的應用場景

在分類、聚類演算法中,需要使用距離來度量相似性的時候(如SVM、KNN)、或者使用PCA技術進行降維的時候,標準化(Z-score standardization)表現更好;

在不涉及距離度量、協方差計算、資料不符合正太分佈的時候,可以使用歸一化方法。

比如影象處理中,將RGB影象轉換為灰度影象後將其值限定在[0 255]的範圍;

基於樹的方法不需要進行特徵的歸一化。

例如隨機森林,bagging與boosting等方法。

如果是基於引數的模型或者基於距離的模型,因為需要對引數或者距離進行計算,都需要進行歸一化。

一般來說,建議優先使用標準化。對於輸出有要求時再嘗試別的方法,如歸一化或者更加複雜的方法。很多方法都可以將輸出範圍調整到[0, 1],如果我們對於資料的分佈有假設的話,更加有效的方法是使用相對應的機率密度函式來轉換。

除了上面介紹的方法外,還有一些相對沒這麼常用的處理方法:RobustScaler、PowerTransformer、QuantileTransformer和QuantileTransformer等。

1.4 正態分佈化

正態分佈化 -Normalizer,將同一行資料的不同特徵進行規範化,這樣一個數據的不同特徵具有相同的量綱

正則化的過程是將每個樣本縮放到單位範數(每個樣本的範數為1),如果要使用如二次型(點積)或者其它核方法計算兩個樣本之間的相似性這個方法會很有用。

該方法是文字分類和聚類分析中經常使用的向量空間模型(Vector Space Model)的基礎。

Normalization主要思想是對每個樣本計算其p-範數,然後對該樣本中每個元素除以該範數,這樣處理的結果是使得每個處理後樣本的p-範數(l1-norm,l2-norm)等於1。

資料分析|Python特徵工程(5)

from sklearn。preprocessing import Normalizer

#歸一化,返回值為歸一化後的資料

Normalizer()。fit_transform(iris。data)

array([[0。80377277, 0。55160877, 0。22064351, 0。0315205 ],

[0。82813287, 0。50702013, 0。23660939, 0。03380134],

[0。80533308, 0。54831188, 0。2227517 , 0。03426949],

[0。80003025, 0。53915082, 0。26087943, 0。03478392],

[0。790965 , 0。5694948 , 0。2214702 , 0。0316386 ],

#normalizer = Normalizer(norm=‘l2’)。fit(X_train)

#normalizer。transform(X_train)

from sklearn。preprocessing import Normalizer

import math

data = np。array([[1,2],[3,4],[5,6]])。reshape(3,2)

print(data)

print (data[0][0]/math。sqrt((data[0][0])**2 + (data[0][1])**2)) # 計算第一個元素L2正則化後的值

# 規範化

Normalizer()。fit_transform(data)

[[1 2]

[3 4]

[5 6]]

0。4472135954999579

Out[27]:

array([[0。4472136 , 0。89442719],

[0。6 , 0。8 ],

[0。6401844 , 0。76822128]])

參考連結:

騰訊文件

OX02 數值型特徵分箱(資料離散化)

離散化是數值型特徵非常重要的一個處理,其實就是要將數值型資料轉化成類別型資料。連續值的取值空間可能是無窮的,為了便於表示和在模型中處理,需要對連續值特徵進行離散化處理。

分箱的重要性及其優勢:

離散特徵的增加和減少都很容易,易於模型的快速迭代;

稀疏向量內積乘法運算速度快,計算結果方便儲存,容易擴充套件;

離散化後的特徵對異常資料有很強的魯棒性;

比如一個特徵是年齡>30是1,否則0。

如果特徵沒有離散化,一個異常資料“年齡300歲”會給模型造成很大的干擾;

對於線性模型,表達能力受限;

單變數離散化為N個後,每個變數有單獨的權重,相當於模型引入了非線性,能夠提升模型表達能力,加大擬合;

離散化後可以進行特徵交叉,由M+N個變數變為M*N個變數,進一步引入非線性,提升表達能力;

特徵離散化後,模型會更穩定;

比如如果對使用者年齡離散化,20-30作為一個區間,不會因為一個使用者年齡長了一歲就變成一個完全不同的人。

當然處於區間相鄰處的樣本會剛好相反,所以怎麼劃分區間是門學問;

特徵離散化以後,起到了簡化了邏輯迴歸模型的作用,降低了模型過擬合的風險;

可以將缺失作為獨立的一類帶入模型;

將所有變數變換到相似的尺度上。

2。1 無監督分箱法

自定義分箱

自定義分箱,是指根據業務經驗或者常識等自行設定劃分的區間,然後將原始資料歸類到各個區間中。

等距分箱

按照相同寬度將資料分成幾等份。

import pandas as pd

df = pd。DataFrame([[22,1],[13,1],[33,1],[52,0],[16,0],[42,1],[53,1],[39,1],[26,0],[66,0]],columns=[‘age’,‘Y’])

df[‘age_bin_2’] = pd。cut(df[‘age’],3) #新增一列儲存等距劃分的分箱特徵

display(df)

# 輸出

age Y age_bin

0 22 1 (12。947, 30。667]

1 13 1 (12。947, 30。667]

2 33 1 (30。667, 48。333]

3 52 0 (48。333, 66。0]

4 16 0 (12。947, 30。667]

5 42 1 (30。667, 48。333]

6 53 1 (48。333, 66。0]

7 39 1 (30。667, 48。333]

8 26 0 (12。947, 30。667]

9 66 0 (48。333, 66。0]

等頻分箱

將資料分成幾等份,每等份資料裡面的個數是一樣的。

import pandas as pd

df = pd。DataFrame([[22,1],[13,1],[33,1],[52,0],[16,0],[42,1],[53,1],[39,1],[26,0],[66,0]],columns=[‘age’,‘Y’])

df[‘age_bin_1’] = pd。qcut(df[‘age’],3) #新增一列儲存等頻劃分的分箱特徵

display(df)

# 輸出

age Y age_bin

0 22 1 (12。999, 26。0]

1 13 1 (12。999, 26。0]

2 33 1 (26。0, 42。0]

3 52 0 (42。0, 66。0]

4 16 0 (12。999, 26。0]

5 42 1 (26。0, 42。0]

6 53 1 (42。0, 66。0]

7 39 1 (26。0, 42。0]

8 26 0 (12。999, 26。0]

9 66 0 (42。0, 66。0]

聚類分箱

基於k均值聚類的分箱:k均值聚類法將觀測值聚為k類,但在聚類過程中需要保證分箱的有序性:第一個分箱中所有觀測值都要小於第二個分箱中的觀測值,第二個分箱中所有觀測值都要小於第三個分箱中的觀測值,等等。

實現步驟

Step 0:

對預處理後的資料進行歸一化處理;

Step 1:

將歸一化處理過的資料,應用k-means聚類演算法,劃分為多個區間:

採用等距法設定k-means聚類演算法的初始中心,得到聚類中心;

Step 2:

在得到聚類中心後將相鄰的聚類中心的中點作為分類的劃分點,將各個物件加入到距離最近的類中,從而將資料劃分為多個區間;

Step 3:

重新計算每個聚類中心,然後重新劃分資料,直到每個聚類中心不再變化,得到最終的聚類結果。

from sklearn。cluster import KMeans

kmodel=KMeans(n_clusters=k) #k為聚成幾類

kmodel。fit(data。reshape(len(data),1))) #訓練模型

c=pd。DataFrame(kmodel。cluster_centers_) #求聚類中心

c=c。sort_values(by=’列索引‘) #排序

w=pd。rolling_mean(c,2)。iloc[1:] #用滑動視窗求均值的方法求相鄰兩項求中點,作為邊界點

w=[0] +list(w[0] + [ data。max() ] #把首末邊界點加上

d3= pd。cut(data,w,labels=range(k)) #cut函式

2。2 二值化

二值化可以將數值型(numerical)的feature進行閥值化得到boolean型資料。這對於下游的機率估計來說可能很有用(比如:資料分佈為Bernoulli分佈時)。

資料分析|Python特徵工程(5)

對定量特徵二值化(對列向量處理)

’‘’

定性與定量區別 定性:博主很胖,博主很瘦

定量:博主有80kg,博主有60kg

‘’‘

from sklearn。preprocessing import Binarizer

#二值化,閾值設定為3,返回值為二值化後的資料 ;>3顯示為1,否則為0

print(iris。data)

Binarizer(threshold=3)。fit_transform(iris。data)

對定性特徵啞編碼(對列向量處理)

from sklearn。preprocessing import OneHotEncoder

#啞編碼,對IRIS資料集的目標值,返回值為啞編碼後的資料

print(OneHotEncoder()。fit_transform(iris。target。reshape((-1,1))))

2。3 有監督分箱法

2.3.1 卡方分箱法

自底向上的(即基於合併的)資料離散化方法。它依賴於卡方檢驗:具有最小卡方值的相鄰區間合併在一起,直到滿足確定的停止準則。

https://

github。com/tatsumiw/Chi

Merge/blob/master/ChiMerge。py

2.3.2 最小熵法分箱

需要使總熵值達到最小,也就是使分箱能夠最大限度地區分因變數的各類別。

熵是資訊理論中資料無序程度的度量標準,提出資訊熵的基本目的是找出某種符號系統的資訊量和冗餘度之間的關係,以便能用最小的成本和消耗來實現最高效率的資料儲存、管理和傳遞。

資料集的熵越低,說明資料之間的差異越小,最小熵劃分就是為了使每箱中的資料具有最好的相似性。給定箱的個數,如果考慮所有可能的分箱情況,最小熵方法得到的箱應該是具有最小熵的分箱。

2。4 小結

我們對特徵進行分箱後,需要對分箱後的每組(箱)進行woe編碼和IV值的計算,透過IV值進行變數篩選後,然後才能放進模型訓練。

分箱後需要進行特徵編碼,如:

LabelEncode、OneHotEncode或LabelBinarizer等。

OX03 其它特徵變換方法

多項式變換(對行向量處理)

’‘’

在多元迴歸分析中, 當特徵不滿足線性,可以多特徵進行多項式變換

‘’‘

from sklearn。preprocessing import PolynomialFeatures

#多項式轉換

#引數degree為度,預設值為2

PolynomialFeatures()。fit_transform(iris。data)

from numpy import log1p

from sklearn。preprocessing import FunctionTransformer

#自定義轉換函式為對數函式的資料變換

#第一個引數是單變元函式

FunctionTransformer(log1p)。fit_transform(iris。data)

Box-Cox變換(對因變數處理)

from scipy。stats import boxcox_normmax

from scipy。special import boxcox1p

lambda_2=boxcox_normmax(test。B)

print(lambda_2)

test。B=boxcox1p(test。B,lambda_2)

print(test)

print(test。skew(axis=0))

OUT:

0。9999999595600494

A B c

0 1 5。033370 4

1 2 17。332385 5

2 3 26。623161 6

3 4 5。033370 7

A 0。000000

B 0。633103

c 0。000000

dtype: float64

特徵工程這篇文件比較全面:

sklearn中的資料預處理和特徵工程 - 是安醬和菜菜呀 - 部落格園

11種降維方法(未寫)

特徵選擇方法(待補充)

選擇特徵的角度很多:變數的預測能力,變數之間的相關性,變數的簡單性(容易生成和使用),變數的強壯性(不容易被繞過),變數在業務上的可解釋性(被挑戰時可以解釋的通)等等。但是,其中最主要和最直接的衡量標準是變數的預測能力。

預測能力衡量:IV值,資訊增益,基尼係數等;

1、 特徵選擇:特徵發散,如果一個特徵不發散,方差為0,說明樣本在這個特徵上基本沒有差異,這個特徵對於樣本區分基本沒用

2、 特徵選擇:考慮特徵與目標的相關性,優先選擇與目標相關性高的特徵!

3、 根據方差選擇特徵:計算各個特徵的方差,選擇方差大於閾值的特徵

4、 單變數特徵選擇:計算每個特徵與y的相關性;對於迴歸問題或分類問題可以採用卡方檢驗的方式對特徵進行檢測

5、 皮爾遜相關係數(適用於迴歸問題即y連續),簡單實用

6、 基於模型的特徵融合方法:主成分分析,聚類,支援向量機,隨機森林都可以作為篩選特徵的方法

未完待續……

最後,歡迎關注我的資料分析專欄,目前已經超過1000+小夥伴聚集在這裡學習了

標簽: 歸一化  特徵  分箱  資料  data