主要參考鏈接爲:參考連接,裏面有詳細的特徵選擇內容。html
特徵選擇
是特徵工程
裏的一個重要問題,其目標是尋找最優特徵子集。特徵選擇能剔除不相關(irrelevant)或冗餘(redundant )的特徵,從而達到減小特徵個數,提升模型精確度,減小運行時間的目的。另外一方面,選取出真正相關的特徵簡化模型,協助理解數據產生的過程。而且常能聽到「數據和特徵決定了機器學習的上限,而模型和算法只是逼近這個上限而已」,因而可知其重要性。可是它幾乎不多出現於機器學習書本里面的某一章。然而在機器學習方面的成功很大程度上在於若是使用特徵工程。算法
之因此要考慮特徵選擇,是由於機器學習常常面臨過擬合的問題。 過擬合的表現是模型參數太貼合訓練集數據,模型在訓練集上效果很好而在測試集上表現很差,也就是在高方差。簡言之模型的泛化能力差。過擬合的緣由是模型對於訓練集數據來講太複雜,要解決過擬合問題,通常考慮以下方法:數組
其中第1條通常是很難作到的,通常主要採用第2和第4點app
特徵選擇的通常過程:dom
可是, 當特徵數量很大的時候, 這個搜索空間會很大,如何找最優特徵仍是須要一些經驗結論。機器學習
根據特徵選擇的形式,可分爲三大類:ide
發散性
或相關性
對各個特徵進行評分,設定閾值或者待選擇特徵的個數進行篩選
基本想法是:分別對每一個特徵 x_i ,計算 x_i 相對於類別標籤 y 的信息量 S(i) ,獲得 n 個結果。而後將 n 個 S(i) 按照從大到小排序,輸出前 k 個特徵。顯然,這樣複雜度大大下降。那麼關鍵的問題就是使用什麼樣的方法來度量 S(i) ,咱們的目標是選取與 y 關聯最密切的一些 特徵x_i 。函數
sklearn使用到的內容主要爲:學習
from sklearn.feature_selection import SelectKBest測試
score_func:callable,函數取兩個數組X和y,返回一對數組(scores, pvalues)或一個分數的數組。默認函數爲f_classif,計算F分數,默認函數只適用於分類函數。
k:int or "all", optional, default=10。所選擇的topK個特徵。「all」選項則繞過選擇,用於參數搜索。
scores_ : array-like, shape=(n_features,),特徵的得分
pvalues_ : array-like, shape=(n_features,),特徵得分的p_value值,若是score_func只返回分數,則返回None。
fit(X,y),在(X,y)上運行記分函數並獲得適當的特徵。
fit_transform(X[, y]),擬合數據,而後轉換數據。
get_params([deep]),得到此估計器的參數。
get_support([indices]),獲取所選特徵的掩碼或整數索引。
inverse_transform(X),反向變換操做。
set_params(**params),設置估計器的參數。
transform(X),將X還原爲所選特徵
皮爾森相關係數是一種最簡單的,能幫助理解特徵和響應變量之間關係的方法,衡量的是變量之間的線性相關性,結果的取值區間爲[-1,1] , -1 表示徹底的負相關(這個變量降低,那個就會上升), +1 表示徹底的正相關, 0 表示沒有線性相關性。Pearson Correlation速度快、易於計算,常常在拿到數據(通過清洗和特徵提取以後的)以後第一時間就執行。Scipy的pearsonr方法可以同時計算相關係數和p-value。
方法一:
pandas中,df.corr()能夠直接計算相關係數
方法二:
import numpy as np from scipy.stats import pearsonr np.random.seed(0) size = 300 x = np.random.normal(0, 1, size) print("Lower noise:", pearsonr(x, x + np.random.normal(0, 1, size))) print("Higher noise:", pearsonr(x, x + np.random.normal(0, 10, size))) from sklearn.feature_selection import SelectKBest from sklearn import datasets iris=datasets.load_iris() model=SelectKBest(lambda X,Y:np.array(list(map(lambda x:pearsonr(x,Y),X.T))).T[0],k=2) #構建相關係數模型 model.fit_transform(iris.data, iris.target) #對模型將數據傳入 print('相關係數:',model.scores_) #返回全部變量X與Y的相關係數值 print('P值:',model.pvalues_) #返回全部變量X的P值 print('所選變量的數值爲:\n',model.fit_transform(iris.data, iris.target)) #打印傳入數據的話會返回k=2所選擇的兩個變量的數據的值
經典的卡方檢驗是檢驗定性自變量對定性因變量的相關性。假設自變量有N種取值,因變量有M種取值,考慮自變量等於i且因變量等於j的樣本頻數的觀察值與指望的差距,構建統計量:
這個統計量的含義簡而言之就是自變量對因變量的相關性。用feature_selection庫的SelectKBest類結合卡方檢驗來選擇特徵的代碼以下:
import numpy as npfrom sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 from sklearn import datasets iris=datasets.load_iris() model=SelectKBest(chi2,k=2) #構建相關係數模型 model.fit_transform(iris.data, iris.target) #對模型將數據傳入 print('卡方係數:',model.scores_) #返回全部變量X與Y的相關係數值 print('P值:',model.pvalues_) #返回全部變量X的P值 print('所選變量的數值爲:\n',model.fit_transform(iris.data, iris.target)) #打印傳入數據的話會返回k=2所選擇的兩個變量的數據的值
經典的互信息也是評價定性自變量對定性因變量的相關性的,互信息計算公式以下:
爲了處理定量數據,最大信息係數法被提出,使用feature_selection庫的SelectKBest類結合最大信息係數法來選擇特徵的代碼以下:
import numpy as np from sklearn.feature_selection import SelectKBest from minepy import MINE from sklearn import datasets iris=datasets.load_iris() def mic(x, y): m = MINE() m.compute_score(x, y) return (m.mic(), 0.5) model=SelectKBest(lambda X,Y:np.array(list(map(lambda x:mic(x,Y),X.T))).T[0],,k=2) #構建互信息數模型 model.fit_transform(iris.data, iris.target) #對模型將數據傳入 print('互信息係數:',model.scores_) #返回全部變量X與Y的相關係數值 print('P值:',model.pvalues_) #返回全部變量X的P值 print('所選變量的數值爲:\n',model.fit_transform(iris.data, iris.target)) #打印傳入數據的話會返回k=2所選擇的兩個變量的數據的值
遞歸消除特徵法使用一個基模型來進行多輪訓練,每輪訓練後,消除若干權值係數的特徵,再基於新的特徵集進行下一輪訓練。使用feature_selection庫的RFE類來選擇特徵的代碼以下:
import numpy as np from sklearn.feature_selection import RFE,RFECV from sklearn.linear_model import LogisticRegression from sklearn import datasets iris=datasets.load_iris() # FECV() #利用交叉驗證來選擇,不過這裏的交叉驗證的數據集切割對象再也不是 行數據(樣本),而是列數據(特徵),可是計算量會大,cv默認是3 model=RFE(estimator=LogisticRegression(), n_features_to_select=2) #構建邏輯迴歸的遞歸消除模型 model.fit_transform(iris.data, iris.target) #傳入數據 print(model.classes_) #返回遞歸消除獲得的變量
使用帶懲罰項的基模型,除了篩選出特徵外,同時也進行了降維。使用feature_selection庫的SelectFromModel類結合帶L1懲罰項的邏輯迴歸模型,來選擇特徵的代碼以下:
import numpy as np from sklearn.feature_selection import SelectFromModel from sklearn.linear_model import LogisticRegression from sklearn import datasets iris=datasets.load_iris() #帶L1懲罰項的邏輯迴歸做爲基模型的特徵選擇 model=SelectFromModel(LogisticRegression(penalty="l1", C=0.1)) model.fit_transform(iris.data, iris.target) #傳入數據 print(model.fit_transform(iris.data, iris.target)) #返回模型選擇的變量的數據內容
L2的特徵選擇請參考鏈接:http://www.javashuo.com/article/p-ygadyblk-gd.html
樹模型中GBDT也可用來做爲基模型進行特徵選擇,使用feature_selection庫的SelectFromModel類結合GBDT模型,來選擇特徵的代碼以下:
import numpy as np from sklearn.feature_selection import SelectFromModel from sklearn.ensemble import GradientBoostingClassifier from sklearn import datasets iris=datasets.load_iris() #帶L1懲罰項的邏輯迴歸做爲基模型的特徵選擇 model=SelectFromModel(GradientBoostingClassifier()) model.fit_transform(iris.data, iris.target) #傳入數據 print(model.fit_transform(iris.data, iris.target)) #返回模型選擇的變量的數據內容