特徵工程(三)特徵選擇

經過“數據清理”和“特徵變換”後的數據集,已經滿足了數據科學項目中算法對數值的基本要求。但是, 不呢止步於此,數據集的特徵數量、質量會影響計算效率和最終模型的預測、分類效果。所以要對特徵進行選擇,即根據具體的項目選擇適合的特徵。

特徵選擇

3.1 特徵選擇簡述

是不是維度越大的數據越好?是不是所有的維度都是必須的?

import pandas as pd
df_wine = pd.read_csv("datasets/wine_data.csv")
df_wine.head()
Class_label Alcohol Malic_acid Ash Alcalinity_of_ash Magnesium Total_phenols Flavanoids Nonflavanoid_phenols Proanthocyanins Color_intensity Hue OD280/OD315_of_diluted_wines Proline
0 1 14.23 1.71 2.43 15.6 127 2.80 3.06 0.28 2.29 5.64 1.04 3.92 1065
1 1 13.20 1.78 2.14 11.2 100 2.65 2.76 0.26 1.28 4.38 1.05 3.40 1050
2 1 13.16 2.36 2.67 18.6 101 2.80 3.24 0.30 2.81 5.68 1.03 3.17 1185
3 1 14.37 1.95 2.50 16.8 113 3.85 3.49 0.24 2.18 7.80 0.86 3.45 1480
4 1 13.24 2.59 2.87 21.0 118 2.80 2.69 0.39 1.82 4.32 1.04 2.93 735

依據機器學習的一般流程,把數據集劃分爲訓練集和測試集,並且對測試集和訓練集分別實現特徵標準化。

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
X, y = df_wine.iloc[:, 1:], df_wine.iloc[:, 0].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0, stratify=y)

std = StandardScaler()
X_train_std = std.fit_transform(X_train)
X_test_std = std.fit_transform(X_test)

以Class_label爲標籤,建立對數迴歸模型,尋找另外13個特徵與標籤之間的關係。

from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(penalty='l1', C=1.0 , solver='liblinear') 
lr.fit(X_train_std, y_train)

LogisticRegression(penalty='l1', solver='liblinear')

在創建對數概率迴歸模型時候,使用了參數penalty='l1', C=1.0,這意味着在本模型中遵照此規則增加了懲罰項,其意圖是避免訓練得到的模型過擬合,也正是出於這個原因,模型捨棄了部分特性——表現出來就是係數爲0

lr.coef_
array([[ 1.24568008,  0.18066268,  0.74500129, -1.16270324,  0.        ,
         0.        ,  1.16473536,  0.        ,  0.        ,  0.        ,
         0.        ,  0.55281296,  2.50976773],
       [-1.53710813, -0.38760504, -0.99525286,  0.36504305, -0.05948103,
         0.        ,  0.66797894,  0.        ,  0.        , -1.93413502,
         1.23360251,  0.        , -2.23189735],
       [ 0.13448113,  0.16969503,  0.35805173,  0.        ,  0.        ,
         0.        , -2.43221807,  0.        ,  0.        ,  1.56308975,
        -0.81943572, -0.49548102,  0.        ]])
lr.intercept_

array([-1.26347923, -1.21597948, -2.36926979])

在機器學習中,過擬合是比較常見的現象,通常採用如下避免方法:

  • 訓練集和測試集五五開
  • 在模型中增加懲罰項,簡化模型
  • 儘可能選用參數少的模型
  • 降低數據集的維度

特徵選擇,是指去除數據集中的冗餘和無關的特徵,從數據集中找出主要特徵,最終得到得到的是原有特徵的子集。因此,特徵選擇也稱爲“特徵子集選擇”

爲實現特徵選擇,這裏介紹三類方法:封裝器法、過濾器法和嵌入法。

3.2 封裝器法

封裝器法的基本思路是:

  1. 選用一個特徵子集訓練模型,此處的模型通常是一種機器學習算法,也稱爲目標函數。
  2. 用驗證數據集對模型進行評估。
  3. 依據某種搜索方式,對不同的特徵子集進行上述操作,
  4. 依據評估結果,選出相對最佳的特徵子集。

image-20220609191735736

這種方式屬於貪心搜索算法,計算量較大。針對特徵子集的組合搜索問題,封裝法有下述三種常見的選擇方式。

循序特徵選擇

包括 循環向前(SFS)和循環向後(SBS)

基礎知識

以SFS爲例:

(1)創建一個空的集合X,作爲特徵子集
(2)從原特徵集合中“一次挑選一個”——這就是“循序”的含義,與特徵子集X中的特徵組合,並使得目標函數(選定的某個機器學習模型)結果最佳(模型預測的誤差最小)
(3)將挑選出來的特徵從原特徵中移除,同時將其追加到X中。
(4)重複(2)、(3)步驟,直到集合X的特徵數量達到規定的數量爲止,中止上述循環。

顯然,SFS不是把所有可能都實現一遍,而是找到一種可能最優解即中止尋找,這樣就大大降低了計算量。
mlxtend的第三庫提供了實現包含SFS的多種循環特徵選擇方法

pip install mlxtend

mlxtend中集成了幾個數據集,這裏使用關於葡萄酒的數據。X有13個特徵178個樣本,y是每個樣本的標籤,即每種葡萄酒的等級(共有3級,用0,1,2表示)。其中,X的13特徵依次對應的名稱是:

  1. Alcohol
  2. Malic acid
  3. Ash
  4. Alcalinity of ash
  5. Magnesium
  6. Total phenols
  7. Flavanoids
  8. Nonflavanoid phenols
  9. Proanthocyanins
  10. Color intensity
  11. Hue
  12. OD280/OD315 of diluted wines
  13. Proline

https://archive.ics.uci.edu/ml/datasets/Wine

from mlxtend.feature_selection import SequentialFeatureSelector as SFS
from sklearn.neighbors import KNeighborsClassifier
from mlxtend.data import wine_data
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

X, y = wine_data()
X.shape

(178, 13)

X_train, X_test, y_train, y_test= train_test_split(X, y, 
                                                   stratify=y,
                                                   test_size=0.3,
                                                   random_state=1)
std = StandardScaler() #標準化
X_train_std = std.fit_transform(X_train)

knn = KNeighborsClassifier(n_neighbors=3)    # knn作爲SFS的目標函數
sfs = SFS(estimator=knn,     # SFS封裝器
           k_features=4,     # 選擇4個最佳特徵
           forward=True, 
           floating=False, 
           verbose=2,         # 2輸出訓練過程的全部日誌信息
           scoring='accuracy',#模型評估方法
           cv=0)              # 0 表示不進行交叉驗證
sfs.fit(X_train_std, y_train)
[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s
[Parallel(n_jobs=1)]: Done  13 out of  13 | elapsed:    0.0s finished

[2022-06-09 19:28:12] Features: 1/4 -- score: 0.8548387096774194[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s
[Parallel(n_jobs=1)]: Done  12 out of  12 | elapsed:    0.0s finished

[2022-06-09 19:28:12] Features: 2/4 -- score: 0.9596774193548387[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s
[Parallel(n_jobs=1)]: Done  11 out of  11 | elapsed:    0.0s finished

[2022-06-09 19:28:12] Features: 3/4 -- score: 0.9919354838709677[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.
[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed:    0.0s remaining:    0.0s
[Parallel(n_jobs=1)]: Done  10 out of  10 | elapsed:    0.0s finished

[2022-06-09 19:28:12] Features: 4/4 -- score: 0.9838709677419355

從輸出的日誌信息可以很明確地看出,當選擇3個特徵的時候,模型knn表現最好

sfs.subsets_
{1: {'feature_idx': (6,),
  'cv_scores': array([0.85483871]),
  'avg_score': 0.8548387096774194,
  'feature_names': ('6',)},
 2: {'feature_idx': (6, 9),
  'cv_scores': array([0.95967742]),
  'avg_score': 0.9596774193548387,
  'feature_names': ('6', '9')},
 3: {'feature_idx': (6, 9, 11),
  'cv_scores': array([0.99193548]),
  'avg_score': 0.9919354838709677,
  'feature_names': ('6', '9', '11')},
 4: {'feature_idx': (6, 8, 9, 11),
  'cv_scores': array([0.98387097]),
  'avg_score': 0.9838709677419355,
  'feature_names': ('6', '8', '9', '11')}}

利用SFS的屬性subsets_得到了每次選擇出來的特徵及其相應的評估分數,feature_names表示特徵名稱。

項目案例

使用隨機森林迴歸作爲目標函數,從房價數據集中,選擇出10佳特徵

import pandas as pd
from sklearn.ensemble import RandomForestRegressor

df = pd.read_csv("datasets/housprice.csv")
cols = list(df.select_dtypes(include=['int64', 'float64']).columns)  
data = df[cols]

X_train,X_test,y_train,y_test= train_test_split(
            data.drop('SalePrice',axis=1),
            data['SalePrice'],
            test_size=.2,
            random_state=1#隨機數生成器使用的種子
)

X_train.fillna(0, inplace=True)    # 用0填充缺失值

sfs3 = SFS(RandomForestRegressor(),    
           k_features=10,
           forward=True,
           verbose=0,
           cv=5,
           n_jobs=-1,
           scoring='r2')
sfs3.fit(X_train,y_train)
sfs3.k_feature_names_

('MSSubClass',
'OverallQual',
'OverallCond',
'YearRemodAdd',
'BsmtFinSF1',
'TotalBsmtSF',
'GrLivArea',
'Fireplaces',
'GarageCars',
'3SsnPorch')

窮舉特徵選擇

指封裝器中的搜索算法先將所有特徵組合都實現一遍,然後通過比較各種特徵組合後的模型表現,從中選擇出最佳得到特徵子集。
顯然窮舉特徵選擇必然浪費更大的計算量。

# 對上面SFS練習題中的10個特徵的數據集,對它使用窮舉法,從10佳中選出5強
mini_data = X_train[X_train.columns[list(sfs3.k_feature_idx_)]]    
mini_data.shape

(1168, 10)

import numpy as np
from mlxtend.feature_selection import ExhaustiveFeatureSelector as EFS
efs = EFS(RandomForestRegressor(),
          min_features=1,
          max_features=5,
          scoring='r2',
          n_jobs=-1)    
efs.fit(np.array(mini_data),y_train)
mini_data.columns[list(efs.best_idx_)]

Index(['MSSubClass', 'OverallQual', 'YearRemodAdd', 'BsmtFinSF1', 'GrLivArea'], dtype='object')

很顯然,窮舉特徵選擇也是構建了一個封裝器,在封裝器裏使用了一種機器學習算法作爲目標函數。

遞歸特徵消除

遞歸特徵消除RFE也是封裝器法的一種具體實施,其主要思想是利用訓練集數據生成模型,再根據模型的特徵權重,對特徵進行取捨,消除權重不同的特徵,從而得到數據集的特徵子集。然後,對這個特徵子集重複上述過程,直到特徵數量達到規定值爲止。顯然,這種尋找最優特徵子集的方法依然是貪心搜索算法。

from sklearn.feature_selection import RFE
# 爲避免大規模計算,還是從10佳中選擇5強,
mini_data = X_train[X_train.columns[list(sfs3.k_feature_idx_)]]  

rfe = RFE(RandomForestRegressor(), #依舊使用隨機森林迴歸
          n_features_to_select=5)     
rfe.fit(np.array(mini_data),y_train)
rfe.ranking_

array([4, 1, 3, 2, 1, 1, 1, 5, 1, 6])

對mini_data的各個特徵的權重從高到低排序之後,表示順序的序號,1表示相應索引的特徵權重最靠前,也就是權重最高。

mini_data.columns[rfe.ranking_==1]

Index(['OverallQual', 'BsmtFinSF1', 'TotalBsmtSF', 'GrLivArea', 'GarageCars'], dtype='object')

對比發現,使用不同的方法選出的5強不完全一致,因此不同的特徵方法會訓練出不同效果的模型

3.3 過濾器法

過濾器法不評估子集的預測誤差,而是使用某些統計指標,比如相關係數、互信息等——目標函數不同,根據這些統計指標,對各特徵進行排序,以確定特徵的取捨。

image-20220609194319468

下面用卡方檢驗(皮爾森卡方檢驗)作爲統計指標選擇特徵

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
skb = SelectKBest(chi2, k=2)    #k爲2表示特徵子集中的特徵數量
result = skb.fit(X, y)    # 根據從大到小的排序取2個特徵
print("X^2 is: ", result.scores_)
print("P-values is: ", result.pvalues_)
X^2 is:  [ 10.81782088   3.7107283  116.31261309  67.0483602 ]
P-values is:  [4.47651499e-03 1.56395980e-01 5.53397228e-26 2.75824965e-15]
  • 卡方檢驗是統計學上的假設檢驗方法。值越大,兩個變量之間的偏差越大;反之,偏差越小。
  • P值是統計學中用於判斷假設檢驗結果的參數。P值越小,原假設發生的概率就越小。

利用訓練得到的模型對數據集X進行特徵選擇,得到含有兩個特徵的新數據集

X_new = skb.transform(X) 
X_new.shape

(150, 2)

顯示數據對應的特徵名稱

import numpy as np
[iris.feature_names[np.where(X[0, :]==i)[0][0]] for i in X_new[0, :]]

['petal length (cm)', 'petal width (cm)']

過濾法中利用統計指標對特徵排序,然後依據特徵排序結果選擇特徵

iris.feature_names

['sepal length (cm)',
'sepal width (cm)',
'petal length (cm)',
'petal width (cm)']

過濾器的實現路徑可以表示爲:

過濾器法和封裝器法對比:

  • 過濾器法通常不對數據集執行迭代計算,因此計算速度比封裝器法要快
  • 封裝器的目標函數是某個機器學習算法,過濾器的函數則是通用的統計函數,這樣使得過濾器法所得到的特徵更具有通用性,非專門針對某個算法有良好表現
  • 利用過濾器法進行特徵選擇時,用戶需要武斷地輸入閾值,這可能會導致一定的選擇成本。
  • 如果特徵數量過少,過濾器可能無法找到最佳的特徵子集,而封裝器總能返回特徵子集
  • 因爲過濾器所得特徵子集與某種算法無關,所以一般不會出現過擬合現象,而經由封裝器法所得特徵子集訓練的模型,會出現過擬合現象。

在項目中,應依據具體數據和項目要求,確定特徵選擇的實施方法。

3.4 嵌入法

在3.1節中曾用對數概率迴歸模型研究了葡萄酒的等級與特徵的關係。因爲在模型中使用了L1懲罰項,從而得到了特徵係數的稀疏解,某些特徵的係數爲0。如此,可以對係數排序——特徵權重,然後依據某個閾值選擇部分特徵。

這種特性選擇的實現方法顯然不是封裝法,也不是過濾器法,而是在訓練模型的同時,得到了特徵權重,並完成特徵選擇。像這樣將特徵選擇過程與訓練模型融爲一體,在模型訓練過程中自動進行特徵選擇,被稱爲嵌入法特徵選擇。

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression

df_wine = pd.read_csv("datasets/wine_data.csv")
X, y = df_wine.iloc[:, 1:], df_wine.iloc[:, 0].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0, stratify=y)

std = StandardScaler()
X_train_std = std.fit_transform(X_train)
X_test_std = std.fit_transform(X_test)
# 創建對數概率迴歸模型,採用L1懲罰項
lr = LogisticRegression(C=1.0, penalty='l1', solver='liblinear')  
# 規定選擇特徵的閾值--特徵權重的中位數
# 能夠用的機器學習模型還有隨機森林模型、決策樹模型、LASSO迴歸模型、嶺迴歸模型等
model = SelectFromModel(lr, threshold='median')   
X_new = model.fit_transform(X_train_std, y_train)

X_new.shape

(124, 7)

X_train_std.shape

(124, 13)

3.5 綜合練習

import pandas as pd
df = pd.read_csv("datasets/app_small.csv")
df.drop('Unnamed: 0', axis=1, inplace=True) # 刪除第一列
df.shape

(30751, 122)

df.columns

Index(['SK_ID_CURR', 'TARGET', 'NAME_CONTRACT_TYPE', 'CODE_GENDER',
'FLAG_OWN_CAR', 'FLAG_OWN_REALTY', 'CNT_CHILDREN', 'AMT_INCOME_TOTAL',
'AMT_CREDIT', 'AMT_ANNUITY',
...
'FLAG_DOCUMENT_18', 'FLAG_DOCUMENT_19', 'FLAG_DOCUMENT_20',
'FLAG_DOCUMENT_21', 'AMT_REQ_CREDIT_BUREAU_HOUR',
'AMT_REQ_CREDIT_BUREAU_DAY', 'AMT_REQ_CREDIT_BUREAU_WEEK',
'AMT_REQ_CREDIT_BUREAU_MON', 'AMT_REQ_CREDIT_BUREAU_QRT',
'AMT_REQ_CREDIT_BUREAU_YEAR'],
dtype='object', length=122)

共有122個特徵

數字類型的特徵和非數字類型的特徵分別保存到不同的列表中

categorical_list = []
numerical_list = []
for i in df.columns.tolist():
    if df[i].dtype=='object':
        categorical_list.append(i)
    else:
        numerical_list.append(i)
print('Number of categorical features:', str(len(categorical_list)))
print('Number of numerical features:', str(len(numerical_list)))

Number of categorical features: 16
Number of numerical features: 106

將數值類型和分類型分別查出來共有16個分類型,106個數值類型

df[numerical_list].isna().any()

SK_ID_CURR False
TARGET False
CNT_CHILDREN False
AMT_INCOME_TOTAL False
AMT_CREDIT False
...
AMT_REQ_CREDIT_BUREAU_DAY True
AMT_REQ_CREDIT_BUREAU_WEEK True
AMT_REQ_CREDIT_BUREAU_MON True
AMT_REQ_CREDIT_BUREAU_QRT True
AMT_REQ_CREDIT_BUREAU_YEAR True
Length: 106, dtype: bool

檢查numerical_list中的特徵是否有缺失值,如果有缺失值,則用中位數填補

from sklearn.impute  import SimpleImputer
df[numerical_list] = SimpleImputer(strategy='median').fit_transform(df[numerical_list])

categorical_list中的特徵都是分類型特徵,於是乎進行OneHot編碼(創建虛擬變量)

df = pd.get_dummies(df, drop_first=True)
df.shape

(30751, 228)

df
SK_ID_CURR TARGET CNT_CHILDREN AMT_INCOME_TOTAL AMT_CREDIT AMT_ANNUITY AMT_GOODS_PRICE REGION_POPULATION_RELATIVE DAYS_BIRTH DAYS_EMPLOYED ... FONDKAPREMONT_MODE_reg oper spec account HOUSETYPE_MODE_specific housing HOUSETYPE_MODE_terraced house WALLSMATERIAL_MODE_Mixed WALLSMATERIAL_MODE_Monolithic WALLSMATERIAL_MODE_Others WALLSMATERIAL_MODE_Panel WALLSMATERIAL_MODE_Stone, brick WALLSMATERIAL_MODE_Wooden EMERGENCYSTATE_MODE_Yes
0 100003.0 0.0 0.0 270000.000 1293502.5 35698.5 1129500.0 0.003541 -16765.0 -1188.0 ... 0 0 0 0 0 0 0 0 0 0
1 100015.0 0.0 0.0 38419.155 148365.0 10678.5 135000.0 0.015221 -20417.0 365243.0 ... 0 0 0 0 0 0 0 0 0 0
2 100051.0 0.0 0.0 202500.000 661702.5 48280.5 598500.0 0.007114 -9827.0 -758.0 ... 0 0 0 0 0 0 0 0 0 0
3 100054.0 0.0 0.0 99000.000 260640.0 26838.0 225000.0 0.022625 -20121.0 -5332.0 ... 0 0 0 0 0 0 0 0 0 0
4 100069.0 0.0 1.0 360000.000 640458.0 27265.5 517500.0 0.007330 -14186.0 -1743.0 ... 0 0 0 0 0 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
30746 456195.0 0.0 0.0 94500.000 270000.0 15075.0 270000.0 0.028663 -20246.0 -5452.0 ... 0 0 0 0 0 0 0 1 0 0
30747 456212.0 0.0 1.0 135000.000 808650.0 23773.5 675000.0 0.009657 -18042.0 -186.0 ... 0 0 0 0 0 0 0 0 0 0
30748 456219.0 0.0 1.0 112500.000 521280.0 31630.5 450000.0 0.006207 -13346.0 -1972.0 ... 0 0 0 0 0 0 0 0 0 0
30749 456237.0 0.0 0.0 135000.000 946764.0 37678.5 765000.0 0.019689 -17533.0 -2306.0 ... 0 0 0 0 0 0 0 0 0 0
30750 456253.0 0.0 0.0 153000.000 677664.0 29979.0 585000.0 0.005002 -14966.0 -7921.0 ... 0 0 0 0 0 0 1 0 0 0

30751 rows × 228 columns

X = df.drop(['SK_ID_CURR', 'TARGET'], axis=1)
y = df['TARGET']
feature_name = X.columns.tolist()

先對X進行特徵規範化操作,而後利用卡方檢驗選擇50個特徵

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
from sklearn.preprocessing import MinMaxScaler

X_norm = MinMaxScaler().fit_transform(X)    # MinMax區間化
chi_selector = SelectKBest(chi2, k=50)    # 過濾器法
chi_selector.fit(X_norm, y)

SelectKBest(k=50, score_func=<function chi2 at 0x000001C74C48F310>)

chi_support = chi_selector.get_support()
chi_feature = X.loc[:,chi_support].columns.tolist()  

使用封裝器,選50個特徵

from sklearn.feature_selection import RFE    
from sklearn.linear_model import LogisticRegression
rfe_selector = RFE(estimator=LogisticRegression(penalty="l1",solver='liblinear'), n_features_to_select=50, step=10, verbose=5)   
rfe_selector.fit(X_norm, y)    
rfe_support = rfe_selector.get_support()
rfe_feature = X.loc[:,rfe_support].columns.tolist()

用嵌入法選擇特徵

from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression    #使用logistic迴歸模型

embeded_lr_selector = SelectFromModel(LogisticRegression(penalty="l1",solver='liblinear'),threshold= '1.25*median')
embeded_lr_selector.fit(X_norm, y)

embeded_lr_support = embeded_lr_selector.get_support()
embeded_lr_feature = X.loc[:,embeded_lr_support].columns.tolist()
print(str(len(embeded_lr_feature)), 'selected features')

105 selected features

不用對數機率迴歸模型,改爲隨機森林分類

from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifier    #相對上面,模型換了

embeded_rf_selector = SelectFromModel(RandomForestClassifier(n_estimators=50), threshold='1.25*median')
embeded_rf_selector.fit(X, y)

embeded_rf_support = embeded_rf_selector.get_support()
embeded_rf_feature = X.loc[:,embeded_rf_support].columns.tolist()
print(str(len(embeded_rf_feature)), 'selected features')

98 selected features

# 下把特徵按照被選擇的次數從高到低列出來
feature_selection_df = pd.DataFrame({'Feature':feature_name, 
                                     'Chi-2':chi_support, 
                                     'RFE':rfe_support, 
                                     'Logistics':embeded_lr_support,
                                     'Random Forest':embeded_rf_support})
# 每個特徵在不同方式中被選擇的次數總和
feature_selection_df['Total'] = np.sum(feature_selection_df, axis=1)
# 按照次數大小,顯示前50個
feature_selection_df = feature_selection_df.sort_values(['Total','Feature'] , ascending=False)
feature_selection_df.index = range(1, len(feature_selection_df)+1)
feature_selection_df.head(50)
Feature Chi-2 RFE Logistics Random Forest Total
1 REGION_RATING_CLIENT_W_CITY True True True True 4
2 ORGANIZATION_TYPE_Self-employed True True True True 4
3 ORGANIZATION_TYPE_Construction True True True True 4
4 ORGANIZATION_TYPE_Business Entity Type 3 True True True True 4
5 FLAG_OWN_CAR_Y True True True True 4
6 EXT_SOURCE_3 True True True True 4
7 EXT_SOURCE_2 True True True True 4
8 EXT_SOURCE_1 True True True True 4
9 DAYS_ID_PUBLISH True True True True 4
10 CODE_GENDER_M True True True True 4
11 WALLSMATERIAL_MODE_Monolithic True True True False 3
12 ORGANIZATION_TYPE_Transport: type 3 True True True False 3
13 ORGANIZATION_TYPE_Police True True True False 3
14 ORGANIZATION_TYPE_Military True True True False 3
15 ORGANIZATION_TYPE_Industry: type 9 True True True False 3
16 OCCUPATION_TYPE_Low-skill Laborers True True True False 3
17 OCCUPATION_TYPE_Laborers True False True True 3
18 OCCUPATION_TYPE_High skill tech staff True True True False 3
19 OCCUPATION_TYPE_Drivers True False True True 3
20 NONLIVINGAPARTMENTS_MODE False True True True 3
21 NAME_FAMILY_STATUS_Married True False True True 3
22 NAME_EDUCATION_TYPE_Higher education True False True True 3
23 LIVINGAREA_MEDI False True True True 3
24 FLOORSMIN_MEDI False True True True 3
25 FLOORSMAX_MODE False True True True 3
26 FLAG_WORK_PHONE True False True True 3
27 FLAG_DOCUMENT_3 True False True True 3
28 ENTRANCES_AVG False True True True 3
29 DEF_60_CNT_SOCIAL_CIRCLE False True True True 3
30 DEF_30_CNT_SOCIAL_CIRCLE False True True True 3
31 BASEMENTAREA_AVG False True True True 3
32 APARTMENTS_MEDI False True True True 3
33 AMT_REQ_CREDIT_BUREAU_MON False True True True 3
34 AMT_GOODS_PRICE False True True True 3
35 AMT_CREDIT False True True True 3
36 AMT_ANNUITY False True True True 3
37 YEARS_BEGINEXPLUATATION_MODE False False True True 2
38 YEARS_BEGINEXPLUATATION_MEDI False False True True 2
39 WEEKDAY_APPR_PROCESS_START_TUESDAY False False True True 2
40 WALLSMATERIAL_MODE_Wooden False True True False 2
41 REG_CITY_NOT_WORK_CITY True False False True 2
42 REG_CITY_NOT_LIVE_CITY True False False True 2
43 REGION_RATING_CLIENT True False False True 2
44 ORGANIZATION_TYPE_Transport: type 1 False True True False 2
45 ORGANIZATION_TYPE_Realtor False True True False 2
46 ORGANIZATION_TYPE_Other False False True True 2
47 ORGANIZATION_TYPE_Insurance False True True False 2
48 ORGANIZATION_TYPE_Industry: type 3 False True True False 2
49 ORGANIZATION_TYPE_Industry: type 2 False True True False 2
50 ORGANIZATION_TYPE_Industry: type 12 False True True False 2
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章