【sklearn】數據預處理 sklearn.preprocessing

數據預處理python

  • 標準化 (Standardization)
  • 規範化(Normalization)
  • 二值化
  • 分類特徵編碼
  • 推定缺失數據
  • 生成多項式特徵
  • 定製轉換器

1. 標準化Standardization(這裏指移除均值和方差標準化) 
標準化是不少數據分析問題的一個重要步驟,也是不少利用機器學習算法進行數據處理的必要步驟。算法

1.1 z-score標準化 
z-score標準化指的是將數據轉化成均值爲0方差爲1的高斯分佈,也就是一般說的z-score標準化,可是對於不服從標準正態分佈的特徵,這樣作效果會不好。數組

在實際應用中,咱們常常忽視分佈的形狀,將數據進行z-score標準化。若是不將數據進行標準化處理,在利用機器學習算法(例如SVM)的過程當中,若是目標函數中的一個特徵的方差的階數的量級高於其餘特徵的方差,那麼這一特徵就會在目標函數中占主導地位,從而「淹沒」其餘特徵的做用。瀏覽器

Python中的scale函數是一種快速進行z-score標準化的方法,可以處理相似於數組結構的數據。Z-score標準化後的數據的均值爲0,方差爲1。機器學習

>>> from sklearn import preprocessing >>> x = [[1., -1., 2], # 每一行爲[feature1, feature2, feature3] ... [2., 0., 0.], ... [0., 1., -1.]] >>> x_scaled = preprocessing.scale(x) >>> x_scaled array([[ 0. , -1.22474487, 1.33630621], [ 1.22474487, 0. , -0.26726124], [-1.22474487, 1.22474487, -1.06904497]]) >>> x_scaled.mean(axis=0) array([ 0., 0., 0.]) >>> x_scaled.std(axis=0) array([ 1., 1., 1.])

preprocessing模塊還提供了一個實用類StandardScaler,這個類實現了一個叫作Transformer的應用程序接口,可以計算訓練數據的均值和標準差,從而在訓練數據集上再次使用。函數

>>> scaler = preprocessing.StandardScaler().fit(x) >>> scaler StandardScaler(copy=True, with_mean=True, with_std=True) >>> scaler.mean_ array([ 1. , 0. , 0.33333333]) >>> scaler.scale_ array([ 0.81649658, 0.81649658, 1.24721913]) >>> scaler.transform(x) array([[ 0. , -1.22474487, 1.33630621], [ 1.22474487, 0. , -0.26726124], [-1.22474487, 1.22474487, -1.06904497]]) >>> scaler = preprocessing.StandardScaler().fit(x) >>> scaler StandardScaler(copy=True, with_mean=True, with_std=True) >>> scaler.transform([[-1., 1., 0.]]) # 在其餘數據集上使用 array([[-2.44948974, 1.22474487, -0.26726124]])

1.2 將特徵數據縮放到一個範圍 scale to a range 
利用最大值和最小值進行縮放,一般是將數據縮放到0-1這個範圍,或者是將每一個特徵的絕對值最大值縮放到單位尺度,分別利用MinMaxScaler和MaxAbsScaler實現。 
使用這一方法的狀況通常有兩種: 
(1) 特徵的標準差較小 
(2) 可使稀疏數據集中的0值繼續爲0學習

>>> x [[1.0, -1.0, 2], [2.0, 0.0, 0.0], [0.0, 1.0, -1.0]] >>> min_max_scaler = preprocessing.MinMaxScaler() >>> x_scaled_minmax = min_max_scaler.fit_transform(x) >>> x_scaled_minmax array([[ 0.5 , 0. , 1. ], [ 1. , 0.5 , 0.33333333], [ 0. , 1. , 0. ]]) >>> #這個transformer的實例還可以應用於新的數據集,此時的縮放比例與以前訓練集上的縮放比例是相同的。 >>> x_test = np.array([[3., 1., 4.]]) >>> min_max_scaler.transform(x_test) array([[ 1.5 , 1. , 1.66666667]]) 

 

能夠查看縮放算子的一些屬性:編碼

min_, scale_, data_min_, data_max_, data_range_, 
>>> min_max_scaler.scale_ # 縮放比例=1/(max-min) array([ 0.5 , 0.5 , 0.33333333]) >>> min_max_scaler.min_ # (x-min)/(max-min), 這裏min_表明min/(max-min) array([ 0. , 0.5 , 0.33333333]) 

 

MaxAbsScaler與上述用法類似,可是標準化後的數據的取值範圍爲[-1, 1]。這對於稀疏數據或者是數據中心已經爲0的數據頗有意義。spa

>>> x=[[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]] >>> max_abs_scaler = preprocessing.MaxAbsScaler() >>> max_abs_scaler.fit_transform(x) array([[ 0.5, -1. , 1. ], [ 1. , 0. , 0. ], [ 0. , 1. , -0.5]]) >>> x_test = [[-2., 4., 2.]] >>> max_abs_scaler.transform(x_test) array([[-1., 4., 1.]]) >>> max_abs_scaler.scale_ array([ 2., 1., 2.])

 

1.3 縮放稀疏數據 
將稀疏數據置中有可能破壞數據的稀疏結構。可是將稀疏數據進行縮放是有意義的,特別是對於量綱不一樣的特徵輸入。code

MaxAbsScaler和maxabs_scale特別適用於縮放稀疏數據。此外,scale和StandardScaler可以處理scipy.sparse矩陣做爲輸入的狀況,此時須要將with_mean設置爲False。不然默認的置中操做將會破壞數據的稀疏型,會拋出一個ValueError的錯誤,並且內存可能會被大量佔用形成內存溢出。RobustScaler不適用於稀疏數據的處理,可是它的transform方法能夠做用於稀疏數據。

注意,縮放器(scaler)容許輸入壓縮的稀疏行和稀疏列數據(見scipy.sparse.csr_matrix和scipy.sparse.csc_matrix)任何其餘的稀疏輸入都會被轉化成壓縮的稀疏行表示。爲了不沒必要要的內存佔用,建議使用CSR或者CSC表示法。 
最後,若是但願置中的數據足夠小,可使用sparse matrices的toarray方法將稀疏的輸入數據轉化爲一個數組。 
sklearn.preprocessing.maxabs_scale(X, axis=0, copy=True) 
class sklearn.preprocessing.MaxAbsScaler(copy=True) # 這是一個Transformer API

1.4 縮放帶有outlier的數據 
若是數據中含有異常值,那麼使用均值和方差縮放數據的效果並很差。這種狀況下,可使用robust_scale和RobustScaler。 
sklearn.preprocessing.robust_scale(X, axis=0, with_centering=True, with_scaling=True, quantile_range=(25.0, 75.0), copy=True)[source] 
class sklearn.preprocessing.RobustScaler(with_centering=True, with_scaling=True, quantile_range=(25.0, 75.0), copy=True) # 這是一個Transformer API

這兩種方法計算的數據的均值和範圍更加可靠。 
Scale和StandardScaler可以用於一維數組,這對於縮放回歸過程當中的的目標/響應變量十分有用。

1.5 置中核矩陣 
若是有一個核矩陣(在函數phi定義的特徵空間上計算點積獲得),那麼KernelCenterer可以轉移核矩陣,使得在函數phi定義的特徵空間中的內積構造的核矩陣可以轉移到移除均值後的空間中。

2. 規範化(Normalization) 
規範化是指將樣本縮放成單位向量。若是須要使用二次方程,好比點積或者其餘核方法計算樣本對之間的類似性,那麼這一過程很是有用。 
這一假設是經常使用於文本分類和內容聚類的向量空間模型的基礎。 
normalize函數提供了一個處理單個結構相似數組的數據集的快速簡單的方法,可使用1範數l1或者2範數l2。

>>> x=[[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]] >>> x_normalized = preprocessing.normalize(x, norm='l2') >>> x_normalized array([[ 0.40824829, -0.40824829, 0.81649658], [ 1. , 0. , 0. ], [ 0. , 0.70710678, -0.70710678]])

 

相似的,preprocessing模塊也提供了一個實體類Normalizer,可以利用Transformer API執行相同的操做(雖然fit方法這裏是沒有意義的,由於規範化是對於每一個樣本獨立進行的)。

>>> x=[[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]] >>> normalizer = preprocessing.Normalizer().fit(x) >>> normalizer Normalizer(copy=True, norm='l2') >>> normalizer.transform(x) array([[ 0.40824829, -0.40824829, 0.81649658], [ 1. , 0. , 0. ], [ 0. , 0.70710678, -0.70710678]]) >>> normalizer.transform([[1., -1., 0]]) array([[ 0.70710678, -0.70710678, 0. ]])

 

對於稀疏的輸入數據,normalize和Normalizer能夠接受非稀疏數組類型和稀疏矩陣類型左右的輸入。稀疏數據將被轉化爲壓縮的稀疏行表示法。

3. 二值化 
3.1 特徵二值化 
這一過程就是定義一個閾值,而後獲得數值特徵的布爾值。這對於假設輸入數據服從多元伯努利分佈的機率估計量很是有用。這在文本處理過程當中也很是常見。 
實力類Binarizer能夠實現這一過程。一樣的,fit函數沒有意義。

>>> x=[[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]] >>> binarizer = preprocessing.Binarizer().fit(x) >>> binarizer Binarizer(copy=True, threshold=0.0) >>> binarizer.transform(x) array([[ 1., 0., 1.], [ 1., 0., 0.], [ 0., 1., 0.]]) >>> binarizer = preprocessing.Binarizer(threshold=1.1) >>> binarizer.transform(x) array([[ 0., 0., 1.], [ 1., 0., 0.], [ 0., 0., 0.]])

 

此外,在不必使用Transformer API時,也提供了binarize方法進行轉化。binarize和Binarizer均可以處理稀疏輸入。

4. 分類特徵編碼 
當某些特徵不是連續取值而是分類數據時,就須要對分類特徵進行編碼,好比人的性別有[「男」, 「女」]之分,國籍能夠是[「中國」, 「英國」, 「美國」],使用的瀏覽器可能爲[「FireFox」, 「Chrome」, 「Safari」, 「IE」]。這樣的特徵能夠分別用不一樣的整數進行標記,好比[「男」, 「女」]分表表示成[0, 1],[「中國」, 「英國」, 「美國」]分別表示成[0, 1, 2],[「FireFox」, 「Chrome」, 「Safari」, 「IE」]表示爲[0, 1, 2, 3]

可是,這種整數表示方法不能直接用於scikit-learn估計量,由於這一算法包但願輸入是連續的變量,所以就會將不一樣的種類理解成不一樣的大小。解決這一問題的一個方法是使用one-of-K或者one-hot編碼,經過OneHotEncoder實現。這一估計量將每一個含有m個取值的分類特徵轉化爲m個二值特徵,其中只有一個處於active狀態。

>>> enc = preprocessing.OneHotEncoder() >>> enc.fit([[0,0,3],[1,1,0],[0,2,1],[1,0,2]]) OneHotEncoder(categorical_features='all', dtype=<class 'float'>, handle_unknown='error', n_values='auto', sparse=True) >>> enc.transform([[0,1,3]]).toarray() array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]]) # 一共9位 >>> # feature1只有0,1兩個取值,所以是兩位 >>> # feature2有0,1,2三個取值,所以是三位 >>> # feature3有0,1,2,3四個取值,所以是四位

 

每一個特徵的分類個數默認上根據輸入數據集自動計算。可是也能夠經過設置參數n_values進行人爲設定。在上述例子中,三個分類屬性的可選值數量分別爲2,3,4。特別是當訓練數據集在某個可能取值上沒有訓練樣本時,須要人爲制定分類數量。例如:

>>> enc = preprocessing.OneHotEncoder(n_values=[2, 3, 4]) >>> enc.fit([[1,2,3],[0,2,0]]) OneHotEncoder(categorical_features='all', dtype=<class 'float'>, handle_unknown='error', n_values=[2, 3, 4], sparse=True) >>> enc.transform([[1 , 0, 0]]).toarray() array([[ 0., 1., 1., 0., 0., 1., 0., 0., 0.]])

5. 推定缺失數據 
不少狀況下,真實的數據集中會存在缺失值,此時數據集中會採用空格、NaNs或者其餘佔位符進行記錄。可是scikit-learn的輸入變量應該爲數值型,此時須要對缺失值進行處理。一種策略是將存在缺失值的整條記錄直接刪除。可是這樣作可能會丟失一部分有價值的信息。更好的一種方法是推定缺失數據,例如根據已經數據推算缺失的數據。

Imputer類可以提供一些處理缺失值的基本策略,例如使用缺失值所處的一行或者一列的均值、中位數或者出現頻率最高的值做爲缺失數據的取值。下邊舉一個使用缺失值所處行的均值做爲缺失值的例子:

>>> 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. ]]

Imputer也支持稀疏矩陣做爲輸入:

>>> import scipy.sparse as sp >>> X = sp.csc_matrix([[1, 2], [0, 3], [7, 6]]) >>> imp = Imputer(missing_values=0, strategy='mean', axis=0) >>> imp.fit(X) Imputer(axis=0, copy=True, missing_values=0, strategy='mean', verbose=0) >>> X_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]]) >>> print(imp.transform(X_test)) [[ 4. 2. ] [ 6. 3.666...] [ 7. 6. ]]

6. 產生多項式特徵 
在輸入數據存在非線性特徵時,這一操做對增長模型的複雜度十分有用。一種常見的用法是生成多項式特徵,可以獲得特徵的高階項和相互做用項。利用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.]])

 

此時,特徵向量X=(X1, X2)被轉化爲(1, X1, X2, X1^2, X1X2, X2^2)。 
在有些狀況下,咱們只須要相互做用項,此時能夠經過設定interaction_only=True實現:

>>> X = np.arange(9).reshape(3, 3) >>> X array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) >>> poly = PolynomialFeatures(degree=3, interaction_only=True) >>> poly.fit_transform(X) array([[ 1., 0., 1., 2., 0., 0., 2., 0.], [ 1., 3., 4., 5., 12., 15., 20., 60.], [ 1., 6., 7., 8., 42., 48., 56., 336.]])

 

這裏,X=(X1, X2, X3)被轉化爲to (1, X1, X2, X3, X1X2, X1X3, X2X3, X1X2X3)。

多項式特徵常常用於使用多項式核函數的核方法(好比SVC和KernelPCA)。

7. 定製轉換器 
咱們常常但願將一個Python的函數轉變爲transformer,用於數據清洗和預處理。可使用FunctionTransformer方法將任意函數轉化爲一個Transformer。好比,構建一個對數log的Transformer:

>>> import numpy as np >>> from sklearn.preprocessing import FunctionTransformer >>> transformer = FunctionTransformer(np.log1p) >>> X = np.array([[0, 1], [2, 3]]) >>> transformer.transform(X) array([[ 0. , 0.69314718], [ 1.09861229, 1.38629436]])
相關文章
相關標籤/搜索