機器學習基礎與實踐(二)----數據轉換

------------------------------------本博客全部內容以學習、研究和分享爲主,如需轉載,請聯繫本人,標明做者和出處,而且是非商業用途,謝謝!--------------------------------html

系列目錄:git

  1 第一部分 模型的評估與數據處理
  2 
  3 機器學習基礎與實踐(一)----數據清洗
  4 
  5 機器學習基礎與實踐(二)----數據轉換
  6 
  7 機器學習基礎與實踐(三)----數據降維
  8 
  9  
 10 
 11 第二部分 特徵工程
 12 
 13 機器學習基礎與實踐(四)----特徵選擇
 14 
 15 機器學習基礎與實踐(五)----特徵提取
 16 
 17 機器學習基礎與實踐(六)----模型選擇與評估
 18 
 19  
 20 
 21 第三部分 算法基礎之有監督算法
 22 
 23 機器學習基礎與實踐(七)----廣義線性模型
 24 
 25 機器學習基礎與實踐(八)----最小二乘法
 26 
 27 機器學習基礎與實踐(九)----LDA
 28 
 29 機器學習基礎與實踐(十)----SGD
 30 
 31 機器學習基礎與實踐(十一)----K近鄰
 32 
 33 機器學習基礎與實踐(十二)----高斯過程
 34 
 35 機器學習基礎與實踐(十三)----決策樹(ID3,C4.5,C5.0,CART)
 36 
 37 機器學習基礎與實踐(十四)----樸素貝葉斯
 38 
 39 機器學習基礎與實踐(十五)----支持向量機
 40 
 41 機器學習基礎與實踐(十六)----集成學習(Bagging,RF,AdaBoost,Gradient Tree Boosting,Voting Classifier)
 42 
 43 機器學習基礎與實踐(十七)----感知機模型
 44 
 45 機器學習基礎與實踐(十八)----多分類算法
 46 
 47  
 48 
 49 第四部分 算法基礎之無監督算法
 50 
 51 機器學習基礎與實踐(十九)----K-means
 52 
 53 機器學習基礎與實踐(二十)----Affinity propagation
 54 
 55 機器學習基礎與實踐(二十一)----Mean-shift
 56 
 57 機器學習基礎與實踐(二十二)----Spectral clustering
 58 
 59 機器學習基礎與實踐(二十三)----Ward hierachical
 60 
 61 機器學習基礎與實踐(二十四)----Agglomerative clustering
 62 
 63 機器學習基礎與實踐(二十五)----DBSCAN
 64 
 65 機器學習基礎與實踐(二十六)----Gaussian mixtures
 66 
 67 機器學習基礎與實踐(二十七)----Birch
 68 
 69  
 70 
 71 第五部分 算法基礎之推薦算法
 72 
 73 機器學習基礎與實踐(二十八)----類似度計算
 74 
 75 機器學習基礎與實踐(二十九)----Arules關聯規則
 76 
 77 機器學習基礎與實踐(三十)----Fp-Growth
 78 
 79 機器學習基礎與實踐(三十一)----User-based or Item-based
 80 
 81  
 82 
 83 第六部分 算法基礎之半監督模型
 84 
 85 機器學習基礎與實踐(三十二)----Label Propagation
 86 
 87  
 88 
 89 第七部分 算法基礎之其餘模型
 90 
 91  機器學習基礎與實踐(三十三)----機率圖模型
 92 
 93 機器學習基礎與實踐(三十四)----最大熵模型
 94 
 95 機器學習基礎與實踐(三十五)----規則學習
 96 
 97 機器學習基礎與實踐(三十六)----強化學習
 98 
 99 機器學習基礎與實踐(三十七)----條件隨機場
100 
101 機器學習基礎與實踐(三十八)----保序迴歸(Isotonic regression)
102 
103 機器學習基礎與實踐(三十九)----Probability calibration
Contents

本文目錄:github

一.標準化的緣由
二.適用狀況
三.三種數據變換方法的含義與應用
四.具體方法及代碼
一)標準化
  1.1 scale----零均值單位方差
      1.2 StandardScaler
二)歸一化
     2.1 MinMaxScaler(最小最大值標準化)
     2.2 MaxAbsScaler(絕對值最大標準化)
     2.3 對稀疏數據進行標準化
     2.4 對離羣點進行標準化
三)正則化
  3.1  L一、L2正則化
四)二值化
  4.1特徵二值化
五)對類別特徵進行編碼
六)缺失值的插補
七)生成多項式特徵 
八)自定義轉換
 

 

正文:算法

一.標準化的緣由
    一般狀況下是爲了消除量綱的影響。譬如一個百分制的變量與一個5分值的變量在一塊兒怎麼比較?只有經過數據標準化,都把它們標準到同一個標準時才具備可比性,通常標準化採用的是Z標準化,即均值爲0,方差爲1,固然也有其餘標準化,好比0--1標準化等等,可根據本身的數據分佈狀況和模型來選擇
 
二.適用狀況
  看模型是否具備伸縮不變性。
     不是全部的模型都必定須要標準化,有些模型對量綱不一樣的數據比較敏感,譬如SVM等。當各個維度進行不均勻伸縮後,最優解與原來不等價,這樣的模型,除非原始數據的分佈範圍原本就不叫接近,不然 必須進行標準化,以避免模型參數被分佈範圍較大或較小的數據主導。可是若是模型在各個維度進行不均勻伸縮後,最優解與原來等價,例如logistic regression等,對於這樣的模型,是否標準化理論上不會改變最優解。可是,因爲實際求解每每使用迭代算法,若是目標函數的形狀太「扁」,迭代算法可能收斂得很慢甚至不收斂。因此對於具備伸縮不變性的模型, 最好也進行數據標準化。
 
三.三種數據變換方法的含義與應用
  Rescaling(重縮放/歸一化):一般是指增長或者減小一個常數,而後乘以/除以一個常數,來改變數據的衡量單位。例如:將溫度的衡量單位從攝氏度轉化爲華氏溫度。

  Normalizing(正則化):一般是指除以向量的範數。例如:將一個向量的歐氏長度等價於1 。在神經網絡中,「正則化」一般是指將向量的範圍重縮放至最小化或者必定範圍,使全部的元素都在[0,1]範圍內。一般用於文本分類或者文本聚類中。數組

  Standardizing(標準化):一般是爲了消除不一樣屬性或樣方間的不齊性,使同同樣方內的不一樣屬性間或同一屬性在不一樣樣方內的方差減少。例如:若是一個向量包含高斯分佈的隨機值,你可能會經過除以標準誤差來減小均值,而後得到零均值單位方差的「標準正態」隨機變量。瀏覽器

  那麼問題是,當咱們在訓練模型的時候,必定要對數據進行變換嗎?這得視狀況而定。不少人對多層感知機有個誤解,認爲輸入的數據必須在[0,1]這個範圍內。雖然標準化後在訓練模型效果會更好,但實際上並無這個要求。可是最好使輸入數據中心集中在0周圍,因此把數據縮放到[0,1]其實並非一個好的選擇。網絡

  若是你的輸出激活函數的範圍是[0,1](sigmoid函數的值域),那你必須保證你的目標值也在這個範圍內。但一般請款下,咱們會使輸出激活函數的範圍適應目標函數的分佈,而不是讓你的數據來適應激活函數的範圍。dom

  當咱們使用激活函數的範圍爲[0,1]時,有些人可能更喜歡把目標函數縮放到[0.1,0.9]這個範圍。我懷疑這種小技巧的之因此流行起來是由於反向傳播的標準化太慢了致使的。但用這種方法可能會使輸出的後驗機率值不對。若是你使用一個有效的訓練算法的話,徹底不須要用這種小技巧,也沒有必要去避免溢出(overflow)機器學習

 
四.具體方法及代碼
一)標準化
  1.1 scale----零均值單位方差
 1 from sklearn import preprocessing 
 2 import numpy as np  
 3 #raw_data
 4 X = np.array([[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]])  
 5 X_scaled = preprocessing.scale(X) 
 6 #output
 7 X_scaled = [[ 0.         -1.22474487  1.33630621]
 8              [ 1.22474487  0.         -0.26726124]
 9              [-1.22474487  1.22474487 -1.06904497]]
10 #scaled以後的數據零均值,單位方差
11 X_scaled.mean(axis=0)  # column mean: array([ 0.,  0.,  0.])  
12 X_scaled.std(axis=0)  #column standard deviation: array([ 1.,  1.,  1.])

 

  1.2 StandardScaler----計算訓練集的平均值和標準差,以便測試數據集使用相同的變換ide

 1 scaler = preprocessing.StandardScaler().fit(X) 
 2 #out:
 3  StandardScaler(copy=True, with_mean=True, with_std=True)
 4 scaler.mean_  
 5 #out: 
 6 array([ 1.,  0. ,  0.33333333])  
 7 scaler.std_ 
 8 #out:
 9  array([ 0.81649658,  0.81649658,  1.24721913]) 
10 #測試將該scaler用於輸入數據,變換以後獲得的結果同上
11 scaler.transform(X)
12  #out: 
13 array([[ 0., -1.22474487,  1.33630621],  [ 1.22474487, 0. , -0.26726124],  [-1.22474487,1.22474487, -1.06904497]])  
14 scaler.transform([[-1., 1., 0.]])  
15 #scale the new data, out: 
16 array([[-2.44948974,  1.22474487, -0.26726124]])

注:1)若設置with_mean=False 或者 with_std=False,則不作centering 或者scaling處理。

   2)scale和StandardScaler能夠用於迴歸模型中的目標值處理。

 

二)歸一化----將數據特徵縮放至某一範圍(scalingfeatures to a range)

  另一種標準化方法是將數據縮放至給定的最小值與最大值之間,一般是0與1之間,可用MinMaxScaler實現。或者將最大的絕對值縮放至單位大小,可用MaxAbsScaler實現。

使用這種標準化方法的緣由是,有時數據集的標準差很是很是小,有時數據中有不少不少零(稀疏數據)須要保存住0元素。

   2.1 MinMaxScaler(最小最大值標準化)

  公式:X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0)) ; 

     X_scaler = X_std/ (max - min) + min

 
 1 #例子:將數據縮放至[0, 1]間
 2 X_train = np.array([[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]])
 3 min_max_scaler = preprocessing.MinMaxScaler() 
 4 X_train_minmax = min_max_scaler.fit_transform(X_train)  
 5 #out: 
 6 array([[ 0.5       ,  0.        ,  1.        ], 
 7 [ 1.        ,  0.5       ,  0.33333333],        
 8 [ 0.        ,  1.        ,  0.        ]])
 9 #將上述獲得的scale參數應用至測試數據
10 X_test = np.array([[ -3., -1., 4.]])  
11 X_test_minmax = min_max_scaler.transform(X_test) #out: array([[-1.5 ,  0. , 1.66666667]])
12 #能夠用如下方法查看scaler的屬性
13 min_max_scaler.scale_        #out: array([ 0.5 ,  0.5,  0.33...])
14 min_max_scaler.min_         #out: array([ 0.,  0.5,  0.33...])

 

   2.2 MaxAbsScaler(絕對值最大標準化)

  與上述標準化方法類似,可是它經過除以最大值將訓練集縮放至[-1,1]。這意味着數據已經以0爲中心或者是含有很是很是多0的稀疏數據。

 1 X_train = np.array([[ 1., -1.,  2.],
 2                      [ 2.,  0.,  0.],
 3                     [ 0.,  1., -1.]])
 4 max_abs_scaler = preprocessing.MaxAbsScaler()
 5 X_train_maxabs = max_abs_scaler.fit_transform(X_train)
 6 # out: 
 7 array([[ 0.5, -1.,  1. ], [ 1. , 0. ,  0. ],       [ 0. ,  1. , -0.5]])
 8 X_test = np.array([[ -3., -1.,  4.]])
 9 X_test_maxabs = max_abs_scaler.transform(X_test) 
10 #out: 
11 array([[-1.5, -1. ,  2. ]])
12 max_abs_scaler.scale_  
13 #out: 
14 array([ 2.,  1.,  2.])

  其實在scale模塊裏,也提供了這兩種方法: minmax_scalemaxabs_scale

 

     2.3 對稀疏數據進行標準化

  對稀疏數據進行中心化會破壞稀疏數據的結構,這樣作沒什麼意義。可是咱們能夠對稀疏數據的輸入進行標準化,尤爲是特徵在不一樣的標準時。MaxAbsScaler 和 maxabs_scale是專門爲稀疏數據設計的,也是經常使用的方法。可是scale 和 StandardScaler只接受scipy.sparse的矩陣做爲輸入,而且必須設置with_centering=False。不然會出現 ValueError且破壞稀疏性,並且還會無心中分配更多的內存致使內存崩潰。RobustScaler不適用於稀疏數據的輸入,可是你能夠用 transform 方法。

  scalers接受壓縮的稀疏行(Compressed Sparse Rows)和壓縮的稀疏列(Compressed Sparse Columns)的格式(具體參考scipy.sparse.csr_matrix 和scipy.sparse.csc_matrix)。其餘的稀疏格式會被轉化成壓縮的稀疏行(Compressed Sparse Rows)格式。爲了不這種沒必要要的內存拷貝,推薦使用CSR或者CSC的格式。若是數據很小,能夠在稀疏矩陣上運用toarray 方法。

 

     2.4 對離羣點進行標準化

  若是你的數據有離羣點(上一篇咱們提到過),對數據進行均差和方差的標準化效果並很差。這種狀況你可使用robust_scale 和 RobustScaler 做爲替代。它們有對數據中心化和數據的縮放魯棒性更強的參數。

 

三)正則化
  3.1  L一、L2正則化
 1 x=np.array([[1.,-1.,2.],
 2             [2.,0.,0.],
 3             [0.,1.,-1.]])
 4 x_normalized=preprocessing.normalize(x,norm='l2')
 5 print(x_normalized)
 6 
 7 # 可使用processing.Normalizer()類實現對訓練集和測試集的擬合和轉換
 8 normalizer=preprocessing.Normalizer().fit(x)
 9 print(normalizer)
10 normalizer.transform(x)

 

注:稀疏數據輸入:

normalize 和 Normalizer 既接受稠密數據(dense array-like),也接受稀疏矩陣(from scipy.sparse)做爲輸入

稀疏數據須要轉換成壓縮的稀疏行(Compressed Sparse Rows)格式(詳見scipy.sparse.csr_matrix),爲了不沒必要要的內存拷貝,推薦使用CSR。

 

四)二值化
  4.1特徵二值化

特徵二值化是把數值特徵轉化成布爾值的過程。這個方法對符合多變量伯努利分佈的輸入數據進行預測機率參數頗有效。詳細能夠見這個例子sklearn.neural_network.BernoulliRBM.

此外,在文本處理中也常常會遇到二值特徵值(極可能是爲了簡化機率推理),即便在實際中正則化後的詞頻或者TF-IDF的值一般只比未正則化的效果好一點點。

對於 NormalizerBinarizer工具類一般是在Pipeline階段(sklearn.pipeline.Pipeline)的前期過程會用到。下面舉一個具體的例子:

 1 #input
 2 X = [[ 1., -1.,  2.],
 3          [ 2.,  0.,  0.],
 4          [ 0.,  1., -1.]]
 5 #binary
 6 binarizer = preprocessing.Binarizer().fit(X)  # fit does nothing
 7 binarizer
 8 Binarizer(copy=True, threshold=0.0)
 9 #transform
10 binarizer.transform(X)
11 #out:
12 array([[ 1.,  0.,  1.],
13        [ 1.,  0.,  0.],
14        [ 0.,  1.,  0.]])     
15 
16 # 調整閾值
17 binarizer = preprocessing.Binarizer(threshold=1.1)
18 binarizer.transform(X)
19 #out:
20 array([[ 0.,  0.,  1.],
21        [ 1.,  0.,  0.],
22        [ 0.,  0.,  0.]])
23   

 

 

注:稀疏數據輸入:

binarize 和 Binarizer 既接受稠密數據(dense array-like),也接受稀疏矩陣(from scipy.sparse)做爲輸入

稀疏數據須要轉換成壓縮的稀疏行(Compressed Sparse Rows)格式(詳見scipy.sparse.csr_matrix),爲了不沒必要要的內存拷貝,推薦使用CSR。

 

五)對類別特徵進行編碼

   咱們常常會遇到一些類別特徵,這些特徵不是離散型的數值,而是這樣的:["男性","女性"],["來自歐洲","來自美國","來自亞洲"],["使用Firefox瀏覽器","使用Chrome瀏覽器","使用Safari瀏覽器","使用IE瀏覽器"]等等。這種類型的特徵能夠被編碼爲整型(int),如["男性","來自美國","使用IE瀏覽器"]能夠表示成[0,1,3],["女性","來自亞洲","使用Chrome瀏覽器"]能夠表示成[1,2,1]。這些整數式的表示不能直接做爲sklearn的參數,由於咱們須要的是連續型的輸入,並且咱們一般是有序的翻譯這些特徵,而不是全部的特徵都是有序化的(譬如瀏覽器就是按人工排的序列)。

   將這些類別特徵轉化成sklearn參數中可使用的方法是:使用one-of-K或者one-hot編碼(獨熱編碼OneHotEncoder)。它能夠把每個有m種類別的特徵轉化成m中二值特徵。舉例以下:

1 enc = preprocessing.OneHotEncoder()
2 #input
3 enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  
4 OneHotEncoder(categorical_features='all', dtype=<... 'float'>,handle_unknown='error', n_values='auto', sparse=True)
5 #transform
6 enc.transform([[0, 1, 3]]).toarray()
7 #out
8 array([[ 1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.]])

  默認狀況下,特徵的類別數量是從數據集裏自動判斷出來的。固然,你也能夠用n_values這個參數。咱們剛剛舉的例子中有兩種性別,三種地名和四種瀏覽器,當咱們fit以後就能夠將咱們的數據轉化爲數值了。從結果中來看,第一個數字表明性別([0,1]表明男性,女性),第二個數字表明地名([0,1,2]表明歐洲、美國、亞洲),最後一個數字表明瀏覽器([3,0,1,2]表明四種瀏覽器)

  此外,字典格式也能夠編碼: Loading features from dicts

  OneHotEncoder參數:class sklearn.preprocessing.OneHotEncoder(n_values='auto'categorical_features='all'dtype=<class 'float'>sparse=Truehandle_unknown='error')

n_values : ‘auto’, int or array of ints

每一個特徵的數量

    • ‘auto’ : 從訓練數據的範圍中獲得
    • int : 全部特徵的最大值(number)
    • array : 每一個特徵的最大值(number)

categorical_features: 「all」 or array of indices or mask :

肯定哪些特徵是類別特徵

    • ‘all’ (默認): 全部特徵都是類別特徵,意味着全部特徵都要進行OneHot編碼
    • array of indices: 類別特徵的數組索引
    • mask: n_features 長度的數組,切dtype = bool

  非類別型特徵一般會放到矩陣的右邊

dtype : number type, default=np.float

  輸出數據的類型

sparse : boolean, default=True

  設置True會返回稀疏矩陣,不然返回數組

handle_unknown : str, ‘error’ or ‘ignore’

  當一個不明類別特徵出如今變換中時,報錯仍是忽略

 

六)缺失值的插補

  上篇咱們講了五種方法來解決缺失值的問題,其實sklearn裏也有一個工具Imputer能夠對缺失值進行插補。Imputer類能夠對缺失值進行均值插補、中位數插補或者某行/列出現的頻率最高的值進行插補,也能夠對不一樣的缺失值進行編碼。而且支持稀疏矩陣。

 1 import numpy as np
 2 from sklearn.preprocessing import Imputer
 3 #用均值插補缺失值
 4 imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
 5 imp.fit([[1, 2], [np.nan, 3], [7, 6]])
 6 Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
 7 X = [[np.nan, 2], [6, np.nan], [7, 6]]
 8 print(imp.transform(X))                           
 9 [[ 4.          2.        ]
10  [ 6.          3.666...]
11  [ 7.          6.        ]]
12 
13 #對稀疏矩陣進行缺失值插補
14 import scipy.sparse as sp
15 X = sp.csc_matrix([[1, 2], [0, 3], [7, 6]])
16 imp = Imputer(missing_values=0, strategy='mean', axis=0)
17 imp.fit(X)
18 Imputer(axis=0, copy=True, missing_values=0, strategy='mean', verbose=0)
19 X_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]])
20 print(imp.transform(X_test))                      
21 [[ 4.          2.        ]
22  [ 6.          3.666...]
23  [ 7.          6.        ]]

  在稀疏矩陣中,缺失值被編碼爲0存儲爲矩陣中,這種格式是適合於缺失值比非缺失值多得多的狀況。此外,Imputer類也能夠用於Pipeline中

 

  Imputor類的參數:class sklearn.preprocessing.Imputer(missing_values='NaN'strategy='mean'axis=0verbose=0copy=True)

missing_values : int或"NaN",默認NaN(String類型)

strategy : string, 默認爲mean,可選則mean、median、most_frequent

axis :int, 默認爲0(axis = 0,對列進行插值;axis= 1,對行進行插值)

verbose : int, 默認爲0

copy : boolean, 默認爲True

  True:會建立一個X的副本

  False:在任何合適的地方都會進行插值。

  可是如下四種狀況,計算設置的copy = Fasle,也會建立一個副本:

  1.X不是浮點型數組

  2.X是稀疏矩陣,並且miss_value = 0

  3.axis= 0,X被編碼爲CSR矩陣

       4.axis= 1,X被編碼爲CSC矩陣

 

  舉個實例(在用隨機森林算法以前先用Imputer類進行處理):

 1 import numpy as np
 2 
 3 from sklearn.datasets import load_boston
 4 from sklearn.ensemble import RandomForestRegressor
 5 from sklearn.pipeline import Pipeline
 6 from sklearn.preprocessing import Imputer
 7 from sklearn.cross_validation import cross_val_score
 8 
 9 rng = np.random.RandomState(0)
10 
11 dataset = load_boston()
12 X_full, y_full = dataset.data, dataset.target
13 n_samples = X_full.shape[0]
14 n_features = X_full.shape[1]
15 
16 # Estimate the score on the entire dataset, with no missing values
17 estimator = RandomForestRegressor(random_state=0, n_estimators=100)
18 score = cross_val_score(estimator, X_full, y_full).mean()
19 print("Score with the entire dataset = %.2f" % score)
20 
21 # Add missing values in 75% of the lines
22 missing_rate = 0.75
23 n_missing_samples = np.floor(n_samples * missing_rate)
24 missing_samples = np.hstack((np.zeros(n_samples - n_missing_samples,
25                                       dtype=np.bool),
26                              np.ones(n_missing_samples,
27                                      dtype=np.bool)))
28 rng.shuffle(missing_samples)
29 missing_features = rng.randint(0, n_features, n_missing_samples)
30 
31 # Estimate the score without the lines containing missing values
32 X_filtered = X_full[~missing_samples, :]
33 y_filtered = y_full[~missing_samples]
34 estimator = RandomForestRegressor(random_state=0, n_estimators=100)
35 score = cross_val_score(estimator, X_filtered, y_filtered).mean()
36 print("Score without the samples containing missing values = %.2f" % score)
37 
38 # Estimate the score after imputation of the missing values
39 X_missing = X_full.copy()
40 X_missing[np.where(missing_samples)[0], missing_features] = 0
41 y_missing = y_full.copy()
42 estimator = Pipeline([("imputer", Imputer(missing_values=0,
43                                           strategy="mean",
44                                           axis=0)),
45                       ("forest", RandomForestRegressor(random_state=0,
46                                                        n_estimators=100))])
47 score = cross_val_score(estimator, X_missing, y_missing).mean()
48 print("Score after imputation of the missing values = %.2f" % score)

 

  結果:

Score with the entire dataset = 0.56
Score without the samples containing missing values = 0.48
Score after imputation of the missing values = 0.55

 

七)生成多項式特徵 

  在輸入數據中增長非線性特徵能夠有效的提升模型的複雜度。簡單且經常使用的方法就是使用多項式特徵(polynomial features),能夠獲得特徵的高階交叉項:

 1 import numpy as np
 2 from sklearn.preprocessing import PolynomialFeatures
 3 X = np.arange(6).reshape(3, 2)
 4 X                                                 
 5 array([[0, 1],
 6        [2, 3],
 7        [4, 5]])
 8 poly = PolynomialFeatures(2)
 9 poly.fit_transform(X)                             
10 array([[  1.,   0.,   1.,   0.,   0.,   1.],
11        [  1.,   2.,   3.,   4.,   6.,   9.],
12        [  1.,   4.,   5.,  16.,  20.,  25.]])

  

  然而有時候咱們只須要特徵的交叉項,能夠設置interaction_only=True來獲得:

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

    這個方法可能你們在工做中比較少見,但世界上它常常用於核方法中,如選擇多項式核時 ( sklearn.svm.SVCsklearn.decomposition.KernelPCA)

 

八)自定義轉換

  若是以上的方法以爲都不夠,譬如你想用對數據取對數,能夠本身用 FunctionTransformer自定義一個轉化器,而且能夠在Pipeline中使用

1 import numpy as np
2 from sklearn.preprocessing import FunctionTransformer
3 transformer = FunctionTransformer(np.log1p)#括號內的就是自定義函數
4 X = np.array([[0, 1], [2, 3]])
5 transformer.transform(X)
6 array([[ 0.        ,  0.69314718],
7        [ 1.09861229,  1.38629436]])

 

  告訴你怎麼用:

  若是你在作一個分類任務時,發現第一主成分與這個不相關,你能夠用FunctionTransformer把第一列除去,剩下的列用PCA:

 1 import matplotlib.pyplot as plt
 2 import numpy as np
 3 
 4 from sklearn.cross_validation import train_test_split
 5 from sklearn.decomposition import PCA
 6 from sklearn.pipeline import make_pipeline
 7 # from sklearn.preprocessing import FunctionTransformer
 8 # 若是報錯ImportError: cannot import name FunctionTransformer,可使用下面的語句
 9 from sklearn.preprocessing import *
10 
11 
12 def _generate_vector(shift=0.5, noise=15):
13     return np.arange(1000) + (np.random.rand(1000) - shift) * noise
14 
15 
16 def generate_dataset():
17     """
18     This dataset is two lines with a slope ~ 1, where one has
19     a y offset of ~100
20     """
21     return np.vstack((
22         np.vstack((
23             _generate_vector(),
24             _generate_vector() + 100,
25         )).T,
26         np.vstack((
27             _generate_vector(),
28             _generate_vector(),
29         )).T,
30     )), np.hstack((np.zeros(1000), np.ones(1000)))
31 
32 
33 def all_but_first_column(X):
34     return X[:, 1:]
35 
36 
37 def drop_first_component(X, y):
38     """
39     Create a pipeline with PCA and the column selector and use it to
40     transform the dataset.
41     """
42     pipeline = make_pipeline(
43         PCA(), FunctionTransformer(all_but_first_column),
44     )
45     X_train, X_test, y_train, y_test = train_test_split(X, y)
46     pipeline.fit(X_train, y_train)
47     return pipeline.transform(X_test), y_test
48 
49 
50 if __name__ == '__main__':
51     X, y = generate_dataset()
52     plt.scatter(X[:, 0], X[:, 1], c=y, s=50)
53     plt.show()
54     X_transformed, y_transformed = drop_first_component(*generate_dataset())
55     plt.scatter(
56         X_transformed[:, 0],
57         np.zeros(len(X_transformed)),
58         c=y_transformed,
59         s=50,
60     )
61     plt.show()

 

結果:

 

  寫到這裏基本上關於數據轉化的方法已經介紹的差很少了,週四寫第三篇--數據降維。寫的比較倉促,有錯誤的歡迎提出來~

相關文章
相關標籤/搜索