特征工程

文章主要參考于大神城東(部分認為有問題的地方進行了修改)

1. 特征工程是什么?

數據和特征決定了機器學習的上限,而模型和算法只是逼近了這個上線而已。特征工程的本質是一項工程活動,目的是最大限度地從原始數據中提取特征以供算法和模型使用。通過總結和歸納,人們認為特征工程包括以下方面:

本文使用python sklearn IRIS(鳶尾花)數據集來對特征處理功能進行說明,IRIS數據集包含4個特征(Sepal.Length(花萼長度),Sepal.Width(花萼寬度),Petal.Length(花瓣長度),Petal.Width(花瓣寬度)),特征都為正浮點數,單位為厘米。目標值為鳶尾花的分類(Iris Setosa(山鳶尾) , Iris Versicolour(雜色鳶尾),IrisVirginica (維吉尼亞鳶尾))

from sklearn.datasets import load_iris

#導入IRIS 數據集
iris = load_iris()
#特征矩陣
iris.data
#目標向量
iris.target

2. 數據預處理

通過特征提取,我們能得到未經處理的特征,這是特征可能存在以下問題:

  • 不屬于同一量綱:即特征的規格不一樣,不能放在一起比較。無量綱化可以解決這一問題。

    • 標準化
      # 使用preproccessing庫的 StandardScaler類對數據進行標準化的代碼如下:
      from sklearn.preprocessing import StandardScaler
      # 標準化,返回值為標準化后的數據
      StandardScaler().fit_transform(iris.data)
      
    • 區間縮放法
      區間縮放法的思路有多種,常見的一種為利用兩個最值進行縮放:
      # 使用preproccessing庫的 MinMaxScaler類對數據進行區間縮放代碼如下:
      from sklearn.preprocessing import MinMaxScaler
      # 區間縮放,返回值為縮放到[0,1]區間的數據
      MinMaxScaler().fit_transform(iris.data)
      
    • 數據歸一化
      歸一化是依照特征矩陣的行處理數據,其目的在于樣本向量在點乘運算或其他核函數計算相似性時,擁有統一的標準,也就是說都轉化為“單位向量”
      # 使用preprocessing庫的 Normalizer 類對數據進行歸一化的代碼如下:
      from sklearn.preprocessing import Normalizer
      # 歸一化,返回值為歸一化后的數據  
      Normalizer().fit_transform(iris.data)
      

    無量綱化使不同規格的數據轉化到同一規格。常用的無量綱方法有標準化和區間縮放法。區間縮放法利用了界值信息,將特征的取值區間縮放到某個特點的范圍,例如[0,1]

  • 信息冗余:對魚某些定量特征,其包含的有效信息為區間劃分,列如學習成績,假若只關心“及格”或“不及格”,那么可以將定量的考分,轉化為“1”和“0”表示及格和未及格,二值化可以解決這一問題。
    定量特征二值化的核心在于設定一個閥值,大于閥值的賦值為1,小于等于閥值的賦值為0:

    #使用preprocessing 庫的 Binarizer類對數據進行二值化的代碼如下:
    from sklearn.preprocessing import Binarizer
    # 二值化,閥值設置為3, 返回值為二值化后的數據
    Binarizer(threshold = 3).fit_transform(iris.data)
    
  • 定性特征不能直接使用:某些機器學習算法和模型只能接受定量特征的輸入,那么需要獎定性特征轉化為定量特征。最簡單的方式是為每一種定性值,但這種方式過于靈活,增加了調參的工作。通常使用啞編碼的方式將定性特征轉化為定量特征:假設有N種定性值,則將這一個特征擴展為N種特征,當原始特征值為第i種定性值時,第i個擴展特征賦值為1,其他擴展特征賦值為0.啞編碼的方式相比直接指定的方式,不用增加調參的工作,對于線性模型來說,使用啞編碼的特征可達到的非線性的效果。

    import pandas as pd
    from sklearn.preprocessing import OneHotEncoder
    from sklearn.preprocessing import LabelEncoder
    # 啞編碼,返回值為啞編碼后的數據
    testData = pd.DataFrame({'pet':['cat','dog','dog','fish'],'age':[4,6,3,3], 'salary':[4,5,1,1]})
    OneHotEncoder(sparse = False).fit_transform(testData[['age']])
    #  對于字符型變量,OneHotEncoder目前無法對其進行編碼
    

可以采用方法,曲線救國
arry = LabelEncoder().fit_transform(testdata['pet'])
OneHotEncoder(sparse = False).fit_transform(arry.reshape(-1,-1))
```

  • 存在缺失值:缺失值需要補充。
  • 信息利用率低:不同的機器學習算法和模型對數據中信息的利用是不同的,之前提到在線性模型中,使用對定性特征啞編碼可以達到非線性的效果。類似地,對定量變量多項式化,或者進行其他的轉化,都能達到非線性的效果
    常見的數據變換有基于多項式的,基于指數函數的,基于對數函數的
    # 基于多項式的變幻
    from sklearn.preprocessing import PolynomialFeatures
    # 多項式轉換
    # 參數digree 為度, 默認值為2 
    PolynomialFeatures().fit_transform(iris.data)
    # 基于單變元函數的數據可以使用統一的方式完成
    from numpy import loglp
    from sklearn.preprocessing import FunctionTransformer
    # 自定義轉換函數為對數函數的數據變換
    # 第一個參數是單變元函數
    FunctionTransformer(loglp).fit_transform(iris.data)
    

我們可以使用sklearn中的preprocessing庫進行數據預處理,可以覆蓋以上問題的解決方案。

3. 特征選擇

當數據預處理完成后,我們需要選擇有意義的特征輸入機械學習的算法和模型中進行訓練。通常來說,從兩個方面考慮來選擇特征:

  • 特征是否發散:如果一個特征不發散,例如方差接近于0,也就是說樣本在這個特征上基本上沒有差異,這個特征對于樣本區分并沒有什么用。
  • 特征與目標的相關性:這點比較顯而易見,與目標相關性高的特征,應當優選選擇。除方差法外。本文介紹的其他方法均從相關性考慮。

根據特征選擇的形式又可以將特征選擇的方法分為3種:

  • Filter : 過濾法,按照發散性或者相關性對各個特征進行評分,設定閥值或者待選閥值的個數,選擇特征
    過濾法與后續機器學習算法的選擇無關。

    1. 方差法(計算各個特征的方差,根據閥值,選擇方差大于閥值的特征)
    from sklearn.feature_selection import VarianceThreshold
    # 方差選擇法,返回值為特征選擇后的數據
    # 參數threshold為方差的閥值
    VarianceThreshold(threshold = 3).fit_transform(iris.data)
    
    1. 相關系數法(先要計算各個特征對目標值的相關系數以及相關系數的P值)
    from sklearn.feature_selection import SelectKBest
    from scipy.stats import pearsonr
    # 選擇K個最好的特征,返回選擇特征后的數據
    # 第一個參數為計算評估特征是否好的函數,該函數輸入特征矩陣和目標向量,輸出二元組(評分,P值)的數組,數組的第i項為第i個特征的評分和P值。在此定義為計算相關系數
    SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)
    
    1. 卡方檢驗
      經典的卡方檢驗是檢驗定性自變量對性因變量的相關性。假設自變量有N種取值,因變量有M種取值,考慮自變量等于i且因變量等于j的樣本頻數的觀察值與期望的差距,構建統計量:
    from sklearn.feature_selection import SelectKBest
    from sklearn.feature_selection import chi2
    # 選擇K個最好的特征,返回選擇特征后的數據
    SelectKBest(chi2, k = 2).fit_transform(iris.data,iris.target)
    
    1. 互信息法
      經典的互信息也是平價定性自變量對定性因變量的相關性的
    from sklearn.feature_selection import SelectKBest
    from minepy import MINE
    # 由于MINE的設計不是函數式的,定義mic方法將其為函數式,返回一個二元組,    二元組的第二項設置成固定的P值 0.5
    def mic(x,y):
        m = MINE()
        m.compute_score(x,y)
        return (m.mic(), 0.5)
    # 選擇K個最好的特征,返回特征選擇后的數據
    SelectKBest(lambda X, Y : array(map(lambda xmic(x,Y)).T, k = 2).fit_transform(iris.data, iris.target)
    
  • Wrapper : 包裝法,根據目標函數(通常是預測效果評分),每次選擇若干特征,或者排除若干特征。

    1. 遞歸特征消除法
      遞歸消除特征法使用一個基模型來進行多輪訓練,每輪訓練后,消除若干權值系數的特征,再基于新的特征集進行下一輪訓練。
    from sklearn.feature_selection import RFE
    from sklearn.linear_model import LogisticRegression
     # 遞歸特征消除法,返回特征選擇后的數據
     # 參數 estimator 為基模型
     # 參數n_features_to_select為選擇的特征個數
     RFE(estimator = LogisticRegression(), n_features_to_select = 2).fit_transform(iris.data, iris.target)
    
  • Embedded : 集成法,先使用某些機器學習的算法和模型進行訓練,得到各個特征的權值系數,根據系數從大到小選擇特征。類似于 Filter方法,但是是通過訓練來確定特征的

    1. 基于懲罰項的特征選擇法(沒看懂~)
    2. 基于樹模型的特征選擇法
    from sklearn.feature_selection import SelectFromModel 
    from sklearn.ensemble import GradientBoostingClassifier
    # GBDT作為基模型的特征選擇
    selectFromModel(GradientBoostingClassifier()).fit_transform(iris.data,iris.target)
    
  1. 降維
    當特征選擇完成以后,可以直接訓練模型了,但是可能由于特征矩陣過大,導致計算量大,訓練時間長的問題,因此降低特征矩陣維度也是必不可少的。常見的降維方法除了以上提到的基于L1懲罰的模型以外,另外還有主成分分析法(PCA)和線性判別分析(LDA),線性判別分析本身也是一個分類模型。PCA和LDA有很多的相似點,其本質是要將原始的樣本映射到維度更低的樣本空間中,但是PCA和LDA的映射目標不一樣:PCA是為了讓映射后的樣本具有最大的發散性;而LDA是為了讓映射后的樣本具有最好的分類性能。所以說PCA是一種無監督的降維方法,而LDA是一種有監督的降維方法。
    1. 主成分分析法(PCA)
    from sklearn.decomposition import PCA
    from sklearn.decomposition import PCA
    #主成分分析法,返回降維后的數據
    #參數n_components為主成分數目
    PCA(n_components=2).fit_transform(iris.data)
    
    1. 線性判別分析法(LDA)
    from sklearn.lda import LDA
    #線性判別分析法,返回降維后的數據
    #參數n_components為降維后的維數
    LDA(n_components=2).fit_transform(iris.data, iris.target)
    
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容