<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          特征選擇:11 種特征選擇策略總結(jié)!

          共 10298字,需瀏覽 21分鐘

           ·

          2022-06-17 21:09

          來源:DeepHub IMBA,編輯:數(shù)據(jù)派THU

          本文約4800,建議閱讀10+分鐘

          本文與你分享可應(yīng)用于特征選擇的各種技術(shù)的有用指南。


          太多的特征會(huì)增加模型的復(fù)雜性和過擬合,而太少的特征會(huì)導(dǎo)致模型的擬合不足。將模型優(yōu)化為足夠復(fù)雜以使其性能可推廣,但又足夠簡(jiǎn)單易于訓(xùn)練、維護(hù)和解釋是特征選擇的主要工作。

          “特征選擇”意味著可以保留一些特征并放棄其他一些特征。本文的目的是概述一些特征選擇策略:

          1. 刪除未使用的列
          2. 刪除具有缺失值的列
          3. 不相關(guān)的特征
          4. 低方差特征
          5. 多重共線性
          6. 特征系數(shù)
          7. p 值
          8. 方差膨脹因子 (VIF)
          9. 基于特征重要性的特征選擇
          10. 使用 sci-kit learn 進(jìn)行自動(dòng)特征選擇
          11. 主成分分析 (PCA)

          該演示的數(shù)據(jù)集在 MIT 許可下發(fā)布,來自 PyCaret——一個(gè)開源的低代碼機(jī)器學(xué)習(xí)庫(kù)。

          數(shù)據(jù)集相當(dāng)干凈,但我做了一些預(yù)處理。請(qǐng)注意,我使用此數(shù)據(jù)集來演示不同的特征選擇策略如何工作,而不是構(gòu)建最終模型,因此模型性能無關(guān)緊要。

          首先加載數(shù)據(jù)集:

          import pandas as pddata = 'https://raw.githubusercontent.com/pycaret/pycaret/master/datasets/automobile.csv'df = pd.read_csv(data)
          df.sample(5)

          該數(shù)據(jù)集包含 202 行和 26 列——每行代表一個(gè)汽車實(shí)例,每列代表其特征和相應(yīng)的價(jià)格。這些列包括:

          df.columns
          >> Index(['symboling', 'normalized-losses', 'make', 'fuel-type', 'aspiration', 'num-of-doors', 'body-style', 'drive-wheels', 'engine-location','wheel-base', 'length', 'width', 'height', 'curb-weight', 'engine-type', 'num-of-cylinders', 'engine-size', 'fuel-system', 'bore', 'stroke', 'compression-ratio', 'horsepower', 'peak-rpm', 'city-mpg', 'highway-mpg', 'price'], dtype='object')


          現(xiàn)在讓我們深入研究特征選擇的 11 種策略。


          1.刪除未使用的列


          當(dāng)然,最簡(jiǎn)單的策略是你的直覺。雖然是直覺,但有時(shí)很有用的,某些列在最終模型中不會(huì)以任何形式使用(例如“ID”、“FirstName”、“LastName”等列)。如果您知道某個(gè)特定列將不會(huì)被使用,請(qǐng)隨時(shí)將其刪除。在我們的數(shù)據(jù)中,沒有一列有這樣的問題所以,我在此步驟中不刪除任何列。

          2.刪除具有缺失值的列


          缺失值在機(jī)器學(xué)習(xí)中是不可接受的,因此我們會(huì)采用不同的策略來清理缺失數(shù)據(jù)(例如插補(bǔ))。但是如果列中缺少大量數(shù)據(jù),那么完全刪除它是非常好的方法。

          # total null values per columndf.isnull().sum()
          >>symboling 0normalized-losses 35make 0fuel-type 0aspiration 0num-of-doors 2body-style 0drive-wheels 0engine-location 0wheel-base 0length 0width 0height 0curb-weight 0engine-type 0num-of-cylinders 0engine-size 0fuel-system 0bore 0stroke 0compression-ratio 0horsepower 0peak-rpm 0city-mpg 0highway-mpg 0price 0dtype: int64

          3.不相關(guān)的特征


          無論算法是回歸(預(yù)測(cè)數(shù)字)還是分類(預(yù)測(cè)類別),特征都必須與目標(biāo)相關(guān)。如果一個(gè)特征沒有表現(xiàn)出相關(guān)性,它就是一個(gè)主要的消除目標(biāo)。可以分別測(cè)試數(shù)值和分類特征的相關(guān)性。

          數(shù)值變量

          # correlation between target and features(df.corr().loc['price'].plot(kind='barh', figsize=(4,10)))

          在此示例中,peak-rpm, compression-ratio, stroke, bore, height , symboling 等特征與價(jià)格幾乎沒有相關(guān)性,因此我們可以刪除它們。

          可以手動(dòng)刪除列,但我更喜歡使用相關(guān)閾值(在本例中為 0.2)以編程方式進(jìn)行:

          # drop uncorrelated numeric features (threshold <0.2)corr = abs(df.corr().loc['price'])corr = corr[corr<0.2]cols_to_drop = corr.index.to_list()df = df.drop(cols_to_drop, axis=1)

          分類變量

          可以使用箱線圖查找目標(biāo)和分類特征之間的相關(guān)性:

          import seaborn as sns
          sns.boxplot(y = 'price', x = 'fuel-type', data=df)

          柴油車的中位價(jià)高于汽油車。這意味著這個(gè)分類變量可以解釋汽車價(jià)格,所以應(yīng)放棄它。可以像這樣單獨(dú)檢查每個(gè)分類列。

          4.低方差特征


          檢查一下我們的特征的差異:

          import numpy as np
          # variance of numeric features(df.select_dtypes(include=np.number).var().astype('str'))

          這里的“bore”具有極低的方差,雖然這是刪除的候選者。在這個(gè)特殊的例子中,我不愿意刪除它,因?yàn)樗闹翟?.54和3.94之間,因此方差很低:
          df['bore'].describe()


          5.多重共線性


          當(dāng)任何兩個(gè)特征之間存在相關(guān)性時(shí),就會(huì)出現(xiàn)多重共線性。在機(jī)器學(xué)習(xí)中,期望每個(gè)特征都應(yīng)該獨(dú)立于其他特征,即它們之間沒有共線性。高馬力車輛往往具有高發(fā)動(dòng)機(jī)尺寸。所以你可能想消除其中一個(gè),讓另一個(gè)決定目標(biāo)變量——價(jià)格。

          我們可以分別測(cè)試數(shù)字和分類特征的多重共線性:

          數(shù)值變量

          Heatmap 是檢查和尋找相關(guān)特征的最簡(jiǎn)單方法。

          import matplotlib.pyplot as plt
          sns.set(rc={'figure.figsize':(16,10)})sns.heatmap(df.corr(), annot=True, linewidths=.5, center=0, cbar=False, cmap="PiYG")plt.show()

          大多數(shù)特征在某種程度上相互關(guān)聯(lián),但有些特征具有非常高的相關(guān)性,例如長(zhǎng)度與軸距以及發(fā)動(dòng)機(jī)尺寸與馬力。

          可以根據(jù)相關(guān)閾值手動(dòng)或以編程方式刪除這些功能。我將手動(dòng)刪除具有 0.80 共線性閾值的特征。

          # drop correlated featuresdf = df.drop(['length', 'width', 'curb-weight', 'engine-size', 'city-mpg'], axis=1)


          還可以使用稱為方差膨脹因子 (VIF) 的方法來確定多重共線性并根據(jù)高 VIF 值刪除特征。我稍后會(huì)展示這個(gè)例子。


          分類變量

          與數(shù)值特征類似,也可以檢查分類變量之間的共線性。諸如獨(dú)立性卡方檢驗(yàn)之類的統(tǒng)計(jì)檢驗(yàn)非常適合它。

          讓我們檢查一下數(shù)據(jù)集中的兩個(gè)分類列——燃料類型和車身風(fēng)格——是獨(dú)立的還是相關(guān)的。

          df_cat = df[['fuel-type', 'body-style']]df_cat.sample(5)

          然后我們將在每一列中創(chuàng)建一個(gè)類別的交叉表/列聯(lián)表。

          crosstab = pd.crosstab(df_cat['fuel-type'], df_cat['body-style'])crosstab

          最后,我們將在交叉表上運(yùn)行卡方檢驗(yàn),這將告訴我們這兩個(gè)特征是否獨(dú)立。
          from scipy.stats import chi2_contingency
          chi2_contingency(crosstab)

          輸出依次是卡方值、p 值、自由度和預(yù)期頻率數(shù)組。

          p 值 <0.05,因此我們可以拒絕特征之間沒有關(guān)聯(lián)的原假設(shè),即兩個(gè)特征之間存在統(tǒng)計(jì)上顯著的關(guān)系。

          由于這兩個(gè)特征之間存在關(guān)聯(lián),我們可以選擇刪除其中一個(gè)。

          到目前為止,我已經(jīng)展示了在實(shí)現(xiàn)模型之前應(yīng)用的特征選擇策略。這些策略在第一輪特征選擇以建立初始模型時(shí)很有用。但是一旦構(gòu)建了模型,就可以獲得有關(guān)模型性能中每個(gè)特征的適應(yīng)度的更多信息。根據(jù)這些新信息,可以進(jìn)一步確定要保留哪些功能。

          下面我們使用最簡(jiǎn)單的線性模型展示其中的一些方法。

          # drop columns with missing valuesdf = df.dropna()from sklearn.model_selection import train_test_split# get dummies for categorical featuresdf = pd.get_dummies(df, drop_first=True)# X featuresX = df.drop('price', axis=1)# y targety = df['price']# split data into training and testing setX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
          from sklearn.linear_model import LinearRegression# scalingfrom sklearn.preprocessing import StandardScalerscaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.fit_transform(X_test)# convert back to dataframeX_train = pd.DataFrame(X_train, columns = X.columns.to_list())X_test = pd.DataFrame(X_test, columns = X.columns.to_list())# instantiate modelmodel = LinearRegression()# fitmodel.fit(X_train, y_train)

          現(xiàn)在我們已經(jīng)擬合了模型,讓我們進(jìn)行另一輪特征選擇。

          6.特征系數(shù)


          如果正在運(yùn)行回歸任務(wù),則特征適應(yīng)度的一個(gè)關(guān)鍵指標(biāo)是回歸系數(shù)(所謂的 beta 系數(shù)),它顯示了模型中特征的相對(duì)貢獻(xiàn)。有了這些信息,可以刪除貢獻(xiàn)很小或沒有貢獻(xiàn)的功能。

          # feature coefficientscoeffs = model.coef_
          # visualizing coefficientsindex = X_train.columns.tolist()
          (pd.DataFrame(coeffs, index = index, columns = ['coeff']).sort_values(by = 'coeff').plot(kind='barh', figsize=(4,10)))

          某些特征beta 系數(shù)很小,對(duì)汽車價(jià)格的預(yù)測(cè)貢獻(xiàn)不大。可以過濾掉這些特征:

          # filter variables near zero coefficient valuetemp = pd.DataFrame(coeffs, index = index, columns = ['coeff']).sort_values(by = 'coeff')temp = temp[(temp['coeff']>1) | (temp['coeff']< -1)]
          # drop those featurescols_coeff = temp.index.to_list()X_train = X_train[cols_coeff]X_test = X_test[cols_coeff]

          7.p 值


          在回歸中,p 值告訴我們預(yù)測(cè)變量和目標(biāo)之間的關(guān)系是否具有統(tǒng)計(jì)顯著性。statsmodels 庫(kù)提供了帶有特征系數(shù)和相關(guān) p 值的回歸輸出的函數(shù)。

          如果某些特征不顯著,可以將它們一個(gè)一個(gè)移除,然后每次重新運(yùn)行模型,直到找到一組具有顯著 p 值的特征,并通過更高的調(diào)整 R2 提高性能。

          import statsmodels.api as smols = sm.OLS(y, X).fit()print(ols.summary())


          8.方差膨脹因子 (VIF)


          方差膨脹因子 (VIF) 是衡量多重共線性的另一種方法。它被測(cè)量為整體模型方差與每個(gè)獨(dú)立特征的方差的比率。一個(gè)特征的高 VIF 表明它與一個(gè)或多個(gè)其他特征相關(guān)。根據(jù)經(jīng)驗(yàn):

          • VIF = 1 表示無相關(guān)性
          • VIF = 1-5 中等相關(guān)性
          • VIF >5 高相關(guān)

          VIF 是一種消除多重共線性特征的有用技術(shù)。對(duì)于我們的演示,將所有 VIF 高于10的刪除。

          from statsmodels.stats.outliers_influence import variance_inflation_factor
          # calculate VIFvif = pd.Series([variance_inflation_factor(X.values, i) for i in range(X.shape[1])], index=X.columns)
          # display VIFs in a tableindex = X_train.columns.tolist()vif_df = pd.DataFrame(vif, index = index, columns = ['vif']).sort_values(by = 'vif', ascending=False)vif_df[vif_df['vif']<10]

          9.基于特征重要性選擇


          決策樹/隨機(jī)森林使用一個(gè)特征來分割數(shù)據(jù),該特征最大程度地減少了雜質(zhì)(以基尼系數(shù)雜質(zhì)或信息增益衡量)。找到最佳特征是算法如何在分類任務(wù)中工作的關(guān)鍵部分。我們可以通過 feature_importances_ 屬性訪問最好的特征。

          讓我們?cè)谖覀兊臄?shù)據(jù)集上實(shí)現(xiàn)一個(gè)隨機(jī)森林模型并過濾一些特征。

          from sklearn.ensemble import RandomForestClassifier
          # instantiate modelmodel = RandomForestClassifier(n_estimators=200, random_state=0)# fit modelmodel.fit(X,y)

          現(xiàn)在讓我們看看特征重要性:

          # feature importanceimportances = model.feature_importances_
          # visualizationcols = X.columns(pd.DataFrame(importances, cols, columns = ['importance']).sort_values(by='importance', ascending=True).plot(kind='barh', figsize=(4,10)))

          上面的輸出顯示了每個(gè)特征在減少每個(gè)節(jié)點(diǎn)/拆分處的重要性。

          由于隨機(jī)森林分類器有很多估計(jì)量(例如上面例子中的 200 棵決策樹),可以用置信區(qū)間計(jì)算相對(duì)重要性的估計(jì)值。

          # calculate standard deviation of feature importancesstd = np.std([i.feature_importances_ for i in model.estimators_], axis=0)
          # visualizationfeat_with_importance = pd.Series(importances, X.columns)fig, ax = plt.subplots(figsize=(12,5))feat_with_importance.plot.bar(yerr=std, ax=ax)ax.set_title("Feature importances")ax.set_ylabel("Mean decrease in impurity")

          現(xiàn)在我們知道了每個(gè)特征的重要性,可以手動(dòng)(或以編程方式)確定保留哪些特征以及刪除哪些特征。

          10.使用 Scikit Learn 自動(dòng)選擇特征


          sklearn 庫(kù)中有一個(gè)完整的模塊,只需幾行代碼即可處理特征選擇。

          sklearn 中有許多自動(dòng)化流程,但這里我只展示一些:

          # import modulesfrom sklearn.feature_selection import (SelectKBest, chi2, SelectPercentile, SelectFromModel, SequentialFeatureSelector, SequentialFeatureSelector)


          基于卡方的技術(shù)


          基于卡方的技術(shù)根據(jù)一些預(yù)定義的分?jǐn)?shù)選擇特定數(shù)量的用戶定義特征 (k)。這些分?jǐn)?shù)是通過計(jì)算 X(獨(dú)立)和 y(因)變量之間的卡方統(tǒng)計(jì)量來確定的。在 sklearn 中,需要做的就是確定要保留多少特征。如果想保留 10 個(gè)功能,實(shí)現(xiàn)將如下所示:

          # select K best featuresX_best = SelectKBest(chi2, k=10).fit_transform(X,y)
          # number of best featuresX_best.shape[1]
          >> 10

          如果有大量特征,可以指定要保留的特征百分比。假設(shè)我們想要保留 75% 的特征并丟棄剩余的 25%:

          # keep 75% top featuresX_top = SelectPercentile(chi2, percentile = 75).fit_transform(X,y)
          # number of best featuresX_top.shape[1]
          >> 36

          正則化

          正則化減少了過擬合。如果你有太多的特征,正則化控制它們的效果,或者通過縮小特征系數(shù)(稱為 L2 正則化)或?qū)⒁恍┨卣飨禂?shù)設(shè)置為零(稱為 L1 正則化)。

          一些模型具有內(nèi)置的 L1/L2 正則化作為超參數(shù)來懲罰特征。可以使用轉(zhuǎn)換器 SelectFromModel 消除這些功能。

          讓我們實(shí)現(xiàn)一個(gè)帶有懲罰 = 'l1' 的 LinearSVC 算法。然后使用 SelectFromModel 刪除一些功能。

          # implement algorithmfrom sklearn.svm import LinearSVCmodel = LinearSVC(penalty= 'l1', C = 0.002, dual=False)model.fit(X,y)# select features using the meta transformerselector = SelectFromModel(estimator = model, prefit=True)
          X_new = selector.transform(X)X_new.shape[1]
          >> 2
          # names of selected featuresfeature_names = np.array(X.columns)feature_names[selector.get_support()]
          >> array(['wheel-base', 'horsepower'], dtype=object)

          序貫法

          序貫法是一種經(jīng)典的統(tǒng)計(jì)技術(shù)。在這種情況下一次添加/刪除一個(gè)功能并檢查模型性能,直到它針對(duì)需求進(jìn)行優(yōu)化。

          序貫法有兩種變體。前向選擇技術(shù)從 0 特征開始,然后添加一個(gè)最大程度地減少錯(cuò)誤的特征;然后添加另一個(gè)特征,依此類推。

          向后選擇在相反的方向上起作用。模型從包含的所有特征開始并計(jì)算誤差;然后它消除了一個(gè)可以進(jìn)一步減少誤差的特征。重復(fù)該過程,直到保留所需數(shù)量的特征。

          # instantiate modelmodel = RandomForestClassifier(n_estimators=100, random_state=0)
          # select featuresselector = SequentialFeatureSelector(estimator=model, n_features_to_select=10, direction='backward', cv=2)selector.fit_transform(X,y)
          # check names of features selectedfeature_names = np.array(X.columns)feature_names[selector.get_support()]
          >> array(['bore', 'make_mitsubishi', 'make_nissan', 'make_saab', 'aspiration_turbo', 'num-of-doors_two', 'body style_hatchback', 'engine-type_ohc', 'num-of-cylinders_twelve', 'fuel-system_spdi'], dtype=object)


          11.主成分分析 (PCA)


          PCA的主要目的是降低高維特征空間的維數(shù)。原始特征被重新投影到新的維度(即主成分)。最終目標(biāo)是找到最能解釋數(shù)據(jù)方差的特征數(shù)量。

          # import PCA modulefrom sklearn.decomposition import PCA# scaling dataX_scaled = scaler.fit_transform(X)# fit PCA to datapca = PCA()pca.fit(X_scaled)evr = pca.explained_variance_ratio_
          # visualizing the variance explained by each principal componentsplt.figure(figsize=(12, 5))plt.plot(range(0, len(evr)), evr.cumsum(), marker="o", linestyle="--")plt.xlabel("Number of components")plt.ylabel("Cumulative explained variance")

          20 個(gè)主成分解釋了超過 80% 的方差,因此可以將模型擬合到這 20 個(gè)成分(特征)。可以預(yù)先確定方差閾值并選擇所需的主成分?jǐn)?shù)量。

          總結(jié)


          這是對(duì)可應(yīng)用于特征選擇的各種技術(shù)的有用指南。在擬合模型之前應(yīng)用了一些技術(shù),例如刪除具有缺失值的列、不相關(guān)的列、具有多重共線性的列以及使用 PCA 進(jìn)行降維,而在基本模型實(shí)現(xiàn)之后應(yīng)用其他技術(shù),例如特征系數(shù)、p 值、 VIF 等。雖然不會(huì)在一個(gè)項(xiàng)目中完全使用所有策略,這些策略都是我們進(jìn)行測(cè)試的方向。

          本文代碼:https://github.com/mabalam/feature_selection
          作者:Mahbubul Alam


          相關(guān)閱讀:


          瀏覽 133
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产真实乱婬A片三区高 | 欧美人与禽性XXXXX杂性 欧美日韩一区二区三区,麻豆 | 国产精品熟妇一区二区三区四区 | 亚洲淫秽视频 | 老少妇av |