數據規范化——sklearn.preprocessing


sklearn實現---歸類為5大類

  • sklearn.preprocessing.scale()(最常用,易受異常值影響)
  • sklearn.preprocessing.StandardScaler()
  • sklearn.preprocessing.minmax_scale()(一般縮放到[0,1]之間,若新數據集最大最小值范圍有變,需重新minmax_scale)
  • sklearn.preprocessing.MinMaxScaler()
  • sklearn.preprocessing.maxabs_scale()(為稀疏數據而生)
  • sklearn.preprocessing.MaxAbsScaler()
  • sklearn.preprocessing.robust_scale()(為異常值而生)
  • sklearn.preprocessing.RobustScaler()
  • sklearn.preprocessing.normalize()(文本分類or聚類時常用,默認對樣本正則化,上述4種默認對列,即特征來規范化)
  • sklearn.preprocessing.preprocessing.Normalizer()

借用iris數據集

import pandas as pd
import numpy as np
from sklearn import datasets
iris  = datasets.load_iris()
x, y = iris.data, iris.target
print(x[:10])
[[ 5.1  3.5  1.4  0.2]
 [ 4.9  3.   1.4  0.2]
 [ 4.7  3.2  1.3  0.2]
 [ 4.6  3.1  1.5  0.2]
 [ 5.   3.6  1.4  0.2]
 [ 5.4  3.9  1.7  0.4]
 [ 4.6  3.4  1.4  0.3]
 [ 5.   3.4  1.5  0.2]
 [ 4.4  2.9  1.4  0.2]
 [ 4.9  3.1  1.5  0.1]]
print(x.shape,x.max(),x.min())
(150, 4) 7.9 0.1

官網對不同方法的比較文檔:

https://scikit-learn.org/stable/auto_examples/preprocessing/plot_all_scaling.html#sphx-glr-auto-examples-preprocessing-plot-all-scaling-py

一.z-score 標准化(zero-mean normalization)

也叫標准差標准化。先減去均值,后除以均方根。提高了數據可比性,同時削弱了數據解釋性,是用的最多的數據的標准化方法。輸出:每個屬性值均值為0,方差為1,呈正態分布。
公式如下:
x* = (x-μ)/σ
( 其中μ為所有樣本數據的均值,σ為所有樣本數據的標准差。)

使用原因:
部分機器學習算法求解目標函數時,要求特征的均值為0,方差為1.(如:SVM的RFB內核、線性模型的L1和L2正則化)此時,如果某個特征的方差比其他特征的方差大幾個數量級別,如:3000:2等,會造成方差大的特征在算法中占據主導地位,使得機器學習效果不佳。

缺點:

  • 當特征明顯不遵從高斯正態分布時,標准化出來的效果較差。
  • 還要注意,均值和標准差受離群點的影響很大,所以如果有很多異常值,使用RobustScaler或robust_scaler 的效果更好。
  • scale和 StandardScaler都能接受 scipy.sparse 作為輸入,但參數必須設置: with_mean=False。Or會報錯: ValueError ,因為默認的中心化會破壞稀疏性,並且此時內存一般會炸,然后崩潰------>dead。
  • 實際應用中,經常忽略特征數據的分布形狀,移除每個特征均值,划分離散特征的標准差,從而等級化,進而實現數據中心化。

實現:

  • sklearn.preprocessing.scale
  • sklearn.preprocessing.StandardScaler(兩個基本一樣,但一般用這個就ok了,比較高級、方法比較齊全)

1.1 sklearn.preprocessing.scale(X, axis=0, with_mean=True, with_std=True, copy=True)

參數說明:
axis=0,默認。計算列。axis=1,則會按行進行標准化。
with_mean、with_std,默認為True,設置將數據轉化成0均值、方差為1的標准正態分布,基本不用管。

from sklearn.preprocessing import scale
iris_scale = scale(x)
print(iris_scale[:5])  #顯示4個被scale后的特征
[[-0.90068117  1.03205722 -1.3412724  -1.31297673]
 [-1.14301691 -0.1249576  -1.3412724  -1.31297673]
 [-1.38535265  0.33784833 -1.39813811 -1.31297673]
 [-1.50652052  0.10644536 -1.2844067  -1.31297673]
 [-1.02184904  1.26346019 -1.3412724  -1.31297673]]
print("平均值:",iris_scale.mean(axis=0))
print("樣本方差:",iris_scale.std(axis=0))
平均值: [ -1.69031455e-15  -1.63702385e-15  -1.48251781e-15  -1.62314606e-15]
樣本方差: [ 1.  1.  1.  1.]

1.2 class sklearn.preprocessing.StandardScaler(copy=True, with_mean=True, with_std=True)

from sklearn.preprocessing import StandardScaler
Stan_scaler = StandardScaler()
Stan_scaler.fit(x)
x_test = np.array([[6,4,6,2],
                  [4.999,3,5,2.3]])   #假設新的數據集,可當作我們平時用到的測試集
Stan_scaler.transform(x_test)
array([[ 0.18982966,  2.18907205,  1.27454998,  1.05353673],
       [-1.02306072, -0.1249576 ,  0.70589294,  1.44795564]])

transform時,用到的是原先x中的均值與標准差,相當於我們平時的訓練集例的均值與標准差,然后用這兩個值去標准化測試集的數據。

二.最小最大值標准化(將數據縮放到一定范圍內)

公式如下:
x* = (x-min)/(max-min) (當使用默認[0,1]范圍時)
( 其中min為特征的最小值,max為特征的最大值。)

使用原因:

  • 對於方差非常小的屬性可以增強其穩定性。有時數據集的標准差非常非常小,有時數據中有很多很多零(稀疏數據)需要保存住0元素。
  • 維持稀疏矩陣中為0的條目。

缺點:
當數據出現新的最大最小值時,需要重來一遍。
若數值集中且某個數值很大,則規范化后各值接近於0,並且將會相差不大。(如:100、101、102、108、20001)

實現:

  • sklearn.preprocessing.minmax_scale
  • sklearn.preprocessing.MinMaxScaler(這兩者的關系跟上面的標准差標准化差不多,這里只講后者)

sklearn.preprocessing.MinMaxScaler(feature_range=(0, 1), copy=True)
官網文檔:
https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html#sklearn.preprocessing.MinMaxScaler
參數說明:
feature_range : tuple (min, max), default=(0, 1)
轉化步驟如下:
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0)) #每列最大、最小值
X_scaled = X_std * (max - min) + min

from sklearn.preprocessing import MinMaxScaler
MiMaScaler = MinMaxScaler()
MiMaScaler.fit(x)
x_test = np.array([[4.563,4,6,2],
                  [4.999,3,3,1]])   #假設新的數據集,可當作我們平時用到的測試集
MiMaScaler.transform(x_test)    #如果新數據集中最大最小值超出原來fit的數據的最大最小值,請注意transform出來的數據將不在[0,1]內,需重新fit
array([[ 0.07305556,  0.83333333,  0.84745763,  0.79166667],
       [ 0.19416667,  0.41666667,  0.33898305,  0.375     ]])

舉一個栗子(反例):當transform的數據集的最大最小值超出fit數據集中的最大最小值

x_test_out = np.array([[9,10,77,88],
                      [33,29,10,3]])
MiMaScaler.transform(x_test_out) 
array([[  1.30555556,   3.33333333,  12.88135593,  36.625     ],
       [  7.97222222,  11.25      ,   1.52542373,   1.20833333]])

Obviously,轉換出來的數據范圍並不在[0,1]內。所以應用中需引起注意。

另外,說明一下:fit_transform存在的意義

1 MiMaScaler.fit(x)
2 MiMaScaler.transform(x)
3 MinMaxScaler().fit_transform(x)
注意第3句效果跟1、2句聯合起來一樣,第3句省一步,飛快實現轉換~~

三.絕對值標准化(暫時這么叫)(將數據縮放到一定范圍內,專為稀疏數據而生)

使用原因:
將每個要素縮放到[-1,1]范圍,它不會移動/居中數據,因此不會破壞任何稀疏性。
該估計器單獨地縮放每個特征,使得訓練集中的每個特征的最大絕對值將是1.0。
該縮放器也可以應用於稀疏CSR或CSC矩陣。

實現:

  • sklearn.preprocessing.maxabs_scale(X, axis=0, copy=True)
  • sklearn.preprocessing.MaxAbsScaler(copy=True)(這兩者的關系同上)
from sklearn.preprocessing import MaxAbsScaler
MaAbScaler = MaxAbsScaler().fit(x)
MaAbScaler.transform(x)[:10]
array([[ 0.64556962,  0.79545455,  0.20289855,  0.08      ],
       [ 0.62025316,  0.68181818,  0.20289855,  0.08      ],
       [ 0.59493671,  0.72727273,  0.1884058 ,  0.08      ],
       [ 0.58227848,  0.70454545,  0.2173913 ,  0.08      ],
       [ 0.63291139,  0.81818182,  0.20289855,  0.08      ],
       [ 0.6835443 ,  0.88636364,  0.24637681,  0.16      ],
       [ 0.58227848,  0.77272727,  0.20289855,  0.12      ],
       [ 0.63291139,  0.77272727,  0.2173913 ,  0.08      ],
       [ 0.55696203,  0.65909091,  0.20289855,  0.08      ],
       [ 0.62025316,  0.70454545,  0.2173913 ,  0.04      ]])
MaAbScaler.transform(x).max(axis=0)
array([ 1.,  1.,  1.,  1.])

每列值的Max值的絕對值將會是1.

四.魯棒性標准化(暫時這么叫)(將數據縮放到一定范圍內,專為異常值而生)

使用原因:
標准差標准化(第一種,最常用的那種)對數據中出現的異常值處理能力不佳,因此誕生了robust_scale,這種不怕異常值擾動的數據縮放法。
此Scaler根據分位數范圍(默認為IQR:Interquartile Range)刪除中位數並縮放數據。 IQR是第1四分位數(第25個分位數)和第3個四分位數(第75個分位數)之間的范圍。

實現:

  • sklearn.preprocessing.robust_scale(X, axis=0, with_centering=True, with_scaling=True, quantile_range=(25.0, 75.0), copy=True)
  • sklearn.preprocessing.RobustScaler(with_centering=True, with_scaling=True, quantile_range=(25.0, 75.0), copy=True)
from sklearn.preprocessing import RobustScaler
Robust_Scaler = RobustScaler()
Robust_Scaler.fit(x)
Robust_Scaler.transform(x)[:10]
array([[-0.53846154,  1.        , -0.84285714, -0.73333333],
       [-0.69230769,  0.        , -0.84285714, -0.73333333],
       [-0.84615385,  0.4       , -0.87142857, -0.73333333],
       [-0.92307692,  0.2       , -0.81428571, -0.73333333],
       [-0.61538462,  1.2       , -0.84285714, -0.73333333],
       [-0.30769231,  1.8       , -0.75714286, -0.6       ],
       [-0.92307692,  0.8       , -0.84285714, -0.66666667],
       [-0.61538462,  0.8       , -0.81428571, -0.73333333],
       [-1.07692308, -0.2       , -0.84285714, -0.73333333],
       [-0.69230769,  0.2       , -0.81428571, -0.8       ]])

五.正則化

使用原因:
每個樣本被單獨縮放,使得其范數等於1。注意,是對每個樣本,不再像之前的(默認對列進行規范化)規范化。
文本分類或聚類中常用。可用於密集的numpy數組和scipy.sparse矩陣(如果你想避免復制/轉換的負擔,請使用CSR格式)
Normalization主要思想是對每個樣本計算其p-范數,然后對該樣本中每個元素除以該范數,這樣處理的結果是使得每個處理后樣本的p-范數(l1-norm,l2-norm)等於1。
p-范數的計算公式:||X||p=(|x1|p+|x2|p+...+|xn|p)1/p

實現:

  • sklearn.preprocessing.normalize(X, norm=’l2’, axis=1, copy=True, return_norm=False)
  • sklearn.preprocessing.Normalizer(norm=’l2’, copy=True)

5.1 sklearn.preprocessing.normalize(X, norm=’l2’, axis=1, copy=True, return_norm=False)

官方文檔:
https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.normalize.html#sklearn.preprocessing.normalize

5.2 sklearn.preprocessing.Normalizer(norm=’l2’, copy=True)

官方文檔:
https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.Normalizer.html#sklearn.preprocessing.Normalizer
參數說明:
norm :‘l1’,‘l2’, or ‘max’, 默認l2。

from sklearn.preprocessing import Normalizer
Normalizer_ = Normalizer()
Normalizer_.fit(x)
Normalizer_.transform(x)[:10]
array([[ 0.80377277,  0.55160877,  0.22064351,  0.0315205 ],
       [ 0.82813287,  0.50702013,  0.23660939,  0.03380134],
       [ 0.80533308,  0.54831188,  0.2227517 ,  0.03426949],
       [ 0.80003025,  0.53915082,  0.26087943,  0.03478392],
       [ 0.790965  ,  0.5694948 ,  0.2214702 ,  0.0316386 ],
       [ 0.78417499,  0.5663486 ,  0.2468699 ,  0.05808704],
       [ 0.78010936,  0.57660257,  0.23742459,  0.0508767 ],
       [ 0.80218492,  0.54548574,  0.24065548,  0.0320874 ],
       [ 0.80642366,  0.5315065 ,  0.25658935,  0.03665562],
       [ 0.81803119,  0.51752994,  0.25041771,  0.01669451]])
 0.80377277* 0.80377277+0.55160877*0.55160877+  0.22064351*0.22064351 +   0.0315205 * 0.0315205 
1.0000000013597559

下面驗證一下每個樣本的范數,隨機挑選第四個樣本、第77個樣本來驗證:

output_3 = []
aa = Normalizer_.transform(x)[3]
for i in aa:
    output_3.append(i*i)
print(output_3)
print("樣本范數:",sum(output_3))
[0.64004839685420423, 0.29068360556563821, 0.068058076225045352, 0.0012099213551119174]
樣本范數: 1.0
output_76 = []
bb = Normalizer_.transform(x)[76]
for i in bb:
    output_76.append(i*i)
print(output_76)
print("樣本范數:",sum(output_76))
[0.58472432979261513, 0.099140111279716753, 0.29135053110773901, 0.024785027819929188]
樣本范數: 1.0

拓:向量范數的內容:

091414004623860.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM