四、數據標準化 Scikit-learn Preprocessing

一、標準化、去均值、方差縮放(variance scaling)

1.原理介紹

   通過將屬性值按比例縮放,使之落入一個小的特定區間,如0.0~1.0,對屬性規範化。有很多數據規範化的方法,這裏我們將介紹三種:最小--最大規範化,z-score規範化,按小數定標規範化和最大絕對值縮放。

下面簡單介紹着幾種規範化的原理:

(1)最小--最大規範化

 

            最小--最大規範化對原始數據進行線性變換。假定minA和maxA分別是屬性A的最小值和最大值。最小--最大規範化通過計算:

          v'  = (v - min) /(max - min )* (new_max - new_min)  + new_min 

這樣可以將A的值映射到區間[new_min , new_max]中的v'。

(2)z-score規範化

        又稱爲零均值 規範化,將屬性A的值基於均值和方差規範化,在不知道屬性A的最小值和最大值的時候,或者是離羣值左右了最小--最大規範化時,該方法是有用的。
      v' = v - mean / std

(3)按小數定標規範化

        通過移動屬性A的小數點位置進行規範化,小數點的移動位數依賴於A的最大絕對值,由下式計算:

                                                     v' = v / 10^j

其中j是使得Max(| v' |) <1的最小整數。

例如:假定屬性A的取值範圍是-986 ~ 917。A的最大絕對值爲986.使用小數定標規範化,用1000(即j = 3)除每個數,這樣,-986就會被規範化爲-0.986,而917也會被規範化成-0.917.

(4)最大絕對值縮放

        它只通過除以每個特徵的最大值將訓練數據特徵縮放至 [-1, 1]。這就意味着,訓練數據應該是已經零中
心化或者是稀疏數據。 

2.代碼實現

(1)preprocessing.scale:(z-score規範化)

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                                          
Out[622]: 
array([[ 0.        , -1.22474487,  1.33630621],
       [ 1.22474487,  0.        , -0.26726124],
       [-1.22474487,  1.22474487, -1.06904497]])

X_scaled.mean(axis=0)  #標準化後數據的均值爲0.方差爲1
Out[623]: array([0., 0., 0.])

X_scaled.std(axis=0)
Out[624]: array([1., 1., 1.])

(2)class:`StandardScaler`

     preprocessing``模塊也提供了一個實用類:class:`StandardScaler` ,它使用 ``Transformer 接口在訓練集上計算均值和標準差,以便於在後續的測試集上進行相同的縮放.

scaler = preprocessing.StandardScaler().fit(X)

scaler
Out[626]: StandardScaler(copy=True, with_mean=True, with_std=True)

scaler.mean_                                      
Out[627]: array([1.        , 0.        , 0.33333333])

scaler.scale_                                       
Out[628]: array([0.81649658, 0.81649658, 1.24721913])

scaler.transform(X) #計算均值和標準差                           
Out[629]: 
array([[ 0.        , -1.22474487,  1.33630621],
       [ 1.22474487,  0.        , -0.26726124],
       [-1.22474487,  1.22474487, -1.06904497]])

#縮放類對象可以在新的數據上實現和訓練集相同縮放操作:
scaler.transform([[-1.,  1., 0.]])
Out[631]: array([[-2.44948974,  1.22474487, -0.26726124]])

3.特徵縮放到特定範圍:(最小--最大規範化)preprocessing.MinMaxScaler()

      另外一個可選的縮放操作是將特徵縮放至給定的最小、最大值範圍,經常是[0,1]。 或者也可以將每個特徵的最大絕對值轉換至單位大小。這兩類操作可以分別通過使用:class:`MinMaxScaler`或者:class:`MaxAbsScaler`實現。

使用這種方法的目的包括:
1、對於方差非常小的屬性可以增強其穩定性。
2、維持稀疏矩陣中爲0的條目。

X_train = np.array([[ 1., -1.,  2.],
                    [ 2.,  0.,  0.],
                    [ 0.,  1., -1.]])

min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)   #使用最小--最大規範化對原始數據進行規範化,默認映射到[0,1]

X_train_minmax
Out[677]: 
array([[0.5       , 0.        , 1.        ],
       [1.        , 0.5       , 0.33333333],
       [0.        , 1.        , 0.        ]])

#同樣的轉換實例可以被用與在訓練過程中不可見的測試數據:實現和訓練數據一致的縮放和移位操作:
X_test = np.array([[ -3., -1.,  4.]])
X_test_minmax = min_max_scaler.transform(X_test)
X_test_minmax
Out[681]: array([[-1.5       ,  0.        ,  1.66666667]])

##你也可以通過查看縮放器(scaler)的屬性,來觀察在訓練集中學習到的轉換操作的基本性質:
min_max_scaler.scale_                             
Out[683]: array([0.5       , 0.5       , 0.33333333])

min_max_scaler.min_                               
Out[684]: array([0.        , 0.5       , 0.33333333])

#如果:class:MinMaxScaler`被提供了一個精確的``feature_range=(min, max)`,完整的公式是:
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_scaled = X_std * (max - min) + min
###自定義縮放的範圍
min_max_scaler = preprocessing.MinMaxScaler(feature_range=(1, 2))
X_train_minmax = min_max_scaler.fit_transform(X_train) 
X_train_minmax
Out[689]: 
array([[1.5       , 1.        , 2.        ],
       [2.        , 1.5       , 1.33333333],
       [1.        , 2.        , 1.        ]])

4.最大絕對值縮放

    MaxAbsScaler 工作原理非常相似,但是它只通過除以每個特徵的最大值將訓練數據特徵縮放至 [-1, 1]。這就意味着,訓練數據應該是已經零中心化或者是稀疏數據。 例子::用先前例子的數據實現最大絕對值縮放操作:

X_train = np.array([[ 1., -1.,  2.],
                    [ 2.,  0.,  0.],
                    [ 0.,  1., -1.]])

max_abs_scaler = preprocessing.MaxAbsScaler()

X_train_maxabs = max_abs_scaler.fit_transform(X_train)

X_train_maxabs                # doctest +NORMALIZE_WHITESPACE^
Out[693]: 
array([[ 0.5, -1. ,  1. ],
       [ 1. ,  0. ,  0. ],
       [ 0. ,  1. , -0.5]])

X_test = np.array([[ -3., -1.,  4.]])

X_test_maxabs = max_abs_scaler.transform(X_test)

X_test_maxabs                 
Out[696]: array([[-1.5, -1. ,  2. ]])

max_abs_scaler.scale_  
Out[697]: array([2., 1., 2.])

二、正則化(Normalization)

     正則化的過程是將每個樣本縮放到單位範數(每個樣本點的範數爲1),如果後面要使用如二次型(點積)或者其他和方法計算兩個樣本之間的相似性,這個方法會很有用。

    Normalization主要思想是對每個樣本計算其P-範數,然後對該樣本中每個元素初一該範數,這樣處理的結果是使得每個處理後的樣本的p-範數(|1 - norm|,|2 - norm|)等於1.

           p-範數的計算公式:||X||p=(|x1|^p+|x2|^p+...+|xn|^p)^1/p

該方法主要應用於文本分類和聚類中。例如,對於兩個TF-IDF向量的I2-norm進行點積,就可以得到這兩個向量的餘弦相似性。

方法1:使用sklearn.preprocessing.normalize()函數

X = [[ 1., -1.,  2.],
    [ 2.,  0.,  0.],
    [ 0.,  1., -1.]]

X_normalized = preprocessing.normalize(X, norm='l2')

X_normalized  
Out[700]: 
array([[ 0.40824829, -0.40824829,  0.81649658],
       [ 1.        ,  0.        ,  0.        ],
       [ 0.        ,  0.70710678, -0.70710678]])

方法2:sklearn.preprocessing.StandardScaler類

normalizer = preprocessing.Normalizer().fit(X)  # fit函數沒有任何效果

normalizer
Out[702]: Normalizer(copy=True, norm='l2')

normalizer.transform(X)                            
Out[703]: 
array([[ 0.40824829, -0.40824829,  0.81649658],
       [ 1.        ,  0.        ,  0.        ],
       [ 0.        ,  0.70710678, -0.70710678]])

normalizer.transform([[-1.,  1., 0.]])   
Out[704]: array([[-0.70710678,  0.70710678,  0.        ]])

三、二值化(Binarization)

    特徵的二值化主要是爲了將數據特徵轉變成boolean變量。在sklearn中,sklearn.preprocessing.Binarizer函數可以實現這一功能。實例如下:

X = [[ 1., -1.,  2.],
     [ 2.,  0.,  0.],
     [ 0.,  1., -1.]]

binarizer = preprocessing.Binarizer().fit(X)  # fit does nothing

binarizer
Out[707]: Binarizer(copy=True, threshold=0.0)

binarizer.transform(X)
Out[708]: 
array([[1., 0., 1.],
       [1., 0., 0.],
       [0., 1., 0.]])
##可以改變二值器的閾值:
binarizer = preprocessing.Binarizer(threshold=1.1)
binarizer.transform(X)
Out[710]: 
array([[0., 0., 1.],
       [1., 0., 0.],
       [0., 0., 0.]])

四、分類特徵編碼

       在很多時候變量的取值是分類數據,而不是連續的數值特徵,比如一個人的性別可以是["male","female"],["from Europe","from  US","from Asia"], ["user Firefox","use Chrome","user Internet Explorer"]這樣的編碼,例如["male" . "from US", "use Internet Explorer"]可以表示成[0, 1, 3]

      這樣的整數特徵並不能在scikit - learn中直接使用,因爲這樣連續的輸入,solve會認爲類別之間是有序的,但實際上是無序的。(就好像瀏覽器的類別數據是無序的)

    可以將類別特徵轉換成scikit - learn估計其可以使用的特徵的方法有one - of - k或者one - hot編碼,該方法是:class:OneHotEncoder`的一個實現。該方法將每個類別特徵的 ``m` 可能值轉換成``m``個二進制特徵值,當然只有一個是激活值

enc = preprocessing.OneHotEncoder()

enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  
Out[712]: 
OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)

enc.transform([[0, 1, 3]]).toarray()
Out[713]: array([[1., 0., 0., 1., 0., 0., 0., 0., 1.]])

        默認情況下,每個特徵使用幾維的數值由數據集自動推斷。當然,你也可以通過使用參數``n_values``來精確指定。 在我們的例 子數據集中,有兩個可能得性別類別,三個洲,四個網絡瀏覽器。接着,我們訓練編碼算法,並用來對一個樣本數據進行轉換。 在結果中,前兩個數值是性別編碼,緊接着的三個數值是洲編碼,最後的四個數值是瀏覽器編碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章