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
官網對不同方法的比較文檔:
一.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)
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
拓:向量范數的內容: