機(jī)器學(xué)習(xí)中的特征選擇

特征選擇主要有兩個(gè)功能:

  1. 減少特征數(shù)量山涡、降維鱼蝉,使模型泛化能力更強(qiáng)奴潘,減少過(guò)擬合
  2. 增強(qiáng)對(duì)特征和特征值之間的理解

1. 去掉取值變化小的特征

這應(yīng)該是最簡(jiǎn)單的特征選擇方法了:假設(shè)某特征的特征值只有0和1凳鬓,并且在所有輸入樣本中,95%的實(shí)例的該特征取值都是1,那就可以認(rèn)為這個(gè)特征作用不大御蒲。如果100%都是1衣赶,那這個(gè)特征就沒(méi)意義了。當(dāng)特征值都是離散型變量的時(shí)候這種方法才能用厚满,如果是連續(xù)型變量府瞄,就需要將連續(xù)變量離散化之后才能用,而且實(shí)際當(dāng)中碘箍,一般不太會(huì)有95%以上都取某個(gè)值的特征存在遵馆,所以這種方法雖然簡(jiǎn)單但是不太好用》崃瘢可以把它作為特征選擇的預(yù)處理货邓,先去掉那些取值變化小的特征,然后再?gòu)慕酉聛?lái)提到的的特征選擇方法中選擇合適的進(jìn)行進(jìn)一步的特征選擇四濒。

2.單變量特征選擇

單變量特征選擇能夠?qū)γ恳粋€(gè)特征進(jìn)行測(cè)試换况,衡量該特征和響應(yīng)變量之間的關(guān)系富弦,根據(jù)得分扔掉不好的特征抵碟。對(duì)于回歸和分類問(wèn)題可以采用卡方檢驗(yàn)等方式對(duì)特征進(jìn)行測(cè)試。
這種方法比較簡(jiǎn)單队塘,易于運(yùn)行喳资,易于理解觉吭,通常對(duì)于理解數(shù)據(jù)有較好的效果(但對(duì)特征優(yōu)化、提高泛化能力來(lái)說(shuō)不一定有效)仆邓;這種方法有許多改進(jìn)的版本亏栈、變種。

2.1 皮爾森相關(guān)系數(shù)

皮爾森相關(guān)系數(shù)是一種最簡(jiǎn)單的宏赘,能幫助理解特征和響應(yīng)變量之間關(guān)系的方法绒北,該方法衡量的是變量之間的線性相關(guān)性,結(jié)果的取值區(qū)間為[-1察署,1]闷游,-1表示完全的負(fù)相關(guān)(這個(gè)變量下降,那個(gè)就會(huì)上升)贴汪,+1表示完全的正相關(guān)脐往,0表示沒(méi)有線性相關(guān)。
Pearson Correlation速度快扳埂、易于計(jì)算业簿,經(jīng)常在拿到數(shù)據(jù)(經(jīng)過(guò)清洗和特征提取之后的)之后第一時(shí)間就執(zhí)行。Scipy的pearsonr方法能夠同時(shí)計(jì)算相關(guān)系數(shù)和p-value阳懂。

import numpy as np
from scipy.stats import pearsonr
np.random.seed(0)
size = 300
x = np.random.normal(0, 1, size)
print "Lower noise", pearsonr(x, x + np.random.normal(0, 1, size))
print "Higher noise", pearsonr(x, x + np.random.normal(0, 10, size))

Pearson相關(guān)系數(shù)的一個(gè)明顯缺陷是梅尤,作為特征排序機(jī)制柜思,他只對(duì)線性關(guān)系敏感。如果關(guān)系是非線性的巷燥,即便兩個(gè)變量具有一一對(duì)應(yīng)的關(guān)系赡盘,Pearson相關(guān)性也可能會(huì)接近0。

2.2 基于學(xué)習(xí)模型的特征排序 (Model based ranking)

這種方法的思路是直接使用你要用的機(jī)器學(xué)習(xí)算法缰揪,針對(duì)每個(gè)單獨(dú)的特征和響應(yīng)變量建立預(yù)測(cè)模型陨享。其實(shí)Pearson相關(guān)系數(shù)等價(jià)于線性回歸里的標(biāo)準(zhǔn)化回歸系數(shù)。假如某個(gè)特征和響應(yīng)變量之間的關(guān)系是非線性的钝腺,可以用基于樹的方法(決策樹抛姑、隨機(jī)森林)、或者擴(kuò)展的線性模型等艳狐《ㄏ酰基于樹的方法比較易于使用,因?yàn)樗麄儗?duì)非線性關(guān)系的建模比較好僵驰,并且不需要太多的調(diào)試喷斋。但要注意過(guò)擬合問(wèn)題,因此樹的深度最好不要太大蒜茴,再就是運(yùn)用交叉驗(yàn)證星爪。
波士頓房?jī)r(jià)數(shù)據(jù)集上使用sklearn的隨機(jī)森林回歸給出一個(gè)單變量選擇的例子:

from sklearn.cross_validation import cross_val_score, ShuffleSplit
from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor

#Load boston housing dataset as an example
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]

rf = RandomForestRegressor(n_estimators=20, max_depth=4)
scores = []
for i in range(X.shape[1]):
     score = cross_val_score(rf, X[:, i:i+1], Y, scoring="r2",
                              cv=ShuffleSplit(len(X), 3, .3))
     scores.append((round(np.mean(score), 3), names[i]))
print sorted(scores, reverse=True)

3 線性模型和正則化

單變量特征選擇方法獨(dú)立衡量每個(gè)特征與相應(yīng)變量之間的關(guān)系另一種主流的方法是基于機(jī)器學(xué)習(xí)模型的方法。有些機(jī)器學(xué)習(xí)方法粉私。有些機(jī)器學(xué)習(xí)方法本身就具有對(duì)特征進(jìn)行打分的機(jī)制顽腾,或者很容易運(yùn)用到特征選擇任務(wù)中,例如回歸模型诺核,SVM抄肖,決策樹,隨機(jī)森林等等窖杀。說(shuō)句題外話漓摩,這種方法在一些地方叫做wrapper類型,大概意思是說(shuō)入客,特征排序模型和機(jī)器學(xué)習(xí)模型是耦合在一起的管毙,對(duì)應(yīng)非wrapper類型的特征選擇方法叫做filter類型。
下面將介紹如何用回歸模型的系數(shù)來(lái)選擇特征桌硫。越是重要的特征在模型中對(duì)應(yīng)的系數(shù)就會(huì)越大夭咬,而跟輸出變量越是無(wú)關(guān)的特征對(duì)應(yīng)的系數(shù)就會(huì)越接近于0。在噪音不多的數(shù)據(jù)上铆隘,或者是數(shù)據(jù)量遠(yuǎn)遠(yuǎn)大于特征數(shù)的數(shù)據(jù)上卓舵,如果特征之間相對(duì)來(lái)說(shuō)是比較獨(dú)立的,那么即便是運(yùn)用最簡(jiǎn)單的線性回歸模型也一樣能取得非常好的效果膀钠。

from sklearn.linear_model import LinearRegression
import numpy as np

np.random.seed(0)
size = 5000

#A dataset with 3 features
X = np.random.normal(0, 1, (size, 3))
#Y = X0 + 2*X1 + noise
Y = X[:,0] + 2*X[:,1] + np.random.normal(0, 2, size)
lr = LinearRegression()
lr.fit(X, Y)

#A helper method for pretty-printing linear models
def pretty_print_linear(coefs, names = None, sort = False):
    if names == None:
        names = ["X%s" % x for x in range(len(coefs))]
    lst = zip(coefs, names)
    if sort:
        lst = sorted(lst,  key = lambda x:-np.abs(x[0]))
    return " + ".join("%s * %s" % (round(coef, 3), name)
                                   for coef, name in lst)

print "Linear model:", pretty_print_linear(lr.coef_)

在這個(gè)例子當(dāng)中掏湾,盡管數(shù)據(jù)中存在一些噪音裹虫,但這種特征選擇模型仍然能夠很好的體現(xiàn)出數(shù)據(jù)的底層結(jié)構(gòu)。當(dāng)然這也是因?yàn)槔又械倪@個(gè)問(wèn)題非常適合用線性模型來(lái)解:特征和響應(yīng)變量之間全都是線性關(guān)系忘巧,并且特征之間均是獨(dú)立的恒界。
在很多實(shí)際的數(shù)據(jù)當(dāng)中睦刃,往往存在多個(gè)互相關(guān)聯(lián)的特征砚嘴,這時(shí)候模型就會(huì)變得不穩(wěn)定,數(shù)據(jù)中細(xì)微的變化就可能導(dǎo)致模型的巨大變化(模型的變化本質(zhì)上是系數(shù)涩拙,或者叫參數(shù)际长,可以理解成W),這會(huì)讓模型的預(yù)測(cè)變得困難兴泥,這種現(xiàn)象也稱為多重共線性工育。例如,假設(shè)我們有個(gè)數(shù)據(jù)集搓彻,它的真實(shí)模型應(yīng)該是Y=X1+X2如绸,當(dāng)我們觀察的時(shí)候,發(fā)現(xiàn)Y'=X1+X2+e旭贬,e是噪音怔接。如果X1和X2之間存在線性關(guān)系,例如X1約等于X2稀轨,這個(gè)時(shí)候由于噪音e的存在扼脐,我們學(xué)到的模型可能就不是Y=X1+X2了,有可能是Y=2X1奋刽,或者Y=-X1+3X2瓦侮。
下邊這個(gè)例子當(dāng)中,在同一個(gè)數(shù)據(jù)上加入了一些噪音佣谐,用隨機(jī)森林算法進(jìn)行特征選擇肚吏。

from sklearn.linear_model import LinearRegression

size = 100
np.random.seed(seed=5)

X_seed = np.random.normal(0, 1, size)
X1 = X_seed + np.random.normal(0, .1, size)
X2 = X_seed + np.random.normal(0, .1, size)
X3 = X_seed + np.random.normal(0, .1, size)

Y = X1 + X2 + X3 + np.random.normal(0,1, size)
X = np.array([X1, X2, X3]).T

lr = LinearRegression()
lr.fit(X,Y)
print "Linear model:", pretty_print_linear(lr.coef_)

Linear model: -1.291 * X0 + 1.591 * X1 + 2.747 * X2

系數(shù)之和接近3,基本上和上上個(gè)例子的結(jié)果一致狭魂,應(yīng)該說(shuō)學(xué)到的模型對(duì)于預(yù)測(cè)來(lái)說(shuō)還是不錯(cuò)的罚攀。但是,如果從系數(shù)的字面意思上去解釋特征的重要性的話趁蕊,X3對(duì)于輸出變量來(lái)說(shuō)具有很強(qiáng)的正面影響坞生,而X1具有負(fù)面影響,而實(shí)際上所有特征與輸出變量之間的影響是均等的掷伙。
同樣的方法和套路可以用到類似的線性模型上是己,比如邏輯回歸。

3.1 正則化模型

正則化就是把額外的約束或者懲罰項(xiàng)加到已有模型(損失函數(shù))上任柜,以防止過(guò)擬合并提高泛化能力卒废。損失函數(shù)由原來(lái)的E(X,Y)變?yōu)镋(X,Y)+alpha||w||沛厨,w是模型系數(shù)組成的向量(有些地方也叫參數(shù)parameter,coefficients)摔认,||·||一般是L1或者L2范數(shù)逆皮,alpha是一個(gè)可調(diào)的參數(shù),控制著正則化的強(qiáng)度参袱。當(dāng)用在線性模型上時(shí)电谣,L1正則化和L2正則化也稱為L(zhǎng)asso和Ridge。

3.2 L1正則化/Lasso

L1正則化將系數(shù)w的l1范數(shù)作為懲罰項(xiàng)加到損失函數(shù)上抹蚀,由于正則項(xiàng)非零剿牺,這就迫使那些弱的特征所對(duì)應(yīng)的系數(shù)變成0。因此L1正則化往往會(huì)使學(xué)到的模型很稀疏(系數(shù)w經(jīng)常為0)环壤,這個(gè)特性使得L1正則化成為一種很好的特征選擇方法晒来。
Scikit-learn為線性回歸提供了Lasso,為分類提供了L1邏輯回歸郑现。
下面的例子在波士頓房?jī)r(jià)數(shù)據(jù)上運(yùn)行了Lasso湃崩,其中參數(shù)alpha是通過(guò)grid search進(jìn)行優(yōu)化的。

from sklearn.linear_model import Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_boston

boston = load_boston()
scaler = StandardScaler()
X = scaler.fit_transform(boston["data"])
Y = boston["target"]
names = boston["feature_names"]

lasso = Lasso(alpha=.3)
lasso.fit(X, Y)

print "Lasso model: ", pretty_print_linear(lasso.coef_, names, sort = True)z`
Lasso model: -3.707 * LSTAT + 2.992 * RM + -1.757 * PTRATIO + -1.081 * DIS + -0.7 * NOX + 0.631 * B + 0.54 * CHAS + -0.236 * CRIM + 0.081 * ZN + -0.0 * INDUS + -0.0 * AGE + 0.0 * RAD + -0.0 * TAX

可以看到接箫,很多特征的系數(shù)都是0攒读。如果繼續(xù)增加alpha的值,得到的模型就會(huì)越來(lái)越稀疏列牺,即越來(lái)越多的特征系數(shù)會(huì)變成0整陌。
然而,L1正則化像非正則化線性模型一樣也是不穩(wěn)定的瞎领,如果特征集合中具有相關(guān)聯(lián)的特征泌辫,當(dāng)數(shù)據(jù)發(fā)生細(xì)微變化時(shí)也有可能導(dǎo)致很大的模型差異。

3.3 L2正則化/Ridge regression

L2正則化將系數(shù)向量的L2范數(shù)添加到了損失函數(shù)中九默。由于L2懲罰項(xiàng)中系數(shù)是二次方的震放,這使得L2和L1有著諸多差異,最明顯的一點(diǎn)就是驼修,L2正則化會(huì)讓系數(shù)的取值變得平均殿遂。對(duì)于關(guān)聯(lián)特征,這意味著他們能夠獲得更相近的對(duì)應(yīng)系數(shù)乙各。還是以Y=X1+X2為例墨礁,假設(shè)X1和X2具有很強(qiáng)的關(guān)聯(lián),如果用L1正則化耳峦,不論學(xué)到的模型是Y=X1+X2還是Y=2X1恩静,懲罰都是一樣的,都是2alpha。但是對(duì)于L2來(lái)說(shuō)驶乾,第一個(gè)模型的懲罰項(xiàng)是2alpha邑飒,但第二個(gè)模型的是4*alpha〖独郑可以看出疙咸,系數(shù)之和為常數(shù)時(shí),各系數(shù)相等時(shí)懲罰是最小的风科,所以才有了L2會(huì)讓各個(gè)系數(shù)趨于相同的特點(diǎn)撒轮。
可以看出,L2正則化對(duì)于特征選擇來(lái)說(shuō)一種穩(wěn)定的模型丐重,不像L1正則化那樣腔召,系數(shù)會(huì)因?yàn)榧?xì)微的數(shù)據(jù)變化而波動(dòng)杆查。所以L2正則化和L1正則化提供的價(jià)值是不同的扮惦,L2正則化對(duì)于特征理解來(lái)說(shuō)更加有用:表示能力強(qiáng)的特征對(duì)應(yīng)的系數(shù)是非零。
回過(guò)頭來(lái)看看3個(gè)互相關(guān)聯(lián)的特征的例子亲桦,分別以10個(gè)不同的種子隨機(jī)初始化運(yùn)行10次崖蜜,來(lái)觀察L1和L2正則化的穩(wěn)定性。

from sklearn.linear_model import Ridge
from sklearn.metrics import r2_score
size = 100
#We run the method 10 times with different random seeds
for i in range(10):
    print "Random seed %s" % i
    np.random.seed(seed=i)
    X_seed = np.random.normal(0, 1, size)
    X1 = X_seed + np.random.normal(0, .1, size)
    X2 = X_seed + np.random.normal(0, .1, size)
    X3 = X_seed + np.random.normal(0, .1, size)
    Y = X1 + X2 + X3 + np.random.normal(0, 1, size)
    X = np.array([X1, X2, X3]).T
    lr = LinearRegression()
    lr.fit(X,Y)
    print "Linear model:", pretty_print_linear(lr.coef_)
    ridge = Ridge(alpha=10)
    ridge.fit(X,Y)
    print "Ridge model:", pretty_print_linear(ridge.coef_)
     Random seed 0 Linear model: 0.728 * X0 + 2.309 * X1 + -0.082 * X2 Ridge model: 0.938 * X0 + 1.059 * X1 + 0.877 * X2

Random seed 1 Linear model: 1.152 * X0 + 2.366 * X1 + -0.599 * X2 Ridge model: 0.984 * X0 + 1.068 * X1 + 0.759 * X2
Random seed 2 Linear model: 0.697 * X0 + 0.322 * X1 + 2.086 * X2 Ridge model: 0.972 * X0 + 0.943 * X1 + 1.085 * X2
Random seed 3 Linear model: 0.287 * X0 + 1.254 * X1 + 1.491 * X2 Ridge model: 0.919 * X0 + 1.005 * X1 + 1.033 * X2
Random seed 4 Linear model: 0.187 * X0 + 0.772 * X1 + 2.189 * X2 Ridge model: 0.964 * X0 + 0.982 * X1 + 1.098 * X2
Random seed 5 Linear model: -1.291 * X0 + 1.591 * X1 + 2.747 * X2 Ridge model: 0.758 * X0 + 1.011 * X1 + 1.139 * X2
Random seed 6 Linear model: 1.199 * X0 + -0.031 * X1 + 1.915 * X2 Ridge model: 1.016 * X0 + 0.89 * X1 + 1.091 * X2
Random seed 7 Linear model: 1.474 * X0 + 1.762 * X1 + -0.151 * X2 Ridge model: 1.018 * X0 + 1.039 * X1 + 0.901 * X2
Random seed 8 Linear model: 0.084 * X0 + 1.88 * X1 + 1.107 * X2 Ridge model: 0.907 * X0 + 1.071 * X1 + 1.008 * X2
Random seed 9 Linear model: 0.714 * X0 + 0.776 * X1 + 1.364 * X2 Ridge model: 0.896 * X0 + 0.903 * X1 + 0.98 * X2

可以看出客峭,不同的數(shù)據(jù)上線性回歸得到的模型(系數(shù))相差甚遠(yuǎn)豫领,但對(duì)于L2正則化模型來(lái)說(shuō),結(jié)果中的系數(shù)非常的穩(wěn)定舔琅,差別較小等恐,都比較接近于1,能夠反映出數(shù)據(jù)的內(nèi)在結(jié)構(gòu)备蚓。

3.4 隨機(jī)森林

隨機(jī)森林具有準(zhǔn)確率高课蔬、魯棒性好、易于使用等優(yōu)點(diǎn)郊尝,這使得它成為了目前最流行的機(jī)器學(xué)習(xí)算法之一二跋。隨機(jī)森林提供了兩種特征選擇的方法:mean decrease impurity和mean decrease accuracy。

3.4.1 平均不純度減少 mean decrease impurity

隨機(jī)森林由多個(gè)決策樹構(gòu)成流昏。決策樹中的每一個(gè)節(jié)點(diǎn)都是關(guān)于某個(gè)特征的條件扎即,為的是將數(shù)據(jù)集按照不同的響應(yīng)變量一分為二。利用不純度可以確定節(jié)點(diǎn)(最優(yōu)條件)况凉,對(duì)于分類問(wèn)題谚鄙,通常采用基尼不純度或者信息增益,對(duì)于回歸問(wèn)題刁绒,通常采用的是方差或者最小二乘擬合闷营。當(dāng)訓(xùn)練決策樹的時(shí)候,可以計(jì)算出每個(gè)特征減少了多少樹的不純度膛锭。對(duì)于一個(gè)決策樹森林來(lái)說(shuō)粮坞,可以算出每個(gè)特征平均減少了多少不純度蚊荣,并把它平均減少的不純度作為特征選擇的值。
下邊的例子是sklearn中基于隨機(jī)森林的特征重要度度量方法:

from sklearn.datasets import load_boston
from sklearn.ensemble import RandomForestRegressor
import numpy as np
#Load boston housing dataset as an example
boston = load_boston()
X = boston["data"]
Y = boston["target"]
names = boston["feature_names"]
rf = RandomForestRegressor()
rf.fit(X, Y)
print "Features sorted by their score:"
print sorted(zip(map(lambda x: round(x, 4), rf.feature_importances_), names), 
             reverse=True)
Features sorted by their score: [(0.5298, 'LSTAT'), (0.4116, 'RM'), (0.0252, 'DIS'), (0.0172, 'CRIM'), (0.0065, 'NOX'), (0.0035, 'PTRATIO'), (0.0021, 'TAX'), (0.0017, 'AGE'), (0.0012, 'B'), (0.0008, 'INDUS'), (0.0004, 'RAD'), (0.0001, 'CHAS'), (0.0, 'ZN')]

這里特征得分實(shí)際上采用的是Gini Importance莫杈。使用基于不純度的方法的時(shí)候互例,要記住:1筝闹、這種方法存在偏向媳叨,對(duì)具有更多類別的變量會(huì)更有利;2关顷、對(duì)于存在關(guān)聯(lián)的多個(gè)特征糊秆,其中任意一個(gè)都可以作為指示器(優(yōu)秀的特征),并且一旦某個(gè)特征被選擇之后议双,其他特征的重要度就會(huì)急劇下降痘番,因?yàn)椴患兌纫呀?jīng)被選中的那個(gè)特征降下來(lái)了,其他的特征就很難再降低那么多不純度了平痰,這樣一來(lái)汞舱,只有先被選中的那個(gè)特征重要度很高,其他的關(guān)聯(lián)特征重要度往往較低宗雇。在理解數(shù)據(jù)時(shí)昂芜,這就會(huì)造成誤解,導(dǎo)致錯(cuò)誤的認(rèn)為先被選中的特征是很重要的赔蒲,而其余的特征是不重要的泌神,但實(shí)際上這些特征對(duì)響應(yīng)變量的作用確實(shí)非常接近的(這跟Lasso是很像的)。
特征隨機(jī)選擇方法稍微緩解了這個(gè)問(wèn)題舞虱,但總的來(lái)說(shuō)并沒(méi)有完全解決欢际。下面的例子中,X0砾嫉、X1幼苛、X2是三個(gè)互相關(guān)聯(lián)的變量,在沒(méi)有噪音的情況下焕刮,輸出變量是三者之和舶沿。

size = 10000
np.random.seed(seed=10)
X_seed = np.random.normal(0, 1, size)
X0 = X_seed + np.random.normal(0, .1, size)
X1 = X_seed + np.random.normal(0, .1, size)
X2 = X_seed + np.random.normal(0, .1, size)
X = np.array([X0, X1, X2]).T
Y = X0 + X1 + X2

rf = RandomForestRegressor(n_estimators=20, max_features=2)
rf.fit(X, Y);
print "Scores for X0, X1, X2:", map(lambda x:round (x,3),
                                    rf.feature_importances_)

Scores for X0, X1, X2: [0.278, 0.66, 0.062]

當(dāng)計(jì)算特征重要性時(shí),可以看到X1的重要度比X2的重要度要高出10倍配并,但實(shí)際上他們真正的重要度是一樣的括荡。盡管數(shù)據(jù)量已經(jīng)很大且沒(méi)有噪音,且用了20棵樹來(lái)做隨機(jī)選擇溉旋,但這個(gè)問(wèn)題還是會(huì)存在畸冲。需要注意的一點(diǎn)是,關(guān)聯(lián)特征的打分存在不穩(wěn)定的現(xiàn)象,這不僅僅是隨機(jī)森林特有的邑闲,大多數(shù)基于模型的特征選擇方法都存在這個(gè)問(wèn)題算行。

3.4.2 平均精確率減少 Mean decrease accuracy

另一種常用的特征選擇方法就是直接度量每個(gè)特征對(duì)模型精確率的影響。主要思路是打亂每個(gè)特征的特征值順序苫耸,并且度量順序變動(dòng)對(duì)模型的精確率的影響州邢。很明顯,對(duì)于不重要的變量來(lái)說(shuō)褪子,打亂順序?qū)δP偷木_率影響不會(huì)太大量淌,但是對(duì)于重要的變量來(lái)說(shuō),打亂順序就會(huì)降低模型的精確率嫌褪。

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)
Features sorted by their score: [(0.7276, 'LSTAT'), (0.5675, 'RM'), (0.0867, 'DIS'), (0.0407, 'NOX'), (0.0351, 'CRIM'), (0.0233, 'PTRATIO'), (0.0168, 'TAX'), (0.0122, 'AGE'), (0.005, 'B'), (0.0048, 'INDUS'), (0.0043, 'RAD'), (0.0004, 'ZN'), (0.0001, 'CHAS')]

在這個(gè)例子當(dāng)中呀枢,LSTAT和RM這兩個(gè)特征對(duì)模型的性能有著很大的影響,打亂這兩個(gè)特征的特征值使得模型的性能下降了73%和57%笼痛。注意裙秋,盡管這些我們是在所有特征上進(jìn)行了訓(xùn)練得到了模型,然后才得到了每個(gè)特征的重要性測(cè)試晃痴,這并不意味著我們?nèi)拥裟硞€(gè)或者某些重要特征后模型的性能就一定會(huì)下降很多残吩,因?yàn)榧幢隳硞€(gè)特征刪掉之后,其關(guān)聯(lián)特征一樣可以發(fā)揮作用倘核,讓模型性能基本上不變。

4 兩種頂層特征選擇算法

之所以叫做頂層即彪,是因?yàn)樗麄兌际墙⒃诨谀P偷奶卣鬟x擇方法基礎(chǔ)之上的紧唱,例如回歸和SVM,在不同的子集上建立模型隶校,然后匯總最終確定特征得分漏益。

4.1 穩(wěn)定性選擇 Stability selection

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)
Features sorted by their score: [(1.0, 'RM'), (1.0, 'PTRATIO'), (1.0, 'LSTAT'), (0.62, 'CHAS'), (0.595, 'B'), (0.39, 'TAX'), (0.385, 'CRIM'), (0.25, 'DIS'), (0.22, 'NOX'), (0.125, 'INDUS'), (0.045, 'ZN'), (0.02, 'RAD'), (0.015, 'AGE')]

在上邊這個(gè)例子當(dāng)中,最高的3個(gè)特征得分是1.0深胳,這表示他們總會(huì)被選作有用的特征(當(dāng)然绰疤,得分會(huì)收到正則化參數(shù)alpha的影響,但是sklearn的隨機(jī)lasso能夠自動(dòng)選擇最優(yōu)的alpha)舞终。接下來(lái)的幾個(gè)特征得分就開始下降轻庆,但是下降的不是特別急劇,這跟純lasso的方法和隨機(jī)森林的結(jié)果不一樣敛劝。能夠看出穩(wěn)定性選擇對(duì)于克服過(guò)擬合和對(duì)數(shù)據(jù)理解來(lái)說(shuō)都是有幫助的:總的來(lái)說(shuō)余爆,好的特征不會(huì)因?yàn)橛邢嗨频奶卣鳌㈥P(guān)聯(lián)特征而得分為0夸盟,這跟Lasso是不同的蛾方。對(duì)于特征選擇任務(wù),在許多數(shù)據(jù)集和環(huán)境下,穩(wěn)定性選擇往往是性能最好的方法之一桩砰。

4.2 遞歸特征消除 Recursive feature elimination (RFE)

遞歸特征消除的主要思想是反復(fù)的構(gòu)建模型(如SVM或者回歸模型)然后選出最好的(或者最差的)的特征(可以根據(jù)系數(shù)來(lái)選)拓春,把選出來(lái)的特征放到一遍,然后在剩余的特征上重復(fù)這個(gè)過(guò)程亚隅,直到所有特征都遍歷了痘儡。這個(gè)過(guò)程中特征被消除的次序就是特征的排序。因此枢步,這是一種尋找最優(yōu)特征子集的貪心算法沉删。
RFE的穩(wěn)定性很大程度上取決于在迭代的時(shí)候底層用哪種模型。例如醉途,假如RFE采用的普通的回歸矾瑰,沒(méi)有經(jīng)過(guò)正則化的回歸是不穩(wěn)定的,那么RFE就是不穩(wěn)定的隘擎;假如采用的是Ridge殴穴,而用Ridge正則化的回歸是穩(wěn)定的,那么RFE就是穩(wěn)定的货葬。
Sklearn提供了RFE包采幌,可以用于特征消除,還提供了RFECV震桶,可以通過(guò)交叉驗(yàn)證來(lái)對(duì)的特征進(jìn)行排序休傍。



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.0, 'NOX'), (2.0, 'RM'), (3.0, 'CHAS'), (4.0, 'PTRATIO'), (5.0, 'DIS'), (6.0, 'LSTAT'), (7.0, 'RAD'), (8.0, 'CRIM'), (9.0, 'INDUS'), (10.0, 'ZN'), (11.0, 'TAX'), (12.0, 'B'), (13.0, 'AGE')]

總結(jié)

  1. 對(duì)于理解數(shù)據(jù)、數(shù)據(jù)的結(jié)構(gòu)蹲姐、特點(diǎn)來(lái)說(shuō)磨取,單變量特征選擇是個(gè)非常好的選擇。盡管可以用它對(duì)特征進(jìn)行排序來(lái)優(yōu)化模型柴墩,但由于它不能發(fā)現(xiàn)冗余(例如假如一個(gè)特征子集忙厌,其中的特征之間具有很強(qiáng)的關(guān)聯(lián),那么從中選擇最優(yōu)的特征時(shí)就很難考慮到冗余的問(wèn)題)江咳。
  2. 正則化的線性模型對(duì)于特征理解和特征選擇來(lái)說(shuō)是非常強(qiáng)大的工具逢净。L1正則化能夠生成稀疏的模型,對(duì)于選擇特征子集來(lái)說(shuō)非常有用歼指;相比起L1正則化爹土,L2正則化的表現(xiàn)更加穩(wěn)定,由于有用的特征往往對(duì)應(yīng)系數(shù)非零东臀,因此L2正則化對(duì)于數(shù)據(jù)的理解來(lái)說(shuō)很合適着饥。由于響應(yīng)變量和特征之間往往是非線性關(guān)系,可以采用basis expansion的方式將特征轉(zhuǎn)換到一個(gè)更加合適的空間當(dāng)中惰赋,在此基礎(chǔ)上再考慮運(yùn)用簡(jiǎn)單的線性模型宰掉。
  3. 隨機(jī)森林是一種非常流行的特征選擇方法呵哨,它易于使用,一般不需要feature engineering轨奄、調(diào)參等繁瑣的步驟孟害,并且很多工具包都提供了平均不純度下降方法。它的兩個(gè)主要問(wèn)題挪拟,1是重要的特征有可能得分很低(關(guān)聯(lián)特征問(wèn)題)挨务,2是這種方法對(duì)特征變量類別多的特征越有利(偏向問(wèn)題)。盡管如此玉组,這種方法仍然非常值得在你的應(yīng)用中試一試谎柄。
  4. 特征選擇在很多機(jī)器學(xué)習(xí)和數(shù)據(jù)挖掘場(chǎng)景中都是非常有用的。在使用的時(shí)候要弄清楚自己的目標(biāo)是什么惯雳,然后找到哪種方法適用于自己的任務(wù)朝巫。當(dāng)選擇最優(yōu)特征以提升模型性能的時(shí)候,可以采用交叉驗(yàn)證的方法來(lái)驗(yàn)證某種方法是否比其他方法要好石景。當(dāng)用特征選擇的方法來(lái)理解數(shù)據(jù)的時(shí)候要留心劈猿,特征選擇模型的穩(wěn)定性非常重要,穩(wěn)定性差的模型很容易就會(huì)導(dǎo)致錯(cuò)誤的結(jié)論潮孽。對(duì)數(shù)據(jù)進(jìn)行二次采樣然后在子集上運(yùn)行特征選擇算法能夠有所幫助揪荣,如果在各個(gè)子集上的結(jié)果是一致的,那就可以說(shuō)在這個(gè)數(shù)據(jù)集上得出來(lái)的結(jié)論是可信的往史,可以用這種特征選擇模型的結(jié)果來(lái)理解數(shù)據(jù)仗颈。
    本文轉(zhuǎn)載自:http://chaoslog.com/te-zheng-xuan-ze.html
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市怠堪,隨后出現(xiàn)的幾起案子揽乱,更是在濱河造成了極大的恐慌,老刑警劉巖粟矿,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異损拢,居然都是意外死亡陌粹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門福压,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)掏秩,“玉大人,你說(shuō)我怎么就攤上這事荆姆∶苫茫” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵胆筒,是天一觀的道長(zhǎng)邮破。 經(jīng)常有香客問(wèn)我诈豌,道長(zhǎng),這世上最難降的妖魔是什么抒和? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任矫渔,我火速辦了婚禮,結(jié)果婚禮上摧莽,老公的妹妹穿的比我還像新娘庙洼。我一直安慰自己,他們只是感情好镊辕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布油够。 她就那樣靜靜地躺著,像睡著了一般征懈。 火紅的嫁衣襯著肌膚如雪石咬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天受裹,我揣著相機(jī)與錄音碌补,去河邊找鬼。 笑死棉饶,一個(gè)胖子當(dāng)著我的面吹牛厦章,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播照藻,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼袜啃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了幸缕?” 一聲冷哼從身側(cè)響起群发,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎发乔,沒(méi)想到半個(gè)月后熟妓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡栏尚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年起愈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片译仗。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抬虽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纵菌,到底是詐尸還是另有隱情阐污,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布咱圆,位于F島的核電站笛辟,受9級(jí)特大地震影響功氨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隘膘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一疑故、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弯菊,春花似錦纵势、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至才漆,卻和暖如春牛曹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背醇滥。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工黎比, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鸳玩。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓阅虫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親不跟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子颓帝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容