特征选择/筛选方法总结
作者:jliang
https://blog.csdn.net/jliang3
?
1.特征選擇介紹
1)特征分類
- 相關特征:對于學習任務(例如分類問題)有幫助,可以提升學習算法的效果;
- 無關特征:對于我們的算法沒有任何幫助,不會給算法的效果帶來任何提升;
- 冗余特征:不會對我們的算法帶來新的信息,或者這種特征的信息可以由其他的特征推斷出;
2)特征選擇的目的
對于一個特定的學習算法來說,哪一個特征是有效的是未知的。因此,需要從所有特征中選擇出對于學習算法有益的相關特征。而且在實際應用中,經常會出現維度災難問題。如果只選擇所有特征中的部分特征構建模型,那么可以大大減少學習算法的運行時間,也可以增加模型的可解釋性。
- 減少特征數量、降維
- 降低學習任務的難度,提升模型的效率
- 使模型泛華能力更強,減少過擬合
- 增強對特征和特征值之間的理解
3)特征選擇的原則
獲取盡可能小的特征子集,不顯著降低分類精度、不影響分類分布以及特征子集應具有穩定、適應性強等特點。
2.特征選擇的方法
1)Filter方法(過濾式)
(1)主要思想是:對每一維特征“打分”,即給每一維的特征賦予權重,這樣的權重就代表著該特征的重要性,然后依據權重排序。
(2)先進行特征選擇,然后去訓練學習器,所以特征選擇的過程與學習器無關。相當于先對特征進行過濾操作,然后用特征子集來訓練分類器。
(3)主要方法
- Chi-squared test(卡方檢驗)
- Information gain(信息增益)
- Correlation coefficient scores(相關系數)
2)Wrapper方法(包裹式)
(1)主要思想是:將子集的選擇看作是一個搜索尋優問題,生成不同的組合,對組合進行評價,再與其他的組合進行比較。這樣就將子集的選擇看作是一個優化問題,這里有很多的優化算法可以解決,尤其是一些啟發式的優化算法,如GA、PSO(如:優化算法-粒子群算法)、DE、ABC(如:優化算法-人工蜂群算法)等,
(2)直接把最后要使用的分類器作為特征選擇的評價函數,對于特定的分類器選擇最優的特征子集。
(3)主要方法有:遞歸特征消除算法
3)Embedded方法(嵌入式)
(1)主要思想是:在模型既定的情況下學習出對提高模型準確性最好的特征。也就是在確定模型的過程中,挑選出那些對模型的訓練有重要意義的特征。
(2)簡單易學的機器學習算法--嶺回歸(Ridge Regression),就是線性回歸過程加入了L2正則項。
3.方法一:去掉取值變化小的特征(Removing features with low variance)
1)該方法一般用在特征選擇前作為一個預處理的工作,即先去掉取值變化小的特征,然后再使用其他特征選擇方法選擇特征。
2)考察某個特征下,樣本的方差值,可以認為給定一個閾值,拋棄哪些小于某個閾值的特征。
3)例子
(1)離散型變量:假設某特征的特征值只有0和1,并且在所有輸入樣本中,95%的實例的該特征取值都是1,那就可以認為這個特征作用不大。如果100%都是1,那這個特征就沒意義了。
(2)連續型變量:需要將連續變量離散化之后才能用。
(3)而且實際當中,一般不太會有95%以上都取某個值的特征存在,所以這種方法雖然簡單但是不太好用。可以把它作為特征選擇的預處理,先去掉那些取值變化小的特征,然后再從接下來提到的的特征選擇方法中選擇合適的進行進一步的特征選擇。
4)實現例子
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]])
4. 方法二:單變量特征選擇(Univariate feature selection)
- 單變量特征選擇方法獨立的衡量每個特征與響應變量之間的關系,單變量特征選擇能夠對每一個特征進行測試,衡量該特征和響應變量之間的關系,根據得分扔掉不好的特征。對于回歸和分類問題可以采用卡方檢驗等方式對特征進行測試。
- 方法簡單,易于運行,易于理解,通常對于理解數據有較好的效果(但對特征優化、提高泛化能力來說不一定有效);這種方法有許多改進的版本、變種。
1)Pearson相關系數(Pearson Correlation)
皮爾森相關系數是一種最簡單的,能幫助理解特征和響應變量之間關系的方法,該方法衡量的是變量之間的線性相關性,結果的取值區間為[-1,1],-1表示完全的負相關(這個變量下降,那個就會上升),+1表示完全的正相關,0表示沒有線性相關。
2)互信息和最大信息系數(Mutual information and maximal information coefficient)
以上就是經典的互信息公式了。想把互信息直接用于特征選擇其實不是太方便:
(1)它不屬于度量方式,也沒有辦法歸一化,在不同數據及上的結果無法做比較;
(2)對于連續變量的計算不是很方便(X和Y都是集合,x,y都是離散的取值),通常變量需要先離散化,而互信息的結果對離散化的方式很敏感。
3)距離相關系數(Distance correlation)
(1)距離相關系數是為了克服Pearson相關系數的弱點而生的。
(2)Pearson相關系數是0,我們也不能斷定這兩個變量是獨立的(有可能是非線性相關)。
(3)但如果距離相關系數是0,那么我們就可以說這兩個變量是獨立的。
4)基于學習模型的特征排序(Model based ranking)
(1)這種方法的思路是直接使用你要用的機器學習算法,針對每個單獨的特征和響應變量建立預測模型。
(2)其實Pearson相關系數等價于線性回歸里的標準化回歸系數。假如某個特征和響應變量之間的關系是非線性的,可以用基于樹的方法(決策樹、隨機森林)、或者擴展的線性模型等。基于樹的方法比較易于使用,因為他們對非線性關系的建模比較好,并且不需要太多的調試。但要注意過擬合問題,因此樹的深度最好不要太大,再就是運用交叉驗證。
5)卡方檢驗
(1)卡方檢驗屬于簡單易計算的Feature weight algorithm
(2)卡方檢驗是概率論和數理統計中常用的假設檢驗的思想,通過觀察實際值和理論值的偏差來確定原假設是否成立。
- 假設兩個變量是獨立的(此為原假設)
- 然后觀察實際值和理論值之間的偏差程度,若偏差足夠小,則認為偏差是自然的樣本誤差,接受假設。
- 若偏差大到一定程度,則否認原假設,接受備擇假設。
6)程序實現
(1)sklearn.feature_selection.SelectKBest:返回k個最佳特征
(2)sklearn.feature_selection.SelectPercentile:返回表現最佳的前r%個特征
(3)例子:使用卡方檢驗選擇特征
#導入sklearn庫中的SelectKBest和chi2
from sklearn.feature_selection import SelectKBest ,chi2
#選擇相關性最高的前5個特征
X_chi2 = SelectKBest(chi2, k=5).fit_transform(X, y)
X_chi2.shape
輸出:(27, 5)
(4)其它可選的方法
- f_classif: ANOVA F-value between label/feature for classification tasks.
- mutual_info_classif: Mutual information for a discrete target.
- chi2: Chi-squared stats of non-negative features for classification tasks.
- f_regression: F-value between label/feature for regression tasks.
- mutual_info_regression: Mutual information for a continuous target.
- SelectPercentile: Select features based on percentile of the highest scores.
- SelectFpr: Select features based on a false positive rate test.
- SelectFdr: Select features based on an estimated false discovery rate.
- SelectFwe: Select features based on family-wise error rate.
- GenericUnivariateSelect: Univariate feature selector with configurable mode.
5. 方法三:線性模型和正則化
1)另一種主流的特征選擇方法是基于機器學習模型的方法
(1)有些機器學習方法本身就具有對特征進行打分的機制,或者很容易將其運用到特征選擇任務中,例如回歸模型,SVM,決策樹,隨機森林等等。
(2)正則化模型
- 正則化就是把額外的約束或者懲罰項加到已有模型(損失函數)上,以防止過擬合并提高泛化能力。
- 損失函數由原來的E(X,Y)變為E(X,Y)+alpha||w||,w是模型系數組成的向量(有些地方也叫參數parameter,coefficients),||·||一般是L1或者L2范數,alpha是一個可調的參數,控制著正則化的強度。
- 當用在線性模型上時,L1正則化和L2正則化也稱為Lasso和Ridge。
2)L1正則化/Lasso regression
(1)L1正則化將系數w的l1范數作為懲罰項加到損失函數上,由于正則項非零,這就迫使那些弱的特征所對應的系數變成0。
(2)因此L1正則化往往會使學到的模型很稀疏(系數w經常為0),這個特性使得L1正則化成為一種很好的特征選擇方法。
3)L2正則化/Ridge regression
(1)L2正則化將系數向量的L2范數添加到了損失函數中。
- ?由于L2懲罰項中系數是二次方的,這使得L2和L1有著諸多差異,最明顯的一點就是,L2正則化會讓系數的取值變得平均。
- 對于關聯特征,這意味著他們能夠獲得更相近的對應系數。
- 可以看出,系數之和為常數時,各系數相等時懲罰是最小的,所以才有了L2會讓各個系數趨于相同的特點。?
- 但是對于L2來說,第一個模型的懲罰項是2alpha,但第二個模型的是4*alpha。
- 如果用L1正則化,不論學到的模型是Y=X1+X2還是Y=2X1,懲罰都是一樣的,都是2alpha。
- 以Y=X1+X2為例,假設X1和X2具有很強的關聯
(2)L2正則化對于特征選擇來說一種穩定的模型,不像L1正則化那樣,系數會因為細微的數據變化而波動。所以L2正則化和L1正則化提供的價值是不同的,L2正則化對于特征理解來說更加有用:表示能力強的特征對應的系數是非零。
4)程序實現
(1)多元線性回歸,具有n個特征值
- 預測公式如下y(i)=θ0+θ1x1(i)+θ2x2(i)+…++θnxni=Xb*θ
- 多元線性回歸方程演變成求θ
- sklearn中 中LinearRegression的fit()方法就是通過訓練集求出θ,LinearRegression的兩個屬性intercept_和coef_分別對應θ0和θ1-θn
(2)獲取模型參數代碼
if __name__ == '__main__':
??? #獲取boston數據
??? boston=datasets.load_boston()
??? x=boston.data
??? y=boston.target
??? #過濾掉異常值
??? x=x[y<50]
??? y=y[y<50]
??? reg=LinearRegression()
??? reg.fit(x,y)
??? #求排序后的coef
??? coefSort=reg.coef_.argsort()
??? #featureNameSort: 按對標記值的影響,從小到大的各特征值名稱
??? #featureCoefSore:按對標記值的影響,從小到大的coef_
??? featureNameSort=boston.feature_names[coefSort]
??? featureCoefSore=reg.coef_[coefSort]
??? print("featureNameSort:", featureNameSort)
??? print("featureCoefSore:",featureCoefSore)
? 運行代碼,輸出結果為:
featureNameSort: ['NOX' 'DIS' 'PTRATIO' 'LSTAT' 'CRIM' 'INDUS' 'AGE' 'TAX' 'B' 'ZN' 'RAD' ?'CHAS' 'RM']
featureCoefSore: [-1.24268073e+01 -1.21088069e+00 -8.38888137e-01 -3.50952134e-01
?-1.05574295e-01 -4.35179251e-02 -2.36116881e-02 -1.37702943e-02 7.93577159e-03?
3.52748549e-02? 2.50740082e-01? 4.55405227e-01 3.75411229e+00]
? (3)從輸出結果可以看出
- ? 正相關影響系數最大的特征值是"RM":房間的平均數量,系數值為3.75;
- ? 負相關影響系數最大的特征值是"NOX":一氧化氮濃度,系數值為-1.24;
6. 方法四:隨機森林
隨機森林具有準確率高、魯棒性好、易于使用等優點,這使得它成為了目前最流行的機器學習算法之一。隨機森林提供了兩種特征選擇的方法:mean decrease impurity和mean decrease accuracy。
1)平均不純度減少(Mean decrease impurity)
(1)隨機森林由多個決策樹構成。決策樹中的每一個節點都是關于某個特征的條件,為的是將數據集按照不同的響應變量一分為二。
(2)利用不純度可以確定節點(最優條件),對于分類問題,通常采用基尼不純度或者信息增益,對于回歸問題,通常采用的是方差或者最小二乘擬合。
(3)當訓練決策樹的時候,可以計算出每個特征減少了多少樹的不純度。對于一個決策樹森林來說,可以算出每個特征平均減少了多少不純度,并把它平均減少的不純度作為特征選擇的值。
(4)程序實現:直接使用sklearn訓練RF模型,然后通過feature_importances_屬性可以得到每個特征的特征重要性,該特征重要性是根據不純度減少計算而來。
2)平均精確度減少(Mean decrease accuracy)
(1)另一種常用的特征選擇方法就是直接度量每個特征對模型精確率的影響。
(2)主要思路是打亂每個特征的特征值順序,并且度量順序變動對模型的精確率的影響。很明顯,對于不重要的變量來說,打亂順序對模型的精確率影響不會太大,但是對于重要的變量來說,打亂順序就會降低模型的精確率。
(3)程序實現例子
from sklearn.cross_validation import ShuffleSplit
from sklearn.metrics import r2_score
from collections import defaultdict
X = boston["data"]
Y = boston["target"]
rf = RandomForestRegressor()
scores = defaultdict(list)
#crossvalidate the scores on a number of different random splits of the data
for train_idx, test_idx in ShuffleSplit(len(X), 100, .3):
??? X_train, X_test = X[train_idx], X[test_idx]
??? Y_train, Y_test = Y[train_idx], Y[test_idx]
??? r = rf.fit(X_train, Y_train)
acc = r2_score(Y_test, rf.predict(X_test))
# 遍歷特征的每一列
??? for i in range(X.shape[1]):
??????? X_t = X_test.copy()
?????? ?# 對這一列特征進行混洗,交互了一列特征內部的值的順序
??????? np.random.shuffle(X_t[:, i])
??????? shuff_acc = r2_score(Y_test, rf.predict(X_t))
??????? scores[names[i]].append((acc-shuff_acc)/acc)
print "Features sorted by their score:"
print sorted([(round(np.mean(score), 4), feat) for feat, score in scores.items()], reverse=True)
7. 方法五:頂層特征選擇算法
之所以叫做頂層,是因為他們都是建立在基于模型的特征選擇方法基礎之上的,例如回歸和SVM,在不同的子集上建立模型,然后匯總最終確定特征得分。
1)穩定性選擇(Stability selection)
(1)穩定性選擇是一種基于二次抽樣和選擇算法相結合較新的方法,選擇算法可以是回歸、SVM或其他類似的方法。
(2)它的主要思想是在不同的數據子集和特征子集上運行特征選擇算法,不斷的重復,最終匯總特征選擇結果。
- 比如可以統計某個特征被認為是重要特征的頻率(被選為重要特征的次數除以它所在的子集被測試的次數)。
(3)理想情況下,重要特征的得分會接近100%。稍微弱一點的特征得分會是非0的數,而最無用的特征得分將會接近于0。
(4)程序實現例子
from sklearn.linear_model import RandomizedLasso
from sklearn.datasets import load_boston
boston = load_boston()
#using the Boston housing data.
#Data gets scaled automatically by sklearn's implementation
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]
rlasso = RandomizedLasso(alpha=0.025)
rlasso.fit(X, Y)
print("Features sorted by their score:")
print(sorted(zip(map(lambda x: round(x, 4), rlasso.scores_), names), reverse=True))
2)遞歸特征消除(Recursive feature elimination,RFE)
(1)遞歸特征消除的主要思想是反復的構建模型(如SVM或者回歸模型)然后選出最好的(或者最差的)的特征(可以根據系數來選),把選出來的特征放到一遍,然后在剩余的特征上重復這個過程,直到所有特征都遍歷了。
(2)這個過程中特征被消除的次序就是特征的排序。因此,這是一種尋找最優特征子集的貪心算法。
(3)RFE的穩定性很大程度上取決于在迭代的時候底層用哪種模型。
- 例如,假如RFE采用的普通的回歸,沒有經過正則化的回歸是不穩定的,那么RFE就是不穩定的;
- 假如采用的是Ridge,而用Ridge正則化的回歸是穩定的,那么RFE就是穩定的。
(4)程序實現例子
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]
#use linear regression as the model
lr = LinearRegression()
#rank all features, i.e continue the elimination until the last one
rfe = RFE(lr, n_features_to_select=1)
rfe.fit(X,Y)
print("Features sorted by their rank:")
print(sorted(zip(map(lambda x: round(x, 4), rfe.ranking_), names)))
結果輸出
Features sorted by their rank:
[(1, 'NOX'), (2, 'RM'), (3, 'CHAS'), (4, 'PTRATIO'), (5, 'DIS'), (6, 'LSTAT'), (7, 'RAD'), (8, 'CRIM'), (9, 'INDUS'), (10, 'ZN'), (11, 'TAX'), (12, 'B'), (13, 'AGE')]
參考文獻?
[1]. 機器學習之特征選擇. https://www.cnblogs.com/nolonely/p/6435083.html
[2]. 特征選擇--scikit-learn. https://blog.csdn.net/a1368783069/article/details/52048349
總結
以上是生活随笔為你收集整理的特征选择/筛选方法总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Arduino通过PS2模块使用PS2键
- 下一篇: 理解softmax函数