特征選擇- Sklearn.feature_selection的理解


Sklearn的feature_selection模塊中給出了其特征選擇的方法,實際工作中選擇特征的方式肯定不止這幾種的,IV,GBDT等等都ok;

一、移除低方差特征(Removing features with low variance)

  API函數:sklearn.feature_selection.VarianceThreshold(threshold=0.0)

  VarianceThreshold是特征選擇的一個簡單基本方法,它會移除所有那些方差不滿足一些閾值的特征。 在默認情況下,其會移除所有方差為0的特征,也就是所有取值相同的特征。

  官網說:[

    例如,假設我們有一個特征是布爾值的數據集,我們想要移除那些在整個數據集中特征值為0或者為1的比例超過80%的特征。布爾特征是伯努利( Bernoulli )隨機變量,變量的方差為

                            \mathrm{Var}[X] = p(1 - p)

    因此,我們可以使用閾值 ``.8 * (1 - .8)``進行選擇:

      ]

其用法可見,移除低於閾值的特征。但是對不不同的特征,其特征分布我們需要自己探索,即使對於離散特征數值化后或者連續特征,可以直接計算其方差。但是我認為這個選擇特征的方法實際意義有待商榷;對於一個特征取值唯一的情況,這種方法是肯定可以發現的。但是如果一個特征是布爾值,即使整個數據集合中有特征值為0或者為1的比例超過80%的特征,並不能說明這個特征不好哇,其對目標變量的相關性如果還不錯,你會忍心把這個變量剔除嗎。對吧,所以我實際工作中,沒用過這個方法。各抒己見!

 

二、單變量特征選擇,Univariate feature selection

  這個有用,比上一個API有用多了。慢慢來看。

  官網說【單變量的特征選擇是通過基於單變量的統計測試來選擇最好的特征。它可以當做是評估器的預處理步驟】。是的哇,單變量的特征選擇,出發點是想針對每一個特征單獨檢測其和目標變量Y的相關性,顧名思義單變量嘛。選擇方法很多,具體區分又區分,你所做的模型是回歸還是分類。

  Scikit-learn 將特征選擇的內容作為實現了 transform 方法的對象

  (1)、SelectKBest移除那些除了評分最高的 K 個特征之外的所有特征

  (2)、SelectPercentile移除除了用戶指定的最高得分百分比之外的所有特征

這些對象將得分函數作為輸入,返回單變量的得分和 p 值:

用例1,SelectPercentile的用法:

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest, SelectPercentile
from sklearn.feature_selection import f_classif
iris = load_iris()
X, y = iris.data, iris.target
sp = SelectPercentile(f_classif, percentile= 90)
#得到返回至少含有90%特征信息的特征
X_result = sp.fit_transform(X, y)
#可以看到哪些特征被保留
sp.get_support()
#輸出結果
array([ True, False,  True,  True], dtype=bool)

用例2,依然使用iris數據集,看一下mutual_info_classif 和pandas中的corr()函數的信息相關性計算結果對比;

import pandas as pd
from sklearn import  datasets
import numpy as np
import seaborn as sns
from sklearn.feature_selection import mutual_info_classif
iris = datasets.load_iris()
X = iris.data
y = iris.target
new_y = [y[i:i+1] for i in range(0, len(y), 1)]
data = np.hstack((X, new_y))
data_df = pd.DataFrame(data)
#0到3表示特征,4表示目標變量,畫圖查看相關性,如下圖所示
sns.heatmap(data_df.corr(), annot= True, fmt= '.2f')

  0,1,2,3特征和4(目標變量)的相關性分別為【0.18,-0.42, 0.95,0.96】

  互信息相關性:

mutual_info = mutual_info_classif(X, y, discrete_features= False)
#輸出結果如下,和上面的結果對比看一下
array([ 0.48502046,  0.30654537,  0.99750059,  0.9849968 ])

  三、遞歸特征消除(Recursive Feature Elimination)

  官網解釋:給定一個外部的估計器,可以對特征賦予一定的權重(比如,線性模型的相關系數),recursive feature elimination ( RFE ) 通過考慮越來越小的特征集合來遞歸的選擇特征。 首先,評估器在初始的特征集合上面訓練並且每一個特征的重要程度是通過一個 coef_ 屬性 或者 feature_importances_ 屬性來獲得。 然后,從當前的特征集合中移除最不重要的特征。在特征集合上不斷的重復遞歸這個步驟,直到最終達到所需要的特征數量為止。

用例:

from sklearn.feature_selection import RFE
from sklearn.ensemble import GradientBoostingClassifier
from sklearn import datasets
iris = datasets.load_iris()
gbdt_RFE = RFE(estimator=GradientBoostingClassifier(random_state= 123),n_features_to_select=2)
gbdt_RFE.fit(iris.data, iris.target)
gbdt_RFE.support_
#特征選擇輸出結果
gbdt_RFE.support_
#輸出結果為:
array([False, False,  True,  True], dtype=bool)

  四、使用SelectFromModel 選取特征(Feature selection using SelectFromModel)

官網解釋:SelectFromModel是一個 meta-transformer(元轉換器) ,它可以用來處理任何帶有 coef_ 或者 feature_importances_ 屬性的訓練之后的評估器。 如果相關的``coef_`` 或者 featureimportances 屬性值低於預先設置的閾值,這些特征將會被認為不重要並且移除掉。除了指定數值上的閾值之外,還可以通過給定字符串參數來使用內置的啟發式方法找到一個合適的閾值。可以使用的啟發式方法有 mean 、 median 以及使用浮點數乘以這些(例如,0.1*mean )

4.1、基於 L1 的特征選取

用例:

from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target

lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y)
model = SelectFromModel(lsvc, prefit=True)
X_new = model.transform(X)
X_new.shape

 

4.2、基於 Tree(樹)的特征選取

  基於樹的 estimators (查閱 sklearn.tree 模塊和樹的森林 在 sklearn.ensemble 模塊) 可以用來計算特征的重要性。

用例:

import numpy as np
import matplotlib.pyplot as plt

from sklearn.datasets import make_classification
from sklearn.ensemble import ExtraTreesClassifier

# Build a classification task using 3 informative features
X, y = make_classification(n_samples=1000,
                           n_features=10,
                           n_informative=3,
                           n_redundant=0,
                           n_repeated=0,
                           n_classes=2,
                           random_state=0,
                           shuffle=False)

# Build a forest and compute the feature importances
forest = ExtraTreesClassifier(n_estimators=250, random_state=0)
forest.fit(X,y)
importances = forest.feature_importances_
indices = np.argsort(importances)[::-1]
#作圖觀察特征重要性
plt.bar(range(10), importances[indices])
plt.xticks(range(X.shape[1]), indices)
plt.show()

五、特征選取作為 pipeline(管道)的一部分(Feature selection as 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 來了解更多的實例。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM