用sklearn做特徵工程

注意:

按照教程跑一個代碼的時候報如下錯誤

TypeError: fit_transform() missing 1 required positional argument :‘X’

原因

    from sklearn.preprocessing import StandardScaler
    from sklearn.neighbors import KNeighborsClassifier
    ss = StandardScaler()
    x_train = ss.fit_transform(x_train)
    x_test = ss.transform(x_test)

第三行使用StandardScaler函數沒有加括號。
 

前言

博主最近參加了幾個kaggle比賽,發現做特徵工程是其中很重要的一部分,而sklearn是做特徵工程(做模型調算法)最常用也是最好用的工具沒有之一,因此將自己的一些經驗做一個總結分享給大家,希望對大家有所幫助
目錄
1. 什麼是特徵工程?
2. 數據預處理
3. 特徵選擇
4. 降維
1. 什麼是特徵工程?

有這麼一句話在業界廣泛流傳,數據和特徵決定了機器學習的上限,而模型和算法只是逼近這個上限而已。那特徵工程到底是什麼呢?顧名思義,其本質是一項工程活動,目的是最大限度地從原始數據中提取特徵以供算法和模型使用。


特徵工程主要分爲三部分:
1. 數據預處理 對應的sklearn包:sklearn-Processing data
1. 特徵選擇 對應的sklearn包: sklearn-Feature selection
1. 降維 對應的sklearn包: sklearn-Dimensionality reduction


本文中使用sklearn中的IRIS(鳶尾花)數據集來對特徵處理功能進行說明導入IRIS數據集的代碼如下:

 1 from sklearn.datasets import load_iris
 2 
 3 #導入IRIS數據集
 4 iris = load_iris()
 5 
 6 #特徵矩陣
 7 iris.data
 8 
 9 #目標向量
10 iris.target

 

2. 數據預處理

通過特徵提取,我們能得到未經處理的特徵,這時的特徵可能有以下問題:

    不屬於同一量綱:即特徵的規格不一樣,不能夠放在一起比較。無量綱化可以解決這一問題。
    信息冗餘:對於某些定量特徵,其包含的有效信息爲區間劃分,例如學習成績,假若只關心“及格”或不“及格”,那麼需要將定量的考分,轉換成“1”和“0”表示及格和未及格。二值化可以解決這一問題。
    定性特徵不能直接使用:通常使用啞編碼的方式將定性特徵轉換爲定量特徵,假設有N種定性值,則將這一個特徵擴展爲N種特徵,當原始特徵值爲第i種定性值時,第i個擴展特徵賦值爲1,其他擴展特徵賦值爲0。啞編碼的方式相比直接指定的方式,不用增加調參的工作,對於線性模型來說,使用啞編碼後的特徵可達到非線性的效果。
    存在缺失值:填充缺失值。
    信息利用率低:不同的機器學習算法和模型對數據中信息的利用是不同的,之前提到在線性模型中,使用對定性特徵啞編碼可以達到非線性的效果。類似地,對定量變量多項式化,或者進行其他的數據變換,都能達到非線性的效果。

我們使用sklearn中的preproccessing庫來進行數據預處理。
2.1 無量綱化

無量綱化使不同規格的數據轉換到同一規格
2.1.1 標準化(也叫Z-score standardization)(對列向量處理)

將服從正態分佈的特徵值轉換成標準正態分佈,標準化需要計算特徵的均值和標準差,公式表達爲:

使用preproccessing庫的StandardScaler類對數據進行標準化的代碼如下:

1 from sklearn.preprocessing import StandardScaler
2 
3 #標準化,返回值爲標準化後的數據
4 StandardScaler().fit_transform(iris.data)

 

2.1.2 區間縮放(對列向量處理)

區間縮放法的思路有多種,常見的一種爲利用兩個最值進行縮放,公式表達爲:

使用preproccessing庫的MinMaxScaler類對數據進行區間縮放的代碼如下:

1 from sklearn.preprocessing import MinMaxScaler
2 
3 #區間縮放,返回值爲縮放到[0, 1]區間的數據
4 MinMaxScaler().fit_transform(iris.data)

 

在什麼時候使用標準化比較好,什麼時候區間縮放比較好呢?

1、在後續的分類、聚類算法中,需要使用距離來度量相似性的時候、或者使用PCA、LDA這些需要用到協方差分析進行降維的時候,同時數據分佈可以近似爲正太分佈,標準化方法(Z-score standardization)表現更好。
2、在不涉及距離度量、協方差計算、數據不符合正太分佈的時候,可以使用區間縮放法或其他歸一化方法。比如圖像處理中,將RGB圖像轉換爲灰度圖像後將其值限定在[0 255]的範圍。
2.1.3 歸一化(對行向量處理)

歸一化目的在於樣本向量在點乘運算或其他核函數計算相似性時,擁有統一的標準,也就是說都轉化爲“單位向量”。規則爲l2的歸一化公式如下:

使用preproccessing庫的Normalizer類對數據進行歸一化的代碼如下:

1 from sklearn.preprocessing import Normalizer
2 
3 #歸一化,返回值爲歸一化後的數據
4 Normalizer().fit_transform(iris.data)

 

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

定性與定量區別

定性:博主很胖,博主很瘦

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

一般定性都會有相關的描述詞,定量的描述都是可以用數字來量化處理


定量特徵二值化的核心在於設定一個閾值,大於閾值的賦值爲1,小於等於閾值的賦值爲0,公式表達如下:

使用preproccessing庫的Binarizer類對數據進行二值化的代碼如下:

1 from sklearn.preprocessing import Binarizer
2 
3 #二值化,閾值設置爲3,返回值爲二值化後的數據
4 Binarizer(threshold=3).fit_transform(iris.data)

 

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

因爲有些特徵是用文字分類表達的,或者說將這些類轉化爲數字,但是數字與數字之間是沒有大小關係的,純粹的分類標記,這時候就需要用啞編碼對其進行編碼。IRIS數據集的特徵皆爲定量特徵,使用其目標值進行啞編碼(實際上是不需要的)。使用preproccessing庫的OneHotEncoder類對數據進行啞編碼的代碼如下:

1 from sklearn.preprocessing import OneHotEncoder
2 
3 #啞編碼,對IRIS數據集的目標值,返回值爲啞編碼後的數據
4 OneHotEncoder().fit_transform(iris.target.reshape((-1,1)))

 

2.4 缺失值計算(對列向量處理)

由於IRIS數據集沒有缺失值,故對數據集新增一個樣本,4個特徵均賦值爲NaN,表示數據缺失。使用preproccessing庫的Imputer類對數據進行缺失值計算的代碼如下:

1 from numpy import vstack, array, nan
2 from sklearn.preprocessing import Imputer
3 
4 #缺失值計算,返回值爲計算缺失值後的數據
5 #參數missing_value爲缺失值的表示形式,默認爲NaN
6 #參數strategy爲缺失值填充方式,默認爲mean(均值)
7 Imputer().fit_transform(vstack((array([nan, nan, nan, nan]), iris.data)))

 

2.5 數據變換
2.5.1 多項式變換(對行向量處理)

常見的數據變換有基於多項式的、基於指數函數的、基於對數函數的。4個特徵,度爲2的多項式轉換公式如下:

使用preproccessing庫的PolynomialFeatures類對數據進行多項式轉換的代碼如下:

1 from sklearn.preprocessing import PolynomialFeatures
2 
3 #多項式轉換
4 #參數degree爲度,默認值爲2
5 PolynomialFeatures().fit_transform(iris.data)

 

2.5.1 自定義變換

基於單變元函數的數據變換可以使用一個統一的方式完成,使用preproccessing庫的FunctionTransformer對數據進行對數函數轉換的代碼如下:

1 from numpy import log1p
2 from sklearn.preprocessing import FunctionTransformer
3 
4 #自定義轉換函數爲對數函數的數據變換
5 #第一個參數是單變元函數
6 FunctionTransformer(log1p).fit_transform(iris.data)

 

總結
類     功能     說明
StandardScaler     無量綱化     標準化,基於特徵矩陣的列,將特徵值轉換至服從標準正態分佈
MinMaxScaler     無量綱化     區間縮放,基於最大最小值,將特徵值轉換到[0, 1]區間上
Normalizer     歸一化     基於特徵矩陣的行,將樣本向量轉換爲“單位向量”
Binarizer     二值化     基於給定閾值,將定量特徵按閾值劃分
OneHotEncoder     啞編碼     將定性數據編碼爲定量數據
Imputer     缺失值計算     計算缺失值,缺失值可填充爲均值等
PolynomialFeatures     多項式數據轉換     多項式數據轉換
FunctionTransformer     自定義單元數據轉換     使用單變元的函數來轉換數據
3. 特徵選擇

當數據預處理完成後,我們需要選擇有意義的特徵輸入機器學習的算法和模型進行訓練。通常來說,從兩個方面考慮來選擇特徵:

    特徵是否發散:如果一個特徵不發散,例如方差接近於0,也就是說樣本在這個特徵上基本上沒有差異,這個特徵對於樣本的區分並沒有什麼用。
    特徵與目標的相關性:這點比較顯見,與目標相關性高的特徵,應當優選選擇。除方差法外,本文介紹的其他方法均從相關性考慮。

根據特徵選擇的形式又可以將特徵選擇方法分爲3種:

    Filter:過濾法,不用考慮後續學習器,按照發散性或者相關性對各個特徵進行評分,設定閾值或者待選擇閾值的個數,選擇特徵。
    Wrapper:包裝法,需考慮後續學習器,根據目標函數(通常是預測效果評分),每次選擇若干特徵,或者排除若干特徵。
    Embedded:嵌入法,是Filter與Wrapper方法的結合。先使用某些機器學習的算法和模型進行訓練,得到各個特徵的權值係數,根據係數從大到小選擇特徵。

我們使用sklearn中的feature_selection庫來進行特徵選擇。
3.1 Filter
3.1.1 方差選擇法

使用方差選擇法,先要計算各個特徵的方差,然後根據閾值,選擇方差大於閾值的特徵。使用feature_selection庫的VarianceThreshold類來選擇特徵的代碼如下:

1 from sklearn.feature_selection import VarianceThreshold
2 
3 #方差選擇法,返回值爲特徵選擇後的數據
4 #參數threshold爲方差的閾值
5 VarianceThreshold(threshold=3).fit_transform(iris.data)

 

3.1.2 卡方檢驗

檢驗特徵對標籤的相關性,選擇其中K個與標籤最相關的特徵。使用feature_selection庫的SelectKBest類結合卡方檢驗來選擇特徵的代碼如下:

1 from sklearn.feature_selection import SelectKBest
2 from sklearn.feature_selection import chi2
3 
4 #選擇K個最好的特徵,返回選擇特徵後的數據
5 SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target)

 

3.2 Wrapper
3.2.1 遞歸特徵消除法

遞歸消除特徵法使用一個基模型來進行多輪訓練,每輪訓練後,消除若干權值係數的特徵,再基於新的特徵集進行下一輪訓練。使用feature_selection庫的RFE類來選擇特徵的代碼如下:

1 from sklearn.feature_selection import RFE
2 from sklearn.linear_model import LogisticRegression
3 
4 #遞歸特徵消除法,返回特徵選擇後的數據
5 #參數estimator爲基模型
6 #參數n_features_to_select爲選擇的特徵個數
7 RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(iris.data, iris.target)

 

3.3 Embedded
3.3.1 基於懲罰項的特徵選擇法

使用帶懲罰項的基模型,除了篩選出特徵外,同時也進行了降維。使用feature_selection庫的SelectFromModel類結合帶L1懲罰項的邏輯迴歸模型,來選擇特徵的代碼如下:

1 from sklearn.feature_selection import SelectFromModel
2 from sklearn.linear_model import LogisticRegression
3 
4 #帶L1懲罰項的邏輯迴歸作爲基模型的特徵選擇
5 SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(iris.data, iris.target)

 

3.3.2 基於樹模型的特徵選擇法

樹模型中GBDT可用來作爲基模型進行特徵選擇,使用feature_selection庫的SelectFromModel類結合GBDT模型,來選擇特徵的代碼如下:

1 from sklearn.feature_selection import SelectFromModel
2 from sklearn.ensemble import GradientBoostingClassifier
3 
4 #GBDT作爲基模型的特徵選擇
5 SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)

 

總結

所屬方式 說明
VarianceThreshold Filter 方差選擇法
SelectKBest Filter 可選關聯繫數、卡方校驗、最大信息係數作爲得分計算的方法
RFE Wrapper 遞歸地訓練基模型,將權值係數較小的特徵從特徵集合中消除
SelectFromModel Embedded 訓練基模型,選擇權值係數較高的特徵


4. 降維

當特徵選擇完成後,可以直接訓練模型了,但是可能由於特徵矩陣過大,導致計算量大,訓練時間長的問題,因此降低特徵矩陣維度也是必不可少的。常見的降維方法除了以上提到的基於L1懲罰項的模型以外,另外還有主成分分析法(PCA)和線性判別分析(LDA),線性判別分析本身也是一個分類模型。PCA和LDA有很多的相似點,其本質是要將原始的樣本映射到維度更低的樣本空間中,但是PCA和LDA的映射目標不一樣:PCA是爲了讓映射後的樣本具有最大的發散性;而LDA是爲了讓映射後的樣本有最好的分類性能。所以說PCA是一種無監督的降維方法,而LDA是一種有監督的降維方法。
4.1 主成分分析法(PCA)

使用decomposition庫的PCA類選擇特徵的代碼如下:

1 from sklearn.decomposition import PCA
2 
3 #主成分分析法,返回降維後的數據
4 #參數n_components爲主成分數目
5 PCA(n_components=2).fit_transform(iris.data)

 

4.2 線性判別分析法(LDA)

使用LDA進行降維的代碼如下:

1 from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
2 
3 #線性判別分析法,返回降維後的數據
4 #參數n_components爲降維後的維數
5 LDA(n_components=2).fit_transform(iris.data, iris.target)

總結 

說明
decomposition PCA 主成分分析法
lda LDA 線性判別分析法

 

以上代碼都已在github上實現:https://github.com/fuqiuai/kaggle-feature-engineering/blob/master/feature_engineering.py
————————————————
版權聲明:本文爲CSDN博主「fuqiuai」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/fuqiuai/article/details/79496005

發佈了37 篇原創文章 · 獲贊 15 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章