特徵工程與scikit-learn

歡迎關注我的公眾號:AI_Engine。知乎,簡書同名呦~今日頭條搜索:極意就是在下啦!歡迎轉發,評論噢!

Filter過濾法

過濾法通常在預處理階段使用,特徵選擇完全獨立於任何算法之外。

  • 方差過濾
<code>    **本質:** 使用特徵本身的方差來消除方差小於閾值的特徵。/<code>
<code>    **API:** VarianceThreshold/<code>
<code>    **實例:**/<code>
<code>import pandas as pd
data = pd.read_csv(r'../Data/digit recognizor.csv')
x = data.iloc[:,1:]
y = data.iloc[:,0]
x.shape

(42000, 784)/<code>
<code>from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold() # 實例化,默認方差為0
x_var = selector.fit_transform(x) # 獲取刪除不合格特徵之後的新特徵矩陣
x_var.shape

(42000, 708)/<code>
<code>import numpy as np
median = np.median(x.var().values)
median

1352.286703180131/<code>
<code>x_fc_var = VarianceThreshold(threshold=median).fit_transform(x)
x_fc_var.shape

(42000, 392)/<code>
<code>%%timeit # 魔法命令,計算運行時間
# 當特徵是二分類是,特徵的取值就是伯努利隨機變量,這些變量的方差可以計算為var[x] = p(1-p),其中x是特徵矩陣,p是二分類特徵中的一類在這個特徵中所佔的概率
# 若特徵是伯努利隨機變量,p=0.8,即二分類特徵中某種分類佔到80%以上的時候刪除特徵
x_bvar = VarianceThreshold(threshold=0.8 * (1-0.8)).fit_transform(x)
x_bvar.shape

(42000, 685)/<code>
  • 卡方過濾
<code>    **本質:** 計算特徵與標籤的相關性,相關性可以根據卡方值和p值進行判定。一般情況下,p值<0.05或=0.01時,特徵與標籤即為相關,該特徵可以保留。/<code>
<code>    API:chi2,SelectKBest/<code>
<code>    **實例:**/<code>
<code>from sklearn.feature_selection import chi2
from sklearn.feature_selection import SelectKBest
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
x_chi_fc_var = SelectKBest(chi2, k=300).fit_transform(x_fc_var, y) # 根據卡方選取得分最高的前300個特徵

(42000, 300)/<code>

計算每個特徵的卡方值與p值

<code>chi_value, p_value = chi2(x_fc_var, y)
chi_value

p_value/<code>

計算k的合理值

<code>k = chi_value.shape[0] - (p_value>0.05).sum()
k

392/<code>
  • F檢驗
<code>    **本質:** 方差齊性檢驗,通過特徵與標間的線性關係進行過濾。(它的本假設是特徵與標籤不存在顯著的線性關係)/<code>
<code>    **API:** f_classif/<code>
<code>    **實例:**/<code>
<code>from sklearn.feature_selection import f_classif
f_value, p_value = f_classif(x_fc_var, y)
f_value.shape
p_value.shape

(392,)
(392,)/<code>
<code>k = f_value.shape[0] - (p_value>0.05).sum()
k

392/<code>
<code>from sklearn.feature_selection import SelectKBest
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
x_f_fc_var = SelectKBest(f_classif, k=392).fit_transform(x_fc_var, y) # 根據F檢驗選取得分最高的前392個特徵
x_f_fc_var.shape

(42000, 392)

cross_val_score(RandomForestClassifier(n_estimators=10,random_state=0), x_fc_var, y, cv=5).mean()

0.9388098166696807/<code>
  • 互信息法
<code>    **本質:** 通過特徵與標籤之間的線性或非線性關係進行過濾。互信息法比F檢驗強大,而且不返回p值和f值,而是返回特徵與標籤之間的互信息量估計(0到1),0表示兩個變量獨立,1表示變量完全相關。/<code>
<code>    **API:** mutual_info_classif(互信息分類);mutual_info_regression(互信息迴歸)/<code>
<code>    **實例:**/<code>
<code>from sklearn.feature_selection import mutual_info_classif as mic
result = mic(x_fc_var, y)
k = result.shape[0] - (result<0).sum()
k

392/<code>
<code>x_mic_fc_var = SelectKBest(mic, k=392).fit_transform(x_fc_var, y) # 根據互信息法選取得分最高的前300個特徵
x_mic_fc_var.shape

(42000, 392)

cross_val_score(RandomForestClassifier(n_estimators=10,random_state=0), x_mic_fc_var, y, cv=5).mean()

0.9388098166696807/<code>


Embedded嵌入法

一句話總結: 一種算法自主選擇特徵的方法,是過濾法的強化版。

API: SelectFromModel

其他: 對於使用懲罰項的模型來說,正則化懲罰項越大,特徵在模型中對應的係數就會越小。當正則化懲罰項大到一定的程度的時候,部分特徵係數會變成0,當正則化懲罰項繼續增大到一定程度時,所有的特徵係數都會趨於0。但是我們會發現一部分特徵係數會更容易先變成0,這部分系數就是可以篩掉的。也就是說,我們選擇特徵係數較大的特徵。另外,支持向量機和邏輯迴歸使用參數C來控制返回的特徵矩陣的稀疏性,參數C越小,返回的特徵越少。Lasso迴歸用alpha參數來控制返回的特徵矩陣,alpha的值越大,返回的特徵越少。

實例:

<code>import pandas as pd
data = pd.read_csv(r'../Data/digit recognizor.csv')
x = data.iloc[:,1:]
y = data.iloc[:,0]

from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=10, random_state=0).fit(x, y)
clf.feature_importances_/<code>
<code>clf = RandomForestClassifier(n_estimators=10, random_state=0)
x_embedded = SelectFromModel(estimator=clf, threshold=0.005).fit_transform(x, y)
x_embedded.shape

(42000, 47)/<code>

利用學習曲線尋找最佳threshold的值

<code>%matplotlib inline  
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import cross_val_score
thresholds = np.linspace(0,(clf.fit(x, y).feature_importances_).max(),10)
scores = []
for threshold in thresholds:
x_embedded = SelectFromModel(clf, threshold=threshold).fit_transform(x, y)
score = cross_val_score(clf, x_embedded, y, cv=5).mean()
scores.append(score)
plt.plot(thresholds, scores)
plt.show()/<code>

evernotecid://199A0999-284B-465C-AF36-D243A9FA840A/appyinxiangcom/18720816/ENResource/p780

特徵工程與scikit-learn

根據學習曲線在將threshold的粒度進行細化,觀測新學習曲線。

<code>scores = []
for threshold in np.linspace(0, 0.002, 10):
x_embedded = SelectFromModel(clf, threshold=threshold).fit_transform(x, y)
score = cross_val_score(clf, x_embedded, y, cv=5).mean()
scores.append(score)
plt.figure(figsize=[20, 5])
plt.plot(np.linspace(0, 0.002, 10), scores)
plt.xticks(np.linspace(0, 0.002, 10))
plt.show()/<code>

evernotecid://199A0999-284B-465C-AF36-D243A9FA840A/appyinxiangcom/18720816/ENResource/p781

特徵工程與scikit-learn

Wrapper包裝法

本質: 特徵選擇與算法訓練同時進行的方法。與嵌入法選擇特徵不同的是,包裝法會選擇一個目標函數幫助我們選擇特徵,而不是我們輸入的某個評估指標和統計量閾值。

思想: 包裝法在初始特徵中根據特徵重要性評估每個特徵,然後從當前一組剔除某些特徵並重復該過程,直至剩餘特徵的數量滿足我們的要求。

複雜度: 過濾法 嵌入法> 包裝法>

API: RFE。其中重要的屬性是.support(返回所有特徵中的選擇結果的bool矩陣)、以及.ranking(返回特徵的迭代選擇後的綜合重要性排名)

實例:

<code>from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
clf = RandomForestClassifier(n_estimators=10, random_state=0)
rfe = RFE(estimator=clf, n_features_to_select=340, step=50).fit(x, y)
rfe.support_.sum()

340/<code>
<code>rfe.ranking_/<code>
<code>x_rfe = rfe.transform(x)
x_rfe

array([[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
...,
[ 0, 0, 0, ..., 0, 128, 255],
[ 0, 0, 146, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0]])/<code>
<code>cross_val_score(estimator=clf, X=x_rfe, y=y ,cv=5).mean()

0.9389522459432109/<code>
<code>%matplotlib inline  
import matplotlib.pyplot as plt
scores = []
for i in range(1, 751, 50):
x_rfe = RFE(estimator=clf, n_features_to_select=i, step=50).fit_transform(x, y)
score = cross_val_score(clf, x_rfe, y, cv=5).mean()
scores.append(score)
plt.figure(figsize=[20, 5])
plt.plot(range(1, 751, 50), scores)
plt.xticks(range(1, 751, 50))
plt.show()/<code>

evernotecid://199A0999-284B-465C-AF36-D243A9FA840A/appyinxiangcom/18720816/ENResource/p782

特徵工程與scikit-learn

qrcodeforghc7b832457165430.jpg

特徵工程與scikit-learn


分享到:


相關文章: