一、什麼是特征工程
有這麼一句話在業界廣泛流傳:資料和特征決定了機器學習的上限,而模型和算法隻是逼近這個上限而已。那特征工程到底是什麼呢?顧名思義,其本質是一項工程活動,目的是最大限度地從原始資料中提取特征以供算法和模型使用。通過總結和歸納,人們認為特征工程包括以下方面:

特征處理是特征工程的核心部分,sklearn提供了較為完整的特征處理方法,包括資料預處理,特征選擇,降維等。首次接觸到sklearn,通常會被其豐富且友善的算法模型庫吸引,但是這裡介紹的特征處理庫也十分強大!
本文中使用sklearn中的IRIS(鸢尾花)資料集來對特征處理功能進行說明。IRIS資料集由Fisher在1936年整理,包含4個特征(Sepal.Length(花萼長度)、Sepal.Width(花萼寬度)、Petal.Length(花瓣長度)、Petal.Width(花瓣寬度)),特征值都為正浮點數,機關為厘米。目标值為鸢尾花的分類(Iris Setosa(山鸢尾)、Iris Versicolour(雜色鸢尾),Iris Virginica(維吉尼亞鸢尾))。導入IRIS資料集的代碼如下:
from sklearn.datasets import load_iris
#導入IRIS資料集
iris = load_iris()
#特征矩陣
iris.data
#目标向量
iris.target
二、資料預處理
通過特征提取,我們能得到未經處理的特征,這時的特征可能有以下問題:
- 不屬于同一量綱:即特征的規格不一樣,不能夠放在一起比較。無量綱化可以解決這一問題。
- 資訊備援:對于某些定量特征,其包含的有效資訊為區間劃分,例如學習成績,假若隻關心“及格”或不“及格”,那麼需要将定量的考分,轉換成“1”和“0”表示及格和未及格。二值化可以解決這一問題。
- 定性特征不能直接使用:某些機器學習算法和模型隻能接受定量特征的輸入,那麼需要将定性特征轉換為定量特征。最簡單的方式是為每一種定性值指定一個定量值,但是這種方式過于靈活,增加了調參的工作。通常使用啞編碼的方式将定性特征轉換為定量特征:假設有N種定性值,則将這一個特征擴充為N種特征,當原始特征值為第i種定性值時,第i個擴充特征指派為1,其他擴充特征指派為0。啞編碼的方式相比直接指定的方式,不用增加調參的工作,對于線性模型來說,使用啞編碼後的特征可達到非線性的效果。
- 存在缺失值:缺失值需要補充。
- 資訊使用率低:不同的機器學習算法和模型對資料中資訊的利用是不同的,之前提到線上性模型中,使用對定性特征啞編碼可以達到非線性的效果。類似地,對定量變量多項式化,或者進行其他的轉換,都能達到非線性的效果。
我們使用sklearn中的preproccessing庫來進行資料預處理,可以覆寫以上問題的解決方案。
1. 無量綱化
無量綱化使不同規格的資料轉換到同一規格。常見的無量綱化方法有标準化和區間縮放法。标準化的前提是特征值服從正态分布,标準化後,其轉換成标準正态分布。區間縮放法利用了邊界值資訊,将特征的取值區間縮放到某個特點的範圍,例如[0, 1]等。
- 标準化
标準化需要計算特征的均值和标準差,公式表達為:
使用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)
- 标準化與歸一化的差別
簡單來說,标準化是依照特征矩陣的列處理資料,其通過求z-score的方法,将樣本的特征值轉換到同一量綱下。歸一化是依照特征矩陣的行處理資料,其目的在于樣本向量在點乘運算或其他核函數計算相似性時,擁有統一的标準,也就是說都轉化為“機關向量”。規則為L2的歸一化公式如下:
使用preproccessing庫的Normalizer類對資料進行歸一化的代碼如下:
from sklearn.preprocessing import Normalizer
#歸一化,傳回值為歸一化後的資料
Normalizer().fit_transform(iris.data)
-
- 對定量特征二值化
定量特征二值化的核心在于設定一個門檻值,大于門檻值的指派為1,小于等于門檻值的指派為0,公式表達如下:
使用preproccessing庫的Binarizer類對資料進行二值化的代碼如下:
from sklearn.preprocessing import Binarizer
#二值化,門檻值設定為3,傳回值為二值化後的資料
Binarizer(threshold=3).fit_transform(iris.data)
3.對定性特征獨熱編碼
由于IRIS資料集的特征皆為定量特征,故使用其目标值進行獨熱編碼(實際上是不需要的)。使用preproccessing庫的OneHotEncoder類對資料進行啞編碼的代碼如下:
from sklearn.preprocessing import OneHotEncoder
#啞編碼,對IRIS資料集的目标值,傳回值為啞編碼後的資料
OneHotEncoder().fit_transform(iris.target.reshape((-1,1)))
4.缺失值計算
由于IRIS資料集沒有缺失值,故對資料集新增一個樣本,4個特征均指派為NaN,表示資料缺失。使用preproccessing庫的Imputer類對資料進行缺失值計算的代碼如下:
from numpy import vstack, array, nan
from sklearn.preprocessing import Imputer
#缺失值計算,傳回值為計算缺失值後的資料
#參數missing_value為缺失值的表示形式,預設為NaN
#參數strategy為缺失值填充方式,預設為mean(均值)
Imputer().fit_transform(vstack((array([nan, nan, nan, nan]), iris.data)))
5.資料變換
常見的資料變換有基于多項式的、基于指數函數的、基于對數函數的。4個特征,度為2的多項式轉換公式如下:
使用preproccessing庫的PolynomialFeatures類對資料進行多項式轉換的代碼如下:
from sklearn.preprocessing import PolynomialFeatures
#多項式轉換
#參數degree為度,預設值為2
PolynomialFeatures().fit_transform(iris.data)
基于單變元函數的資料變換可以使用一個統一的方式完成,使用preproccessing庫的FunctionTransformer對資料進行對數函數轉換的代碼如下:
from numpy import log1p
from sklearn.preprocessing import FunctionTransformer
#自定義轉換函數為對數函數的資料變換
#第一個參數是單變元函數
FunctionTransformer(log1p).fit_transform(iris.data)
回顧