1 特徵工程是什麼?
有這麼一句話在業界廣泛流傳:數據和特徵決定了機器學習的上限,而模型和算法只是逼近這個上限而已。那特徵工程到底是什麼呢?顧名思義,其本質是一項工程活動,目的是最大限度地從原始數據中提取特徵以供算法和模型使用。通過總結和歸納,人們認為特徵工程包括以下方面:
特徵處理是特徵工程的核心部分,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
2 數據預處理
通過特徵提取,我們能得到未經處理的特徵,這時的特徵可能有以下問題:
不屬於同一量綱:即特徵的規格不一樣,不能夠放在一起比較。無量綱化可以解決這一問題。
信息冗餘:對於某些定量特徵,其包含的有效信息為區間劃分,例如學習成績,假若只關心「及格」或不「及格」,那麼需要將定量的考分,轉換成「1」和「0」表示及格和未及格。二值化可以解決這一問題。
定性特徵不能直接使用:某些機器學習算法和模型只能接受定量特徵的輸入,那麼需要將定性特徵轉換為定量特徵。最簡單的方式是為每一種定性值指定一個定量值,但是這種方式過於靈活,增加了調參的工作。通常使用啞編碼的方式將定性特徵轉換為定量特徵:假設有N種定性值,則將這一個特徵擴展為N種特徵,當原始特徵值為第i種定性值時,第i個擴展特徵賦值為1,其他擴展特徵賦值為0。啞編碼的方式相比直接指定的方式,不用增加調參的工作,對於線性模型來說,使用啞編碼後的特徵可達到非線性的效果。
存在缺失值:缺失值需要補充。
信息利用率低:不同的機器學習算法和模型對數據中信息的利用是不同的,之前提到在線性模型中,使用對定性特徵啞編碼可以達到非線性的效果。類似地,對定量變量多項式化,或者進行其他的轉換,都能達到非線性的效果。
我們使用sklearn中的preproccessing庫來進行數據預處理,可以覆蓋以上問題的解決方案。
2.1 無量綱化
無量綱化使不同規格的數據轉換到同一規格。常見的無量綱化方法有標準化和區間縮放法。標準化的前提是特徵值服從正態分布,標準化後,其轉換成標準正態分布。區間縮放法利用了邊界值信息,將特徵的取值區間縮放到某個特點的範圍,例如[0, 1]等。
2.1.1 標準化
標準化需要計算特徵的均值和標準差,公式表達為:
使用preproccessing庫的StandardScaler類對數據進行標準化的代碼如下:
from sklearn.preprocessing import StandardScaler
#標準化,返回值為標準化後的數據
StandardScaler().fit_transform(iris.data)
2.1.2 區間縮放法
區間縮放法的思路有多種,常見的一種為利用兩個最值進行縮放,公式表達為:
使用preproccessing庫的MinMaxScaler類對數據進行區間縮放的代碼如下:
from sklearn.preprocessing import MinMaxScaler
#區間縮放,返回值為縮放到[0, 1]區間的數據
MinMaxScaler().fit_transform(iris.data)
2.1.3 標準化與歸一化的區別
簡單來說,標準化是依照特徵矩陣的列處理數據,其通過求z-score的方法,將樣本的特徵值轉換到同一量綱下。歸一化是依照特徵矩陣的行處理數據,其目的在於樣本向量在點乘運算或其他核函數計算相似性時,擁有統一的標準,也就是說都轉化為「單位向量」。規則為l2的歸一化公式如下:
使用preproccessing庫的Normalizer類對數據進行歸一化的代碼如下:
from sklearn.preprocessing import Normalizer
#歸一化,返回值為歸一化後的數據
Normalizer().fit_transform(iris.data)
2.2 對定量特徵二值化
定量特徵二值化的核心在於設定一個閾值,大於閾值的賦值為1,小於等於閾值的賦值為0,公式表達如下:
使用preproccessing庫的Binarizer類對數據進行二值化的代碼如下:
from sklearn.preprocessing import Binarizer
#二值化,閾值設置為3,返回值為二值化後的數據
Binarizer(threshold=3).fit_transform(iris.data)
2.3 對定性特徵啞編碼
由於IRIS數據集的特徵皆為定量特徵,故使用其目標值進行啞編碼(實際上是不需要的)。使用preproccessing庫的OneHotEncoder類對數據進行啞編碼的代碼如下:
from sklearn.preprocessing import OneHotEncoder
#啞編碼,對IRIS數據集的目標值,返回值為啞編碼後的數據
OneHotEncoder().fit_transform(iris.target.reshape((-1,1)))2.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)))2.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)《數據科學與人工智慧》公眾號推薦朋友們學習和使用Python語言,需要加入Python語言群的,請掃碼加我個人微信,備註【姓名-Python群】,我誠邀你入群,大家學習和分享。