特徵選擇
一,刪除低方差的特徵
VarianceThreshold是特徵選擇的簡單基準方法。它將刪除方差未達到某個閾值的所有特徵。默認情況下,它將刪除所有零方差特徵,即在所有樣本中具有相同值的特徵。
例如,假設我們有一個具有布爾特徵的數據集,並且我們要刪除80%以上樣本中所有爲1或0(打開或關閉)的特徵。布爾特徵是伯努利隨機變量,這些變量的方差由下式給出:
因此我們可以使用閾值進行選擇:0.8 * (1 - 0.8)
>>> from sklearn.feature_selection import VarianceThreshold
>>> X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
>>> sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
>>> sel.fit_transform(X)
array([[0, 1],
[1, 0],
[0, 0],
[1, 1],
[1, 0],
[1, 1]])
不出所料,VarianceThreshold
已刪除第一列,這很可能 p = 5/6 > 0.8
包含零。
二,單變量特徵選擇
單變量特徵選擇通過基於單變量統計檢驗選擇最佳特徵來工作。可以將其視爲估算器的預處理步驟。Scikit-learn將要素選擇例程公開爲實現該transform
方法的對象:
- SelectKBest 刪除除 k 最高評分功能
- SelectPercentile刪除除用戶指定的最高得分百分比以外的所有特徵
- 對每個特徵使用通用的單變量統計檢驗:誤報率SelectFpr,誤發現率
SelectFdr
或家族錯誤SelectFwe。 - GenericUnivariateSelect允許使用可配置的策略執行單變量特徵選擇。這允許使用超參數搜索估計器選擇最佳的單變量選擇策略。
例如,我們可以執行 χ2 測試樣本以僅檢索以下兩個最佳功能:
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectKBest
>>> from sklearn.feature_selection import chi2
>>> X, y = load_iris(return_X_y=True)
>>> X.shape
(150, 4)
>>> X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
>>> X_new.shape
(150, 2)
這些對象作爲輸入計分函數,返回單因素分數和p值(或僅分數SelectKBest
和 SelectPercentile
):
基於F檢驗的方法估計兩個隨機變量之間的線性相關程度。另一方面,互信息方法可以捕獲任何類型的統計依賴性,但是由於是非參數性的,因此它們需要更多的樣本才能進行準確的估算。
稀疏數據的特徵選擇
如果您使用稀疏數據(即,表示爲稀疏矩陣的數據)
則mutual_info_regression
,chi2
,mutual_info_classif
會處理數據而不會使其變得密集。
警告:
當心不要在分類問題上使用迴歸評分功能,您將獲得無用的結果。
例子:
三,遞歸特徵消除
給定一個將權重分配給特徵(例如線性模型的係數)的外部估計器,遞歸特徵消除(RFE)是通過遞歸考慮越來越少的特徵集來選擇特徵。首先,對估計器進行初始特徵集訓練,並通過coef_
屬性或屬性獲得每個特徵的重要性feature_importances_
。然後,從當前的一組特徵中刪除最不重要的特徵,然後對該過程進行遞歸重複,直到最終達到所需的特徵數量。
RFECV 在交叉驗證循環中執行 RFE,以找到最佳數量的特徵。
例子:
- 遞歸特徵消除:一個遞歸特徵消除示例,顯示了數字分類任務中像素的相關性。
- 帶有交叉驗證的遞歸特徵消除:一個遞歸特徵消除示例,其中自動調整了通過交叉驗證選擇的特徵數。
四,使用SelectFromModel特徵選擇
SelectFromModel是一個元變壓器,可與擬合後具有coef_
或feature_importances_
屬性的任何估計量一起使用。如果相應的coef_
或feature_importances_
值低於提供的 threshold
參數,則認爲這些功能不重要並已刪除 。除了通過數字指定閾值之外,還內置了使用字符串參數查找閾值的試探法。可用的試探法是 “平均值”,“中位數” 和 “浮點數” 的倍數,例如 “ 0.1 *平均值”。與threshold
標準結合使用時,可以使用 max_features
參數設置要選擇的要素數量的限制。
例子
- 使用SelectFromModel和LassoCV進行特徵選擇:從糖尿病數據集中選擇兩個最重要的特徵,而無需事先知道閾值
4.1 L1-based 特徵選擇
受到L1範數懲罰的 線性模型 的解決方案稀疏:許多估計係數爲零。當目標是減少要與另一個分類器一起使用的數據的維數時,可以將它們與feature_selection.SelectFromModel
選擇非零係數一起使用。特別地,用於此目的的稀疏估計量是linear_model.Lasso
用於迴歸,和linear_model.LogisticRegression
以及svm.LinearSVC
用於分類的:
>>> from sklearn.svm import LinearSVC
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectFromModel
# 讀取數據
>>> X, y = load_iris(return_X_y=True)
>>> X.shape
(150, 4)
# 訓練線性模型
>>> lsvc = LinearSVC(C=0.01, penalty="l1", dual=False)
>>> lsvc.fit(X, y)
# 根據給出的進行特徵選擇
>>> model = SelectFromModel(lsvc, prefit=True)
>>> X_new = model.transform(X)
>>> X_new.shape
(150, 3)
對於SVM和logistic迴歸,參數C控制稀疏度:C越小,選擇的特徵就越少。使用套索,alpha參數越高,選擇的特徵就越少。
例子:
- 使用稀疏特徵對文本文檔進行分類:比較不同的文檔分類算法,包括基於L1的特徵選擇。
L1恢復和壓縮感測
對於α的良好選擇,只要滿足某些特定條件,
Lasso
就可以僅使用很少的觀察值即可完全恢復非零變量的確切集合。特別是,樣本數量應爲“足夠大”,否則L1模型將隨機執行,其中“足夠大”取決於非零係數的數量,特徵數量的對數,噪聲量,非零係數的最小絕對值,以及設計矩陣X的結構。此外,設計矩陣必須顯示某些特定的屬性,例如,不要過於相關。沒有一般規則來選擇用於恢復非零係數的alpha參數。它可以通過交叉驗證(
LassoCV
或LassoLarsCV
)進行設置,儘管這可能會導致模型不足化:包括少量不相關的變量不會損害預測得分。LassoLarsIC
相反,BIC()
傾向於設置較高的alpha值
。參考 Richard G. Baraniuk“壓縮感測”,IEEE信號處理雜誌[120] 2007年7月
http://users.isr.ist.utl.pt/~aguiar/CS_notes.pdf
4.2 Tree-based 特徵選擇
基於樹的估計器(請參閱sklearn.tree模塊和模塊中的樹林sklearn.ensemble)可用於計算基於雜質的特徵重要性,而反過來又可用於丟棄不相關的特徵(當與sklearn.feature_selection.SelectFromModel meta-transformer結合使用時):
>>> from sklearn.ensemble import ExtraTreesClassifier
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectFromModel
# 加載數據
>>> X, y = load_iris(return_X_y=True)
>>> X.shape
(150, 4)
# 訓練tree估計器
>>> clf = ExtraTreesClassifier(n_estimators=50)
>>> clf = clf.fit(X, y)
>>> clf.feature_importances_
array([ 0.04..., 0.05..., 0.4..., 0.4...])
# 根據估計器進行特徵選擇
>>> model = SelectFromModel(clf, prefit=True)
>>> X_new = model.transform(X)
>>> X_new.shape
(150, 2)
例子:
- 樹木森林的特徵重要性:綜合數據示例顯示了實際有意義的特徵的恢復。
- 平行樹木樹林的像素重要性:人臉識別數據示例。
五,使用part of a pipeline特徵選擇
在進行實際學習之前,通常將特徵選擇用作預處理步驟。推薦在scikit-learn中執行此操作的方法是使用sklearn.pipeline.Pipeline:
clf = Pipeline([
('feature_selection', SelectFromModel(LinearSVC(penalty="l1"))),
('classification', RandomForestClassifier())
])
clf.fit(X, y)
在此代碼段中,我們sklearn.svm.LinearSVC 結合使用sklearn.feature_selection.SelectFromModel 來評估功能的重要性並選擇最相關的功能。然後,sklearn.ensemble.RandomForestClassifier對轉換後的輸出(即僅使用相關特徵)進行訓練。您可以使用其他功能選擇方法以及分類器執行類似的操作,這些分類器提供了一種評估功能的重要性的方法。有關sklearn.pipeline.Pipeline更多詳細信息,請參見示例。