精彩文章不會錯過!

今天說一個比較重要的內容,無論是在算法建模還是在數據分析都比較常見:數據歸一化和標準化。
開始之前,請你先把網上看到的所有相關的博客、帖子都忘掉。不說全部,能講清楚這個概念的文章真寥寥無幾,首先是中英文名稱翻譯的問題,其次是概念理解的不全面,也就造成了網上的說法不一,看了之后各種被誤導。
當然,如果你在閱讀文章的時候,發現存在問題歡迎留言批評指正
但是我覺得你可能沒有批評指正的機會
先來說下概念
數據歸一化和標準化都屬于數據特征無量綱的一種方式。無量綱指的是將不同規格的數據轉換到同一規格,或不同分布的數據轉換到某個特定分布的需求,稱之為數據“無量綱化”。
在模型訓練過程中,經過無量綱化之后的數據特征對于模型的求解有加速作用,特別是對于需要計算梯度和矩陣的模型(例如邏輯回歸中通過梯度下降求解損失函數)。
另外,在k近鄰、聚類等算法中需要計算距離,使用無量綱化可以提升模型精度,避免異常值對整體的計算造成影響,這個在后面會細說。
數據的無量綱化可以是線性的,也可以是非線性的。非線性的無量綱不太常用,例如百分位數轉換、應用特征功率轉換等,基本很少用到;而常用的線性無量綱化主要包括 中心化處理和縮放處理,在特征工程中比較常見。
中心化的本質是 讓所有記錄減去一個固定值,即讓數據樣本平移到某個位置。
縮放的本質是 通過除以一個固定值,將數據固定在某個范圍之中。
下面來細說
數據歸一化
重要!!?數據歸一化的英文翻譯有兩種:Normalization 和 Min-Max Scaling
數據歸一化是當數據 x 按照最小值中心化后再按極差(最大值-最小值)進行縮放。最終的數據移動了最小值個單位,并且會被收斂到 [0,1] 之間。
歸一化的公式如下:
這里一定要注意的是:Normalization 是歸一化的意思,并不是正則化,而正則化的英文翻譯應該是:Regularization,但是正則化并不是數據處理的一種手段。
代碼實現
常用的特征無量綱化方法都已經在 sklearn 中實現,可以直接調用,一般都是在基于 sklearn 下的 preprocessing 模塊。
歸一化的實現可以調用 MinMaxScaler 函數,當然你也可以自己實現,公式也都在上面列出來了。
MinMaxScaler 有一個重要參數:feature_range,默認值 [0,1] 表示將數據收斂到 [0,1] 之間。
MinMaxScaler 可以手動設置,但是一般情況都是選擇默認值
具體的,進行特征歸一化的代碼實現如下:
import?numpy?as?np
from?sklearn.preprocessing?import?MinMaxScaler
#?創建數組
data_rn?=?np.random.randint(-10,?10,?10).reshape(5,?2)
print(data_rn)
#?進行標準歸一化
scaler_mms?=?MinMaxScaler()
result_mms?=?scaler_mms.fit_transform(data_rn)
print(result_mms)
#?手動設置收斂區間[1,3]
scaler_mms_parm?=?MinMaxScaler(feature_range=(1,?3))
result_mms_parm?=?scaler_mms_parm.fit_transform(data_rn)
print(result_mms_parm)
"""輸出"""
[[-10???7]
?[??1???9]
?[?-3??-5]
?[?-9??-6]
?[?-8???5]]
[[0.?????????0.86666667]
?[1.?????????1.????????]
?[0.63636364?0.06666667]
?[0.09090909?0.????????]
?[0.18181818?0.73333333]]
[[1.?????????2.73333333]
?[3.?????????3.????????]
?[2.27272727?1.13333333]
?[1.18181818?1.????????]
?[1.36363636?2.46666667]]
可以看到,手動設置的收斂范圍其實就是在 [0,1] 的基礎上進行了相應的平移和縮放。
就比如上面手動設置的 [1,3] 就是在 [0,1] 的基礎上先縮放 2 變成 [0,2] 再平移 1 變成 [1,3]。
所以,要想歸一化的結果收斂至任意一組值 [a,b] 之間,則歸一化的公式變成:
對應的,在 MinMaxScaler 函數調用中只需要設置 feature_range 的取值為 (a,b) 即可。
數據標準化
數據標準化的英文翻譯:Standardization,又稱 Z-score normalization。
數據標準化是指當數據 x 按均值 μ 中心化后,再按標準差 σ 縮放,數據就會服從均值為 0,方差為 1 的標準正態分布,這個過程就叫做數據標準化。
數據標準化的公式如下:
有一點需要注意:標準化并不會改變數據的分布。之所以會說標準化之后數據變成標準正態分布,是因為原始的數據就是符合正態分布的,只不過并不是標準正態分布。
另外大家會把標準化和正態分布聯系起來,是因為實際中大多數數據都是正態分布的,或者近似正態分布。所以在標準化之后數據就會變成標準正態分布。
不是說原本未知分布在標準化之后就可以憑空變成正態分布的。
代碼實現
具體的,進行特征標準化的代碼實現如下:
import?numpy?as?np
from?sklearn.preprocessing?import?StandardScaler
#?創建數組
data_rn?=?np.random.randint(-10,?10,?10).reshape(5,?2)
#?進行標準化
print(data_rn)
scaler_ss?=?StandardScaler()
result_ss?=?scaler_ss.fit_transform(data_rn)
print(result_ss)
"""輸出"""
[[-10???7]
?[??1???9]
?[?-3??-5]
?[?-9??-6]
?[?-8???5]]
[[-1.00803226??0.79859571]
?[?1.63205223??1.11803399]
?[?0.67202151?-1.11803399]
?[-0.76802458?-1.27775313]
?[-0.5280169???0.47915742]]
另外,也可以通過 inverse_transform 函數將標準化后的數據進行逆轉
#?標準化后的數據逆轉
data_inverse?=?scaler_ss.inverse_transform(result_ss)
對于 StandardScaler 和 MinMaxScaler 來說,空值 NAN 會被當作是缺失值,在 fit_transform 的時候繼續保持缺失狀態。
標準化和歸一化的區別與聯系?
首先,需要明確很重要的一點:歸一化和標準化都不會改變數據的分布。
它們都是對于數據的線性無量綱化,通過相應的縮放和平移使得數據發生改變的過程,但是并沒有改變原始數據的排列順序。
其中歸一化 Normalization 會嚴格的限定數據變化后的范圍,默認的是將數據控制在 [0,1] 之間。
而標準化 Standardization 之后的數據沒有嚴格的區間,變化之后的數據沒有范圍,只是數據整體的均值為 0,標準差為 1
另外,歸一化縮放的比例僅僅和極值有關,而標準化縮放的比例和整體數據集有關。所以對于存在異常數據的樣本來說,用歸一化并不是一個聰明的決定
比如有一批樣本取值是 0~10,突然加入異常值 99 再進行歸一化之后,正確樣本的數值將會變得很小,這個時候,使用標準化的效果會優于歸一化。
數據處理的時候選哪個?
只能說,針對情況選擇。
在大多數機器學習算法中,因為 MinMaxScaler 對異常值的敏感,所以都會選擇 StandardScaler 進行特征縮放。例如聚類、邏輯回歸、支持向量機、PCA 等算法。
但是如果在縮放的時候不涉及距離、梯度等的計算,并且對數據的范圍有嚴格要求,就可以使用歸一化進行縮放。
并不是所有模型的數據都需要標準化和歸一化的。
類似決策樹模型,在節點分裂的時候計算的是信息增益,標準化后并不能大幅提高模型的計算速度【可能會有很小的提升】
類似概率模型,并不關心變量的值,只關心變量的分布和變量之間的條件概率。
綜上,一般在特征無量綱化的時候,如果沒有硬性規定【縮放范圍、距離計算等】,可以先使用標準化,效果不好再試試歸一化。
我是東哥,最后給大家分享《100本Python電子書》,包括Python編程技巧、數據分析、爬蟲、Web開發、機器學習、深度學習。
現在免費分享出來,有需要的讀者可以下載學習,在下面的公眾號「GitHuboy」里回復關鍵字:Python,就行。
推薦閱讀
像Excel一樣使用SQL進行數據分析吹爆了這個可視化神器,上手后直接開大~再見,360安全衛士!別去送死了!Selenium 能被網站探測的幾十個特征Pandas用了一年,這3個函數是我最愛…邏輯回歸 + GBDT模型融合實戰!
愛點贊的人運氣都不會太差