如何進行特徵選擇|機器學習

特徵選擇

爲什麼要進行特徵選擇

  • 我們在現實任務中經常會遇到維數災難的問題,這是由於屬性過多而造成的,若能從中選擇出重要的特徵,使得後續學習過程僅需在一部分特徵上構建模型,則維數災難問題會大爲減輕。

  • 去除不相關特徵往往會降低學習任務的難度,我們把複雜的問題變得簡單化,往往也能使得效率變高,結果變的更準確。

過濾式(Filter)

過濾式是過濾式的方法先對數據集進行特徵選擇,然後再訓練學習器,特徵選擇過程與後續學習器無關,也就是說我們先用特徵選擇過程對初始特徵進行“過濾”,再用過濾後的特徵來訓練模型。

  • 方差選擇法

設置一個閾值,然後計算各個特徵的方差,根據閾值,選擇方差大於閾值的特徵。

該方法的代碼使用方式如下:

from sklearn.feature_selection import VarianceThreshold

# 方差選擇法,返回值爲特徵選擇後的數據
# 參數threshold爲方差的閾值
VarianceThreshold(threshold=3).fit_transform(iris.data)
  • 相關係數法

計算各個特徵x對目標值y的Pearson相關係數,Pearson相關係數的計算方式如下:

r=(XXˉ)(YYˉ)(XXˉ)2(YYˉ)2r=\frac{\sum(X-\bar{X})(Y-\bar{Y})}{\sqrt{\sum(X-\bar{X})^2\sum(Y-\bar{Y})^2}}

Pearson 反應的是兩個變量間的線性相關性,它的取值區間爲[-1,1],其中1表示完全正相關,0表示完全沒有線性關係,-1表示完全的負相關。相關係數越接近於0,相關性越弱,通常在0.8-1.0之間極強相關,0.6-0.8強相關,0.4-0.6中等強度相關,0.2-0.4弱相關,0-0.2極弱相關或者不相關。

該方法的代碼使用方式如下:

from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr

# 選擇K個最好的特徵,返回選擇特徵後的數據
# 第一個參數爲計算評估特徵是否好的函數,該函數輸入特徵矩陣和目標向量,輸出二元組(評分,P值)的數組,數組第i項爲第i個特徵的評分和P值。在此定義爲計算相關係數
# 參數k爲選擇的特徵個數
SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)
  • 卡方檢驗

對於卡方檢驗,我們需要檢驗的是定性自變量對定性因變量的相關性,假設自變量有N種取值,因變量有M種取值,考慮自變量等於i且因變量等於j的樣本頻數的觀察值與期望的差距,構建如下的統計量(這裏的A表示觀察值,E表示理論值):

X2=(AE)2EX^2=\sum\frac{(A-E)^2}{E}

我們可以看出,這個統計量的含義簡而言之就是自變量對因變量的相關性。

該方法的代碼使用方式如下:

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

# 選擇K個最好的特徵,返回選擇特徵後的數據
SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target)
  • 互信息法

互信息可以看成是一個隨機變量中包含的關於另一個隨機變量的信息量,或者說是一個隨機變量由於已知另一個隨機變量而減少的不肯定性,互信息是聯合分佈與邊緣分佈的相對熵,互信息計算公式如下:

I(X;Y)=xXyYp(x,y)logp(x,y)p(x)p(y)I(X;Y)=\sum_{x\in X}\sum_{y\in Y}p(x,y)log\frac{p(x,y)}{p(x)p(y)}

該方法的代碼使用方式如下:

from sklearn.feature_selection import SelectKBest
from minepy import MINE
 
# 由於MINE的設計不是函數式的,定義mic方法將其爲函數式的,返回一個二元組,二元組的第2項設置成固定的P值0.5
def mic(x, y):
    m = MINE()
    m.compute_score(x, y)
    return (m.mic(), 0.5)

# 選擇K個最好的特徵,返回特徵選擇後的數據
SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)

包裹式(wrapper)

與過濾式特徵選擇不考慮後續學習器不同,包裹式特徵選擇直接把最終將要使用的學習器性能作爲特徵子集的評價準則。因此從最終學習器性能來看,包裹式特徵選擇比過濾式特徵選擇更好,但是其計算開銷也要比過濾式特徵選擇大得多。

  • 遞歸特徵消除法

遞歸特徵消除法使用一個基模型來進行多輪訓練,每輪訓練後,移除若干權值係數的特徵,再基於新的特徵集進行下一輪訓練。

該方法的代碼使用方式如下:

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

# 遞歸特徵消除法,返回特徵選擇後的數據
# 參數estimator爲基模型
# 參數n_features_to_select爲選擇的特徵個數
RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(iris.data, iris.target)

嵌入式(Embedding)

在過濾式和包裹式特徵選擇方法中,特徵選擇過程與學習器訓練過程有明顯的分別;與此不同的是,嵌入式特徵選擇是將特徵選擇過程與學習器訓練過程融爲一體,兩者在同一個優化過程中完成,即在學習器訓練過程中自動的進行了特徵選擇。

  • 基於懲罰項的特徵選擇法

我們使用帶有懲罰項的基模型(例如LR、SVM),不僅可以篩選出特徵,同時也進行了降維,下面的例子嘗試使用LR+L1正則來進行特徵選擇:

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

同樣我們也可以使用樹模型進行特徵的選擇,樹模型中的GBDT就是一個很好的例子,代碼的實現方式如下:

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

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章