1. 特征工程是什么邦尊?
數(shù)據(jù)和特征決定了機器學習的上限涝开,而模型和算法只是逼近了這個上線而已赃磨。特征工程的本質(zhì)是一項工程活動蝉仇,目的是最大限度地從原始數(shù)據(jù)中提取特征以供算法和模型使用后裸。通過總結(jié)和歸納瑰钮,人們認為特征工程包括以下方面:
本文使用python sklearn IRIS(鳶尾花)數(shù)據(jù)集來對特征處理功能進行說明,IRIS數(shù)據(jù)集包含4個特征(Sepal.Length(花萼長度)微驶,Sepal.Width(花萼寬度)浪谴,Petal.Length(花瓣長度),Petal.Width(花瓣寬度)),特征都為正浮點數(shù)因苹,單位為厘米苟耻。目標值為鳶尾花的分類(Iris Setosa(山鳶尾) , Iris Versicolour(雜色鳶尾)扶檐,IrisVirginica (維吉尼亞鳶尾))
from sklearn.datasets import load_iris
#導入IRIS 數(shù)據(jù)集
iris = load_iris()
#特征矩陣
iris.data
#目標向量
iris.target
2. 數(shù)據(jù)預處理
通過特征提取凶杖,我們能得到未經(jīng)處理的特征,這是特征可能存在以下問題:
-
不屬于同一量綱:即特征的規(guī)格不一樣款筑,不能放在一起比較智蝠。無量綱化可以解決這一問題。
- 標準化
# 使用preproccessing庫的 StandardScaler類對數(shù)據(jù)進行標準化的代碼如下: from sklearn.preprocessing import StandardScaler # 標準化奈梳,返回值為標準化后的數(shù)據(jù) StandardScaler().fit_transform(iris.data)
- 區(qū)間縮放法
區(qū)間縮放法的思路有多種杈湾,常見的一種為利用兩個最值進行縮放:# 使用preproccessing庫的 MinMaxScaler類對數(shù)據(jù)進行區(qū)間縮放代碼如下: from sklearn.preprocessing import MinMaxScaler # 區(qū)間縮放,返回值為縮放到[0,1]區(qū)間的數(shù)據(jù) MinMaxScaler().fit_transform(iris.data)
- 數(shù)據(jù)歸一化
歸一化是依照特征矩陣的行處理數(shù)據(jù)攘须,其目的在于樣本向量在點乘運算或其他核函數(shù)計算相似性時毛秘,擁有統(tǒng)一的標準,也就是說都轉(zhuǎn)化為“單位向量”# 使用preprocessing庫的 Normalizer 類對數(shù)據(jù)進行歸一化的代碼如下: from sklearn.preprocessing import Normalizer # 歸一化阻课,返回值為歸一化后的數(shù)據(jù) Normalizer().fit_transform(iris.data)
無量綱化使不同規(guī)格的數(shù)據(jù)轉(zhuǎn)化到同一規(guī)格叫挟。常用的無量綱方法有標準化和區(qū)間縮放法。區(qū)間縮放法利用了界值信息限煞,將特征的取值區(qū)間縮放到某個特點的范圍抹恳,例如[0,1]
- 標準化
-
信息冗余:對魚某些定量特征,其包含的有效信息為區(qū)間劃分署驻,列如學習成績奋献,假若只關(guān)心“及格”或“不及格”,那么可以將定量的考分旺上,轉(zhuǎn)化為“1”和“0”表示及格和未及格瓶蚂,二值化可以解決這一問題。
定量特征二值化的核心在于設(shè)定一個閥值宣吱,大于閥值的賦值為1窃这,小于等于閥值的賦值為0:#使用preprocessing 庫的 Binarizer類對數(shù)據(jù)進行二值化的代碼如下: from sklearn.preprocessing import Binarizer # 二值化,閥值設(shè)置為3征候, 返回值為二值化后的數(shù)據(jù) Binarizer(threshold = 3).fit_transform(iris.data)
-
定性特征不能直接使用:某些機器學習算法和模型只能接受定量特征的輸入杭攻,那么需要獎定性特征轉(zhuǎn)化為定量特征祟敛。最簡單的方式是為每一種定性值,但這種方式過于靈活兆解,增加了調(diào)參的工作馆铁。通常使用啞編碼的方式將定性特征轉(zhuǎn)化為定量特征:假設(shè)有N種定性值,則將這一個特征擴展為N種特征锅睛,當原始特征值為第i種定性值時埠巨,第i個擴展特征賦值為1,其他擴展特征賦值為0.啞編碼的方式相比直接指定的方式现拒,不用增加調(diào)參的工作乖订,對于線性模型來說,使用啞編碼的特征可達到的非線性的效果具练。
import pandas as pd from sklearn.preprocessing import OneHotEncoder from sklearn.preprocessing import LabelEncoder # 啞編碼,返回值為啞編碼后的數(shù)據(jù) 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))
```
- 存在缺失值:缺失值需要補充岂丘。
- 信息利用率低:不同的機器學習算法和模型對數(shù)據(jù)中信息的利用是不同的,之前提到在線性模型中奥帘,使用對定性特征啞編碼可以達到非線性的效果。類似地寨蹋,對定量變量多項式化松蒜,或者進行其他的轉(zhuǎn)化,都能達到非線性的效果
常見的數(shù)據(jù)變換有基于多項式的已旧,基于指數(shù)函數(shù)的,基于對數(shù)函數(shù)的# 基于多項式的變幻 from sklearn.preprocessing import PolynomialFeatures # 多項式轉(zhuǎn)換 # 參數(shù)digree 為度惊楼, 默認值為2 PolynomialFeatures().fit_transform(iris.data) # 基于單變元函數(shù)的數(shù)據(jù)可以使用統(tǒng)一的方式完成 from numpy import loglp from sklearn.preprocessing import FunctionTransformer # 自定義轉(zhuǎn)換函數(shù)為對數(shù)函數(shù)的數(shù)據(jù)變換 # 第一個參數(shù)是單變元函數(shù) FunctionTransformer(loglp).fit_transform(iris.data)
我們可以使用sklearn中的preprocessing庫進行數(shù)據(jù)預處理,可以覆蓋以上問題的解決方案秸讹。
3. 特征選擇
當數(shù)據(jù)預處理完成后檀咙,我們需要選擇有意義的特征輸入機械學習的算法和模型中進行訓練。通常來說璃诀,從兩個方面考慮來選擇特征:
- 特征是否發(fā)散:如果一個特征不發(fā)散,例如方差接近于0侣诺,也就是說樣本在這個特征上基本上沒有差異,這個特征對于樣本區(qū)分并沒有什么用年鸳。
- 特征與目標的相關(guān)性:這點比較顯而易見,與目標相關(guān)性高的特征彼棍,應(yīng)當優(yōu)選選擇膳算。除方差法外。本文介紹的其他方法均從相關(guān)性考慮涕蜂。
根據(jù)特征選擇的形式又可以將特征選擇的方法分為3種:
-
Filter : 過濾法,按照發(fā)散性或者相關(guān)性對各個特征進行評分蜘拉,設(shè)定閥值或者待選閥值的個數(shù)有鹿,選擇特征
過濾法與后續(xù)機器學習算法的選擇無關(guān)。- 方差法(計算各個特征的方差葱跋,根據(jù)閥值,選擇方差大于閥值的特征)
from sklearn.feature_selection import VarianceThreshold # 方差選擇法稍味,返回值為特征選擇后的數(shù)據(jù) # 參數(shù)threshold為方差的閥值 VarianceThreshold(threshold = 3).fit_transform(iris.data)
- 相關(guān)系數(shù)法(先要計算各個特征對目標值的相關(guān)系數(shù)以及相關(guān)系數(shù)的P值)
from sklearn.feature_selection import SelectKBest from scipy.stats import pearsonr # 選擇K個最好的特征荠卷,返回選擇特征后的數(shù)據(jù) # 第一個參數(shù)為計算評估特征是否好的函數(shù),該函數(shù)輸入特征矩陣和目標向量僵朗,輸出二元組(評分,P值)的數(shù)組顶吮,數(shù)組的第i項為第i個特征的評分和P值粪薛。在此定義為計算相關(guān)系數(shù) SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)
- 卡方檢驗
經(jīng)典的卡方檢驗是檢驗定性自變量對性因變量的相關(guān)性。假設(shè)自變量有N種取值湃交,因變量有M種取值,考慮自變量等于i且因變量等于j的樣本頻數(shù)的觀察值與期望的差距搞莺,構(gòu)建統(tǒng)計量:
from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 # 選擇K個最好的特征,返回選擇特征后的數(shù)據(jù) SelectKBest(chi2, k = 2).fit_transform(iris.data,iris.target)
-
互信息法
經(jīng)典的互信息也是平價定性自變量對定性因變量的相關(guān)性的
from sklearn.feature_selection import SelectKBest from minepy import MINE # 由于MINE的設(shè)計不是函數(shù)式的迈喉,定義mic方法將其為函數(shù)式温圆,返回一個二元組, 二元組的第二項設(shè)置成固定的P值 0.5 def mic(x,y): m = MINE() m.compute_score(x,y) return (m.mic(), 0.5) # 選擇K個最好的特征得运,返回特征選擇后的數(shù)據(jù) SelectKBest(lambda X, Y : array(map(lambda xmic(x,Y)).T, k = 2).fit_transform(iris.data, iris.target)
-
Wrapper : 包裝法锅移,根據(jù)目標函數(shù)(通常是預測效果評分),每次選擇若干特征帆啃,或者排除若干特征窍帝。
- 遞歸特征消除法
遞歸消除特征法使用一個基模型來進行多輪訓練,每輪訓練后疯坤,消除若干權(quán)值系數(shù)的特征深浮,再基于新的特征集進行下一輪訓練。
from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression # 遞歸特征消除法飞苇,返回特征選擇后的數(shù)據(jù) # 參數(shù) estimator 為基模型 # 參數(shù)n_features_to_select為選擇的特征個數(shù) RFE(estimator = LogisticRegression(), n_features_to_select = 2).fit_transform(iris.data, iris.target)
- 遞歸特征消除法
-
Embedded : 集成法布卡,先使用某些機器學習的算法和模型進行訓練,得到各個特征的權(quán)值系數(shù)忿等,根據(jù)系數(shù)從大到小選擇特征。類似于 Filter方法庵寞,但是是通過訓練來確定特征的
- 基于懲罰項的特征選擇法(沒看懂~)
- 基于樹模型的特征選擇法
from sklearn.feature_selection import SelectFromModel from sklearn.ensemble import GradientBoostingClassifier # GBDT作為基模型的特征選擇 selectFromModel(GradientBoostingClassifier()).fit_transform(iris.data,iris.target)
- 降維
當特征選擇完成以后,可以直接訓練模型了捐川,但是可能由于特征矩陣過大,導致計算量大将谊,訓練時間長的問題,因此降低特征矩陣維度也是必不可少的尊浓。常見的降維方法除了以上提到的基于L1懲罰的模型以外纯衍,另外還有主成分分析法(PCA)和線性判別分析(LDA),線性判別分析本身也是一個分類模型襟诸。PCA和LDA有很多的相似點,其本質(zhì)是要將原始的樣本映射到維度更低的樣本空間中菇用,但是PCA和LDA的映射目標不一樣:PCA是為了讓映射后的樣本具有最大的發(fā)散性陷揪;而LDA是為了讓映射后的樣本具有最好的分類性能。所以說PCA是一種無監(jiān)督的降維方法悍缠,而LDA是一種有監(jiān)督的降維方法。- 主成分分析法(PCA)
from sklearn.decomposition import PCA from sklearn.decomposition import PCA #主成分分析法滤港,返回降維后的數(shù)據(jù) #參數(shù)n_components為主成分數(shù)目 PCA(n_components=2).fit_transform(iris.data)
- 線性判別分析法(LDA)
from sklearn.lda import LDA #線性判別分析法趴拧,返回降維后的數(shù)據(jù) #參數(shù)n_components為降維后的維數(shù) LDA(n_components=2).fit_transform(iris.data, iris.target)