數(shù)據(jù)預(yù)處理是進行機器學(xué)習(xí)的必要環(huán)節(jié)系忙,對原始數(shù)據(jù)進行加工,比如標(biāo)準(zhǔn)化惠豺、歸一化银还、二進制化、特征編碼耕腾、插補缺失值见剩、生成多項式特征等。
scikit-learn 是 Python 下的機器學(xué)習(xí)工具包扫俺,集成了預(yù)處理苍苞、降維、聚類狼纬、分類等方法羹呵。我們用此工具來介紹數(shù)據(jù)預(yù)處理。
主要應(yīng)用的是 preprocessing 類疗琉。
標(biāo)準(zhǔn)化 Standardization
常用的標(biāo)準(zhǔn)化方法為 z-score 法冈欢,目的是將傳入的矩陣變?yōu)槊苛芯禐?、方差為1的標(biāo)準(zhǔn)型盈简,因為機器學(xué)習(xí)中的函數(shù)許多是以0為中心的凑耻,例如 sigmoid 函數(shù),方差為1可以使數(shù)據(jù)分布均勻柠贤,防止某個特征數(shù)據(jù)過大影響模型的訓(xùn)練香浩。
我們用 sklearn 中的 preprocessing 類中的 scale 方法簡單進行標(biāo)準(zhǔn)化。
>>> from sklearn import preprocessing
>>> import numpy as np
>>> X = np.array([[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]])
>>> X_scaled = preprocessing.scale(X)
>>> X_scaled
array([[ 0. ..., -1.22..., 1.33...],
[ 1.22..., 0. ..., -0.26...],
[-1.22..., 1.22..., -1.06...]])
或者可以將計算均值和方差與轉(zhuǎn)換的步驟分開臼勉。
>>> scaler = preprocessing.StandardScaler().fit(X)
>>> scaler
StandardScaler(copy=True, with_mean=True, with_std=True)
>>> scaler.transform(X)
array([[ 0. ..., -1.22..., 1.33...],
[ 1.22..., 0. ..., -0.26...],
[-1.22..., 1.22..., -1.06...]])
fit 是計算過程邻吭,transform 是轉(zhuǎn)換過程。transform 的一個好處是可以繼續(xù)使用 fit 的數(shù)據(jù)宴霸,例如 transform 訓(xùn)練數(shù)據(jù)之后之后可以直接 transform 測試數(shù)據(jù)囱晴。
有時標(biāo)準(zhǔn)化時要求把數(shù)據(jù)縮放到某一個范圍中膏蚓,preprocessing 類也提供了 MinMaxScaler 方法,設(shè)置 MinMaxScaler 的參數(shù) feature_range=(min, max) 畸写。
當(dāng)然最常用的就是(0,1)范圍驮瞧。
>>> X_train = np.array([[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]])
...
>>> min_max_scaler = preprocessing.MinMaxScaler(feature_range=(0, 1))
>>> X_train_minmax = min_max_scaler.fit_transform(X_train)
>>> X_train_minmax
array([[ 0.5 , 0. , 1. ],
[ 1. , 0.5 , 0.33333333],
[ 0. , 1. , 0. ]])
歸一化 Normalization
歸一化是將每個樣本縮放到單位范數(shù)(可以粗略地理解為向量的函數(shù))的過程。如果后面要使用如二次型(點積)或者其它核方法計算兩個樣本之間的相似性這個方法會很有用艺糜。歸一化的計算方法是 1除以p-范數(shù)剧董。歸一化之后的樣本的 p-范數(shù)等于1。
preprocessing 類下的 normalize 方法可以直接歸一化破停,并可以選擇 l1 范數(shù)與 l2 范數(shù)翅楼,默認是 l2 范數(shù)。
>>> X = [[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]]
>>> X_normalized = preprocessing.normalize(X, norm='l2')
>>> X_normalized
array([[ 0.40..., -0.40..., 0.81...],
[ 1. ..., 0. ..., 0. ...],
[ 0. ..., 0.70..., -0.70...]])
normalize 也同樣有 fit 方法與 transform 方法真慢。
>>> normalizer = preprocessing.Normalizer().fit(X) # fit does nothing
>>> normalizer
Normalizer(copy=True, norm='l2')
>>> normalizer.transform(X)
array([[ 0.40..., -0.40..., 0.81...],
[ 1. ..., 0. ..., 0. ...],
[ 0. ..., 0.70..., -0.70...]])
.
>>> normalizer.transform([[-1., 1., 0.]])
array([[-0.70..., 0.70..., 0. ...]])
二進制化 Binarization
二進制化的方法是設(shè)定一個閾值毅臊,樣本值比閾值大的為1,小的為0黑界。
文本處理領(lǐng)域愿意使用二進制化管嬉,雖然歸一化和 TF-IDF 加工的特征表現(xiàn)得更好,但使用二進制化來簡化數(shù)據(jù)更為普遍(可能簡化概率推理)朗鸠。
>>> X = [[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]]
>>> binarizer = preprocessing.Binarizer().fit(X) # fit does nothing
>>> binarizer
Binarizer(copy=True, threshold=0.0)
>>> binarizer.transform(X)
array([[ 1., 0., 1.],
[ 1., 0., 0.],
[ 0., 1., 0.]])
閾值調(diào)整需要設(shè)置 threshold 參數(shù)蚯撩,下面代碼是設(shè)置閾值1.1的情況。
>>> binarizer = preprocessing.Binarizer(threshold=1.1)
>>> binarizer.transform(X)
array([[ 0., 0., 1.],
[ 1., 0., 0.],
[ 0., 0., 0.]])
類別特征編碼 Encoding categorical features
比如現(xiàn)在有特征 ["male", "female"] ["from Europe", "from US", "from Asia"],
["uses Firefox", "uses Chrome", "uses Safari", "uses Internet Explorer"]烛占,
平常我們將特征進行整數(shù)編碼.
["male", "from US", "uses Internet Explorer"] 編碼應(yīng)該是 [0, 1, 3]胎挎。
["female", "from Asia", "uses Chrome"]的編碼應(yīng)該是[1,2,1]。
但是 scikit-learn 估計器不能直接使用這種整數(shù)型的編碼忆家,它的輸入最好是連續(xù)型的犹菇,估計器也可能把整數(shù)編碼特征特征誤解為有序的數(shù)據(jù),這會有害于模型訓(xùn)練芽卿。
類別特征編碼用的是 OneHotEncoder 方法揭芍,占第幾位的特征值就是1,其余為0卸例。例如 ["male", "female"] 有兩個特征称杨,male 占第1個位置,剩下的0筷转,male 就是 [1,0]列另,female 就是 [0,1]; ["from Europe", "from US", "from Asia"]有3個特征旦装,"from Europe"就是 [1,0,0],"from US" 就是 [0,1,0]摊滔,"from Asia"就是 [0,0,1]阴绢,以此類推店乐。
["male", "from US", "uses Internet Explorer"]的整數(shù)編碼[0,1,3]的二進制編碼就是
[1,0, 0,1,0, 0,0,0,1]。
代碼實現(xiàn)用的是 preprocessing 類下的 OneHotEncoder 方法呻袭。
>>> enc = preprocessing.OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
handle_unknown='error', n_values='auto', sparse=True)
>>> enc.transform([[0, 1, 3]]).toarray()
array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]])
插補缺失值 Imputation of missing values
以往對于數(shù)據(jù)中有丟失值的情況眨八,做法是把該數(shù)據(jù)所在行和列都刪掉,這樣的后果是容易丟失重要的數(shù)據(jù)左电。
imputer 的方法利用平均值廉侧、中位數(shù)或出現(xiàn)頻率最高的數(shù)據(jù)對缺失的數(shù)據(jù)進行填補。代碼如下篓足,NaN 即位丟失的值段誊。
>>> import numpy as np
>>> from sklearn.preprocessing import Imputer
>>> imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
>>> imp.fit([[1, 2], [np.nan, 3], [7, 6]])
Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
>>> X = [[np.nan, 2], [6, np.nan], [7, 6]]
>>> print(imp.transform(X))
[[ 4. 2. ]
[ 6. 3.666...]
[ 7. 6. ]]
strategy 告訴了本代碼用 mean 平均值找補,fit 是用它括號里的數(shù)據(jù)計算平均值栈拖,transform 是應(yīng)用變換连舍。
生成多項式特征 Generating polynomial features
生成多項式的預(yù)處理方式是為了給輸入數(shù)據(jù)增加復(fù)雜性。處理后的特征會獲得高階的數(shù)據(jù)和交叉的數(shù)據(jù)涩哟。
用到的是 preprocessing 下的 PolynomialFeatures 方法索赏。
>>> import numpy as np
>>> from sklearn.preprocessing import PolynomialFeatures
>>> X = np.arange(6).reshape(3, 2)
>>> X
array([[0, 1],
[2, 3],
[4, 5]])
>>> poly = PolynomialFeatures(2)
>>> poly.fit_transform(X)
array([[ 1., 0., 1., 0., 0., 1.],
[ 1., 2., 3., 4., 6., 9.],
[ 1., 4., 5., 16., 20., 25.]])
PolynomialFeatures(2) 指的是最多生成二次項。
X的特征值由(X1贴彼,X2)變成了(1潜腻,X1,X2器仗,X12融涣,X1X2,X22)青灼。