特徵選擇
特徵選擇
特徵選擇是從資料集的諸多特徵裡面選擇和目標變數相關的特徵,去掉那些不相關的特徵。
特徵選擇分為兩個問題:一個是子集搜尋問題,另外一個是子集評價問題。比如將前向搜尋和資訊熵評價這兩種策略進行結合就是決策樹演算法,事實上決策樹演算法可以進行特徵選擇。sklearn當中的“樹形”演算法的feature_importances_就是特徵重要性的體現。
常用的特徵選擇分為三類:過濾式(filter),包裹式(wrapper)和嵌入式(embedding)
過濾式:先進行特徵選擇,然後進行後續的訓練,特徵選擇和後續的訓練過程沒有關係。
包裹式:將機器學習的效能當做子集評價標準
嵌入式:將特徵選擇和機器學習融為一體,兩者在同一個優化過程當中完成。和包裹式學習不同的是,包裹式中的子集選擇和機器訓練過程還是有區分的,而嵌入式將這兩個過程融為一個過程。
sklearn當中的特徵選擇
1:移除方差較低的特徵 VarianceThreshold方法
移除方差比較低的特徵,使用方差作為特徵選擇的一個標準,是因為觀察到這麼一個事實,方差較低的樣本差異不大,對我們的目標變數貢獻比較低,所以我們移除方差比較低的樣本。
舉個例子,假如特徵是boolean型別,那麼它是伯努利隨機變數,它的方差為D(X)=p(1−p)D(X)=p(1−p)。 假如我們想要移除特徵當中有超過80%要麼是0要麼是1的樣本
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]] #樣本為: ''' 0 0 1 0 1 0 0 1 1 0 1 0 0 1 1 ''' clf = VarianceThreshold(threshold=(0.8 * (1-0.8))) print(clf.fit_transform(X))
輸出結果:
[[0 1] [1 0] [0 0] [1 1] [1 0] [1 1]]
使用variances_屬性可以獲得各個特徵的方差:
print(clf.variances_) # [0.13888889 0.22222222 0.25 ]
注意:這裡的VarianceThreshold和我們傳統意義上面的anova(analysis of variance)沒有關係。這裡的VarianceThreshold方法不依賴於類的取值,只和特徵本身的方差有關,所以可以用在無監督學習當中。而單因素的anova的傳統應用是觀察一組因素是否對我們的試驗指標有顯著的影響。下面的f_classif則是利用anova的原理。
2:單變數特徵選擇
利用統計學當中的方差假設檢驗的知識來對模型的特徵進行選擇,我在特徵相似性度量中介紹了一下這些方法。
其中SelectKBest是用來選擇k個最高分數的特徵,SelectPercentile是選擇百分比個分數最高的特徵
from sklearn.datasets import load_iris from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 iris = load_iris() X, y = iris.data, iris.target print(X.shape) #(150, 4) X_new = SelectKBest(chi2, k=2).fit_transform(X, y) print(X_new.shape) #(150, 2)
上面選用的是χ2測試,
其它的還有:對於迴歸問題:f_regression, mutual_info_regression 。對於分類問題有: chi2, f_classif, mutual_info_classif。
事實上在統計學當中使用的測試的結果,比如chi2值,還有F值等都可以轉化為p值。所以SelectKBest有兩種方法可以檢視特徵的狀況,一個是scores_屬性,另外一個是pvalues_屬性。
k_best = SelectKBest(chi2, k=2).fit(X, y) print(k_best.scores_) #[ 10.81782088 3.59449902 116.16984746 67.24482759] print(k_best.pvalues_) #[4.47651499e-03 1.65754167e-01 5.94344354e-26 2.50017968e-15]
3: 迴歸特徵消除
Recursive feature elimination(RFE) 是使用迴歸的方法,在一個模型裡面不斷的減少不重要的特徵,最後達到我們要的特徵。下面是RFE中的引數:
estimator:輸入需要的模型。
n_features_to_select:需要選擇的特徵,預設選擇半數。
step:如果大於等於1,那麼每次迭代的時候去除step個,如果是0到1之間的小數,代表每次迭代去除的百分比。
下面是在手寫數字識別資料集當中進行畫素選擇的例子:
from sklearn.datasets import load_digits from sklearn.svm import SVC from sklearn.feature_selection import RFE #RFE import matplotlib.pyplot as plt digits = load_digits() X = digits.images.reshape((len(digits.images), -1)) y = digits.target svc = SVC(kernel='linear', C=1) rfe = RFE(svc, n_features_to_select=1, step=1) # rfe.fit(X, y) ranking = rfe.ranking_.reshape(digits.images[0].shape) plt.matshow(ranking, cmap=plt.cm.Blues) plt.colorbar() plt.title("Ranking of pixels with RFE") plt.show()