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)
輸出結果:
原始數據: (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)
輸出結果:
原始數據: (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)
輸出結果:
原始數據: (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)
輸出結果:
原始數據: (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)