特徵工程之特徵選擇

2021-08-15 02:54:40 字數 4180 閱讀 5005

在前一篇文章中我介紹了一些資料預處理的方法,原始資料在經過預處理之後可以被演算法處理了,但是實際中可能有一些特徵是沒有必要的,比如在中國採集的一些資料,那麼國籍就都是中國,其實也就沒有意義了,反映在統計量上就是方差過小,也就是樣本在這個特徵上變化很小。還有一種情況是特徵和最後的結果相關性很小,也就是這個特徵不起作用,衡量這種相關性我們可以用卡方檢驗,f-檢驗以及互資訊等。其實很多sklearn的演算法本身帶有coef_和feature_importance_屬性,而這個屬性就可以被利用來篩選特徵。前面說過的方法其實都是在已有特徵的基礎上排除特徵的方法,但是在實際中我們很多時候需要自己構造特徵,構造出好的特徵可以大大提公升模型的效能,對於這方面我就不是很了解了,畢竟我也是個新手,沒有太多經驗。

sklearn中variancethreshold可以起到這個作用

from sklearn.feature_selection import variancethreshold

sel = variancethreshold(0.2)

sel.fit_transform(data)

上述**起到移除方差小於0.2的特徵的作用(只起到示意作用)。

單一變數選擇就是通過某種得分來度量相關性,進而選擇特徵,sklearn中有兩個比較常用

. selectkbest :選擇前k個最好的特徵,也就是得分最高的k個

. selectpercentile :選擇前百分之幾的特徵,這個百分比由使用者指定

所以從上面就可以看出必須要有乙個方法來衡量這種相關性,來傳給上面的兩個方法,才能夠做出選擇。衡量方法也就是上面提到的,卡方檢驗,f-檢驗以及互資訊。這幾種方法在sklearn中是有專門的實現的,再進行單一變數特徵選擇的時候將他們作為引數傳遞進去。下面以卡方檢驗為例

>>> 

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

>>> x.shape

(150, 4)

>>> x_new = selectkbest(chi2, k=2).fit_transform(x, y)

>>> x_new.shape

(150, 2)

作為引數的打分的函式對於回歸和分類是不同的:

-回歸:f_regression, mutual_info_regression

-分類:chi2, f_classif, mutual_info_classif

值得注意的是互資訊(mutual_info_regression, mutual_info_classif)可以得到特徵和最後的結果之間的非線性的相關性,而卡方檢驗和f-檢驗應該只能夠判斷線性性。互資訊的公式是 i(

x;y)

=∑x∈

x∑y∈

yp(x

,y)p

(x,y

)p(x

)p(y

) i(x

;y)=

∑x∈x

∑y∈y

p(x,

y)p(

x,y)

p(x)

p(y)

遞迴特徵消除(rfe)很好理解,給定乙個模型,要求這個模型要能夠給出coef_或者feature_importance_,然後我們就能夠根據訓練的這些相關性特徵刪除得分最差的特徵,然後再一次訓練,重複這個過程,直到最後滿足我們預設的特徵個數。還可以用rfecv通過交叉驗證找出最佳的特徵個數。下面是乙個示例。

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)

slectformmodel也就是從模型中選擇,感覺上和上面的遞迴特徵消除有點相似,它是乙個「元轉換器」,可以和任何帶有coef_或者feature_importance_的模型一起使用。另外我們會指定乙個引數「閾值」,小於這個閾值的特徵被認為是不重要的,並且會被移除,不像是rfe會反覆地擬合模型每次移除乙個。大致用法如下

clf = lassocv()

# set a minimum threshold of 0.25

sfm = selectfrommodel(clf, threshold=0.25)

sfm.fit(x, y)

n_features = sfm.transform(x).shape[1]

上面用的是lassocv結合selectfrommodel進行特徵選擇。

帶有l1懲罰項的線性模型容易產生稀疏解,那麼我們可以讓selectfrommodel和這種模型相結合,最後選擇相關係數不為0的特徵就行。一般的線性模型有lasso,logisiticregression以及linearsvc

>>> 

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

>>> x.shape

(150, 4)

>>> 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

(150, 3)

對於svc和logisticregression越小的c,越少的特徵被選擇。對於lasso,越大的alpha越少的特徵被選擇。具體是什麼原因,我也不知道。

這個方法的原理也是類似的,因為樹在生成過程中一定也會選擇特徵。回憶一下決策樹,不論是id3,c4.5還是cart開始的時候都是先找乙個最能夠區分資料集的特徵,cart是二叉樹,第一步要找出最優特徵和最優切分點,之後不斷迴圈。這個過程不就是篩選出最優特徵的過程嗎?不過在應用中,**還是和上面類似,和selectfrommodel已啟用。

>>> from sklearn.ensemble import extratreesclassifier

>>> from sklearn.datasets import load_iris

>>> from sklearn.feature_selection import selectfrommodel

>>> iris = load_iris()

>>> x, y = iris.data, iris.target

>>> x.shape

>(150, 4)

>>> clf = extratreesclassifier()

>>> 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)

以上是一些特徵篩選的方法,另外還有特徵的構造,但本人經驗不足,在此就略去這方面的論述了。

特徵工程之特徵選擇

特徵選擇其實就是減少屬性個數,為什麼要這麼做呢?直接使用原始資料來訓練模型的話,雖然說在訓練模型上的準確率會非常高,但是在測試樣本上的準確率將會大打折扣,也就是會產生過擬合的現象。所以說需要選擇出最適合的屬性進行訓練。特徵選擇的原因 2 雜訊 部分特徵對 結果又影響 進行特徵選擇的時候有兩種情況 一...

特徵工程之特徵選擇

在做資料分析的時候,特徵的 一般有兩塊,一塊是業務已經整理好各種特徵資料,我們需要去找出適合我們問題需要的特徵 另一塊是我們從業務特徵中自己去尋找高階資料特徵。我們就針對這兩部分來分別討論。2.選擇合適的特徵 我們首先看當業務已經整理好各種特徵資料時,我們如何去找出適合我們問題需要的特徵,此時特徵數...

特徵工程之特徵表達

在特徵工程之特徵選擇中,我們講到了特徵選擇的一些要點。本篇我們繼續討論特徵工程,不過會重點關注於特徵表達部分,即如果對某乙個特徵的具體表現形式做處理。主要包括缺失值處理,特殊的特徵處理比如時間和地理位置處理,離散特徵的連續化和離散化處理,連續特徵的離散化處理幾個方面。特徵有缺失值是非常常見的,大部分...