如何找出模型需要的特征?首先要找到該領域的業務專家,讓他們給一些建議。比如我們需要解決一個葯品療效的分類問題,那么先找到領域專家,向他們咨詢哪些因素(特征)會對該葯品的療效產生影響,較大影響和較小影響的因素都要。這些因素就是我們特征的第一候選集。(摘自:https://www.cnblogs.com/pinard/p/9032759.html)
以上是從業務角度對特征進行的選擇,這也是最重要的方法。
除此之外,從技術角度考慮,特征選擇的方法主要分為3大類:
- 過濾法(Filter):針對單個特征的統計學特性進行篩選。按照發散性或者相關性對各個特征進行評分,通過設定閾值選擇特征。
- 包裹法(Wrapper):本質是用迭代法。根據模型的預測效果進行評分,每次向模型添加一個特征,或者刪除一個特征,直到達到特定的停止條件。
- 嵌入法(Embedded):是一種基於模型的方法。使用模型進行訓練,得到各個特征的權值系數,根據系數從大到小選擇特征。特征選擇本身融合在模型訓練的過程中。
過濾法(Filter)
(以下內容部分摘自:https://www.zhihu.com/question/28641663/answer/110165221)
1,方差法
基本原理是:移除方差較低的特征。如果一個特征不發散,例如方差接近於0,也就是說樣本在這個特征上基本上沒有差異,那么這個特征對於樣本的區分並沒有什么用。具體方法是:計算各個特征的方差,選擇方差大於閾值的特征。
用sklearn中feature_selection庫的VarianceThreshold類來選擇特征的代碼如下:
from sklearn.feature_selection import VarianceThreshold
#方差選擇法,返回值為特征選擇后的數據
#參數threshold為方差的閾值
VarianceThreshold(threshold=3).fit_transform(iris.data)
2,皮爾遜相關系數法
基本原理是:移除和目標y不相關的特征。具體方法是:計算各個特征對目標值的皮爾遜相關系數以及相關系數的p值,選擇顯著相關的特征。
用sklearn中feature_selection庫的SelectBest(選擇k個最強大的特征)類結合相關系數來選擇特征的代碼如下:
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)
此外,還可以用SelectPercentile類選擇最強大的k%特征。(下同)
需要注意的是:皮爾遜相關系數只能衡量x和y之間是否線性相關。
3,卡方檢驗
基本原理是:運用卡方檢驗中的獨立性檢驗,如果兩類別型變量之間有關聯,那么說明彼此之間不獨立。具體方法是:假設自變量有N種取值,因變量有M種取值,考慮自變量等於i且因變量等於j的樣本頻數的觀察值與期望的差距,構建統計量。
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2 #選擇K個最好的特征,返回選擇特征后的數據 SelectKBest(score_func=chi2, k=2).fit_transform(iris.data, iris.target)
注:卡方檢驗只能用於x和y都是類別型變量的情況。
4,F檢驗
基本原理是:運用單因素方差分析,在變量總離差平方和中,如果組間方差所占比例較大,說明觀測變量的變動主要是由控制變量引起的。具體方法是:將組間均方差除以組內均方差,構建統計量。
用sklearn中feature_selection庫的SelectBest(選擇k個最強大的特征)類結合f_classif來選擇特征的代碼如下:
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_classif
SelectKBest(score_func=f_classif, k=4).fit_transform(iris.data, iris.target)
注:f_classif用於y是類別型變量的情況,如果y是數值型變量,那么用f_regression,此時和用皮爾遜相關系數一樣。
5,互信息法
互信息也能評價定性自變量和定性因變量之間的相關性,從信息增益的角度來看,互信息表示由於x的引入而使y的不確定性減少的量。互信息值越大,說明該自變量和因變量之間的相關性越大。互信息計算公式如下:。
用sklearn中feature_selection庫的SelectBest(選擇k個最強大的特征)類結合mutual_info_classif來選擇特征的代碼如下:
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import mutual_info_classif SelectKBest(score_func=mutual_info_classif, k=4).fit_transform(iris.data, iris.target)
但是將互信息直接用於特征選擇其實不是太方便:1、它不屬於度量方式,也沒有辦法歸一化,在不同數據及上的結果無法做比較;2、對於連續變量的計算不是很方便,通常變量需要先離散化,而互信息的結果對離散化的方式很敏感。
因此為了處理定量數據,最大信息系數法(Mutual information and maximal information coefficient,MIC)被提出。它首先尋找一種最優的離散化方式,然后把互信息取值轉換成一種度量方式,取值區間在[0,1]。
使用sklearn中feature_selection庫的SelectKBest類結合最大信息系數法(minepy 提供了MIC功能)來選擇特征的代碼如下:
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)
注:互信息法可以衡量x和y之間的非線性關系。
包裹法(Wrapper)
1,遞歸特征消除法(Recursive Feature Elimination, RFE)
遞歸消除特征法使用一個基模型來進行多輪訓練,每輪訓練后,消除若干權值系數的特征,再基於新的特征集進行下一輪訓練。首先,在原始特征上訓練模型,每個特征得到一個權重。之后,那些擁有最小絕對值權重的特征被踢出特征集。如此往復遞歸,直至剩余的特征數量達到所需的特征數量。RFE的表現如何很依賴於基模型,如果基模型穩定那么特征選擇的質量也穩定。
之前所說的逐步回歸法(請見:https://www.cnblogs.com/HuZihu/p/12329998.html)就是遞歸特征消除法的一種,之前文章是針對線性回歸模型來說的,如果要擴展到其他模型,那么使用交叉驗證預測誤差來衡量模型。
使用sklearn中feature_selection庫的RFE類來選擇特征的代碼如下:
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)
嵌入法(Embedded)
1,基於樹模型的特征選擇法
目前對於分類問題來說一般使用基尼系數或信息增益,對回歸問題來說一般使用RMSE(均方根誤差)或MSE(平方誤差)。
使用sklearn中feature_selection庫的SelectFromModel類結合GBDT模型來選擇特征的代碼如下:
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier #GBDT作為基模型的特征選擇 SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)
2,正則化
這里指L1正則方法,其本質是將某些特征對應的權重置零。使用帶懲罰項的基模型,除了能篩選出特征外,同時也訓練出了模型。
使用sklearn中feature_selection庫的SelectFromModel類結合帶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)
這三大類特征選擇方法的優缺點:
- 過濾式方法運用統計指標來為每個特征打分並篩選特征,其聚焦於數據本身的特點。其優點是計算快,不依賴於具體的模型。缺點是選擇的統計指標不是為特定模型定制的,因而最后的准確率可能不高。而且因為進行的是單變量統計檢驗,沒有考慮特征間的相互關系,並且不能對交互項進行選擇。
- 包裹式方法使用模型來篩選特征,通過不斷地增加或刪除特征,在驗證集上測試模型准確率,尋找最優的特征子集。包裹式方法因為有模型的直接參與,因而通常准確性較高,但是因為每變動一個特征都要重新訓練模型,因而計算開銷大,其另一個缺點是容易過擬合。
- 嵌入式方法利用了模型本身的特性,將特征選擇嵌入到模型的構建過程中。典型的如 Lasso 和樹模型等。准確率較高,計算復雜度介於過濾式和包裹式方法之間,但缺點是只有部分模型有這個功能。
參考:https://www.cnblogs.com/massquantity/p/10486904.html