機器學習:特徵選擇

1.特徵選擇算法

         特徵選擇是降維的一種方法,即選擇對預測結果相關度高的特徵或者消除類似度高的特徵,以提升估計函數的準確率或者提升多維度數據集上的性能。ide

 

2.刪除低方差特徵函數

        1)思路:設置一個閥值,對每一個特徵求方差,若是所求方差低於這個閥值,則刪除此特徵。默認狀況下會刪除0方差。性能

        2)核心函數測試

              sklearn.feature_selection.VarianceThresholdspa

       3)主要參數:翻譯

              threshold :設置的閥值3d

             補充說明:code

             官網給出的是一個布爾值的數據集,閥值的表示方式爲下面的公式:orm

             

             示例寫法:sel = VarianceThreshold(threshold=(0.8 * (1 - 0.8)))

             通過測試,非布爾值的數據集也適用,而且直接寫成:threshold=0.16 也是能夠的。

             對於二維矩陣,求的是每列的方差,而後和閥值比較。

        4)示例

             爲了更好的說明用刪除低方差的方式進行特徵選擇後,新的數據集不會影響預測結果或者不會形成太大的影響,這裏選擇一個官方提供的數據集進行對比。這個數據集是關於花朵類型判斷的:包含150個樣本數據,每一個樣本數據包含4個特徵,這些樣本數據屬於3類,每類50個樣本。

       使用決策樹進行分類預測。

        詳細代碼以下:

from sklearn.datasets import load_iris
from sklearn import tree
from sklearn.feature_selection import VarianceThreshold
import numpy as np

##加載數據
iris = load_iris()
##設置篩選閥值
sel = VarianceThreshold(threshold=(.7 * (1 - .7)))

##設置訓練集和標籤集
X, y = iris.data, iris.target
print("原始數據:")
print(X.shape) #(150, 4)

#篩選數據
X_new = sel.fit_transform(X)
print("新數據集:")
print(X_new.shape) #(150, 3)

##設置分類函數:決策樹
clf = tree.DecisionTreeClassifier()
##訓練數據
clf.fit(X, y)
##預測數據
y_pred = clf.predict(X)

##使用選擇特徵後的數據進行訓練
clf.fit(X_new, y)
##在新數據集上進行預測
y_pred1 = clf.predict(X_new)


##原始數據的預測結果和真實結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred[i] == y[i]:
        cnt += 1
print("原始數據的預測結果和真實結果相同的個數:")
print(cnt)

##新數據集和真實結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred1[i]== y[i]:
        cnt += 1
print("新數據集的預測結果和真實結果相同的個數:")
print(cnt)

##原始數據的預測結果和新數據的預測結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred[i] == y_pred1[i]:
        cnt += 1
print("原始據集的預測結果和新數據集預測結果相同的個數:")
print(cnt)
View Code

        輸出結果:

原始數據:
(150, 4)
新數據集:
(150, 3)
原始數據的預測結果和真實結果相同的個數:
150
新數據集的預測結果和真實結果相同的個數:
150
原始據集的預測結果和新數據集預測結果相同的個數:
150

   從結果能夠看出,數據從150×4的矩陣變成了150×3的矩陣,可是徹底沒有對預測結果形成任何影響。

 

3.單變量特徵選擇

        (下面的翻譯可能不是很準確)

        1)思路:對每一個特徵作基於統計的檢驗,從而選擇出最佳特徵。

        2)可用的函數

                   SelectPercentile:根據最高分數的百分位數選擇特徵。
                   SelectKBest:根據k最高分選擇特徵。
                   SelectFpr:基於假陽性率測試選擇特徵。
                   SelectFdr:根據估計的虛假髮現率選擇特徵。
                   SelectFwe:根據家庭錯誤率選擇功能(這個翻譯感受很怪:based on family-wise error rate)
                   GenericUnivariateSelect:具備可配置模式的單變量特徵選擇器。

         3)可用的統計方法(上面函數的參數):                 

                   f_classif:用於分類任務的標籤/特徵之間方差分析的F值。
                   mutual_info_classif:離散目標的相互信息。
                  chi2:用於分類任務的非負性特徵的卡方統計。
                  f_regression:用於迴歸任務的標籤/特徵之間的F值。
                  mutual_info_regression:連續目標的相互信息。

         4)示例

               依然使用上面的關於花朵的數據集和決策樹分類方法。

               詳細代碼以下:

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
from sklearn import tree
import numpy as np

##加載數據
iris = load_iris()
##設置訓練集和標籤集
X, y = iris.data, iris.target
print("原始數據:")
print(X.shape) #(150, 4)

##選擇關鍵特徵
X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
print("新數據集:")
print(X_new.shape) #(150, 2)

##設置分類函數:決策樹
clf = tree.DecisionTreeClassifier()
##訓練數據
clf.fit(X, y)
##預測數據
y_pred = clf.predict(X)

##使用選擇特徵後的數據進行訓練
clf.fit(X_new, y)
##在新數據集上進行預測
y_pred1 = clf.predict(X_new)


##原始數據的預測結果和真實結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred[i] == y[i]:
        cnt += 1
print("原始數據的預測結果和真實結果相同的個數:")
print(cnt)

##新數據集和真實結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred1[i]== y[i]:
        cnt += 1
print("新數據集的預測結果和真實結果相同的個數:")
print(cnt)

##原始數據的預測結果和新數據的預測結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred[i] == y_pred1[i]:
        cnt += 1
print("原始據集的預測結果和新數據集預測結果相同的個數:")
print(cnt)
View Code

               輸出結果:

原始數據:
(150, 4)
新數據集:
(150, 2)
原始數據的預測結果和真實結果相同的個數:
150
新數據集的預測結果和真實結果相同的個數:
149
原始據集的預測結果和新數據集預測結果相同的個數:
149

               從結果能夠看出,原始的數據集從150×4變成了150×2,可是預測的結果只有一個偏差。

 

4.使用SelectFromModel進行特徵選擇

         1)思路:SelectFromModel是一種元變壓器,可用於任何在擬合後有coef_或feature_importances_屬性的擬合函數。若是相應的coef_或feature_importances_值低於提供的threshold參數(閥值),則認爲這些特徵是是不重要的而且刪除。除了數值上指定閾值外,還有內置的啓發式算法,用於使用字符串參數來查找閾值。可用的啓發式算法是「平均值」,「中位數」和浮點倍數,如「0.1 *mean」。

        2)由上面SelectFromModel的思路可知,首先須要進行一次擬合,而後才經過SelectFromModel選擇特徵。根據第一次擬合函數的不一樣,分爲兩類:

            a)基於L1的特徵選擇

                 詳細代碼:

from sklearn.datasets import load_iris
from sklearn.svm import LinearSVC
from sklearn.feature_selection import SelectFromModel
from sklearn import tree
import numpy as np

##加載數據
iris = load_iris()
##設置訓練集和標籤集
X, y = iris.data, iris.target
print("原始數據:")
print(X.shape) #(150, 4)

##選擇關鍵特徵
lsvc = LinearSVC(C=0.01, penalty="l1", dual=False)
lsvc = lsvc.fit(X, y)
model = SelectFromModel(lsvc, prefit=True)
X_new = model.transform(X)
print("新數據集:")
print(X_new.shape) #(150, 3)

##設置分類函數:決策樹
clf = tree.DecisionTreeClassifier()
##訓練數據
clf.fit(X, y)
##預測數據
y_pred = clf.predict(X)

##使用選擇特徵後的數據進行訓練
clf.fit(X_new, y)
##在新數據集上進行預測
y_pred1 = clf.predict(X_new)


##原始數據的預測結果和真實結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred[i] == y[i]:
        cnt += 1
print("原始數據的預測結果和真實結果相同的個數:")
print(cnt)

##新數據集和真實結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred1[i]== y[i]:
        cnt += 1
print("新數據集的預測結果和真實結果相同的個數:")
print(cnt)

##原始數據的預測結果和新數據的預測結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred[i] == y_pred1[i]:
        cnt += 1
print("原始據集的預測結果和新數據集預測結果相同的個數:")
print(cnt)
View Code

                輸出結果:

原始數據:
(150, 4)
新數據集:
(150, 3)
原始數據的預測結果和真實結果相同的個數:
150
新數據集的預測結果和真實結果相同的個數:
150
原始據集的預測結果和新數據集預測結果相同的個數:
150

                從結果能夠看出,數據從150×4變成了150×3,可是預測結果沒有受影響。

            b)基於樹的特徵選擇

               詳細代碼:

from sklearn.datasets import load_iris
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.feature_selection import SelectFromModel
from sklearn import tree
import numpy as np

##加載數據
iris = load_iris()
##設置訓練集和標籤集
X, y = iris.data, iris.target
print("原始數據:")
print(X.shape) #(150, 4)

##選擇關鍵特徵
etc = ExtraTreesClassifier()
etc = etc.fit(X,y)
model = SelectFromModel(etc, prefit=True)
X_new = model.transform(X)
print("新數據集:")
print(X_new.shape) #(150, 2)

##設置分類函數:決策樹
clf = tree.DecisionTreeClassifier()
##訓練數據
clf.fit(X, y)
##預測數據
y_pred = clf.predict(X)

##使用選擇特徵後的數據進行訓練
clf.fit(X_new, y)
##在新數據集上進行預測
y_pred1 = clf.predict(X_new)


##原始數據的預測結果和真實結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred[i] == y[i]:
        cnt += 1
print("原始數據的預測結果和真實結果相同的個數:")
print(cnt)

##新數據集和真實結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred1[i]== y[i]:
        cnt += 1
print("新數據集的預測結果和真實結果相同的個數:")
print(cnt)

##原始數據的預測結果和新數據的預測結果的對比
cnt = 0
for i in range(len(y)):
    if y_pred[i] == y_pred1[i]:
        cnt += 1
print("原始據集的預測結果和新數據集預測結果相同的個數:")
print(cnt)
View Code

             輸出結果:

原始數據:
(150, 4)
新數據集:
(150, 2)
原始數據的預測結果和真實結果相同的個數:
150
新數據集的預測結果和真實結果相同的個數:
149
原始據集的預測結果和新數據集預測結果相同的個數:
149

             從結果看出,數據集從150×4變成了150×2,出現了一個偏差。

       3)上述代碼的選擇特徵,而後預測,也可簡寫成以下形式:

clf = Pipeline([
  ('feature_selection', SelectFromModel(LinearSVC(C=0.01, penalty="l1", dual=False))),
  ('classification', tree.DecisionTreeClassifier())
])
clf.fit(X, y)
相關文章
相關標籤/搜索