【讀書筆記】Feature Scaling (特徵縮放)

created on: 2020-01-20

@author: 假如我年華正好

Feature Scaling

WHY?

歸一化/標準化實質是一種線性變換對向量XX按比例縮放,再進行平移),在樣本給定的情況下,XmaxX_{max}XminX_{min}μ\muσ\sigma 都可看作常數。

線性變換有很多良好的性質,決定了對數據改變後不會造成“失效”,反而能提高數據的表現,這些性質是歸一化/標準化的前提。比如有一個很重要的性質:

  • 線性變換不會改變原始數據的數值排序(不改變原始數據的分佈狀態)。

爲什麼要歸一化/標準化?

  1. 某些模型求解需要

    1. 如果輸入範圍不同,某些算法無法正常工作。例如邏輯迴歸,神經網絡
    2. 梯度下降的收斂速度非常慢慢甚至完全無法完成有效訓練。 歸一化/標準化後可以加快梯度下降的求解速度,即提升模型的收斂速度。(梯度下降是Logistic迴歸、支持向量機、神經網絡等常用的優化算法。)
    3. 一些分類器需要計算樣本之間的距離(如歐氏距離),例如KNN。如果一個特徵值域範圍非常大,那麼距離計算就主要取決於這個特徵,從而與實際情況相悖(比如這時實際情況是值域範圍小的特徵更重要)

    【⭐注意】:基於樹的算法幾乎是唯一不受輸入大小影響的算法

  2. 爲了做無量綱化
    使得不同度量之間的特徵具有可比性;
    對目標函數的影響體現在幾何分佈(離散型概率分佈)上,而不是數值上

  3. 避免數值問題
    太大的數會引發數值問題。

需要歸一化的機器學習算法

(參考來源:https://blog.csdn.net/pipisorry/article/details/52247379

  • 有些模型在各個維度進行不均勻伸縮後,最優解與原來不等價,例如SVM(距離分界面遠的也拉近了,支持向量變多?)。對於這樣的模型,除非本來各維數據的分佈範圍就比較接近,否則必須進行標準化,以免模型參數被分佈範圍較大或較小的數據dominate。

  • 有些模型在各個維度進行不均勻伸縮後,最優解與原來等價,例如logistic regression(因爲θ的大小本來就自學習出不同的feature的重要性吧?)。對於這樣的模型,是否標準化理論上不會改變最優解。但是,由於實際求解往往使用迭代算法,如果目標函數的形狀太“扁”,迭代算法可能收斂得很慢甚至不收斂(模型結果不精確)。所以對於具有伸縮不變性的模型,最好也進行數據標準化。

  • 有些模型/優化方法的效果會強烈地依賴於特徵是否歸一化,如LogisticReg,SVM,NeuralNetwork,SGD等。

  • 不需要歸一化的模型:

    • 0/1取值的特徵通常不需要歸一化,歸一化會破壞它的稀疏性。

    • 有些模型則不受歸一化影響,如DecisionTree。


HOW?

歸一化(normalization)

  • 把數據映射到 [0,1](或者 [-1, 1])區間內

  • 把有量綱表達式變成無量綱的純量,便於不同單位或量級的指標能夠進行比較和加權。

  • 縮放僅僅跟最大、最小值的差別有關

  • 區間放縮法是歸一化的一種

  • Min-Max Normalization(也叫離差標準化):輸出範圍 [0, 1]

XiXminXmaxXmin \frac{X_i - X_{min}}{X_{max} - X_{min}}

img
([圖片來源](https://blog.csdn.net/qq_36523839/article/details/82919412))
from sklearn import preprocessing
norm_x = preprocessing.MinMaxScaler().fit_transform(x)

在這裏插入圖片描述

([圖片來源](https://www.meiwen.com.cn/subject/vgmveqtx.html))
  • 非線性歸一化:

    • 經常用在數據分化比較大的場景,有些數值很大,有些很小。該方法包括log、指數、正切等
    • 需要根據數據分佈的情況,決定非線性函數的曲線
    • 例如 對數函數轉換:y=log(X)y = \log(X)
歸一化後的好處
  1. 提升模型的收斂速度

在這裏插入圖片描述

如左圖所示,未歸一化時形成的等高線偏橢圓,迭代時很有可能走“之”字型路線(垂直長軸),從而導致迭代很多次才能收斂。而如右圖對兩個特徵進行了歸一化,對應的等高線就會變圓,在梯度下降進行求解時能較快的收斂。([圖片來源](https://www.jianshu.com/p/95a8f035c86c))
  1. 提升模型的精度
    在涉及到一些距離計算的算法時效果顯著,比如算法要計算歐氏距離,歸一化可以讓各個特徵對結果做出的貢獻相同。
    當各指標間的水平相差很大時,如果直接用原始指標值進行分析,就會突出數值較高的指標在綜合分析中的作用,相對削弱數值水平較低指標的作用。

標準化(standardization)

  • Z-score規範化(標準差標準化 / 零均值標準化)

  • 通過求z-score的方法,轉換爲標準正態分佈(均值爲0,標準差爲1)

  • 和整體樣本分佈相關,每個樣本點都能對標準化產生影響,通過均值(μ\mu)和標準差(σ\sigma)體現出來。

  • 也能取消由於量綱不同引起的誤差,使不同度量之間的特徵具有可比性

  • 輸出範圍:[-∞, +∞]

Xiμσ \frac{X_i - \mu}{\sigma}

img
([圖片來源](https://blog.csdn.net/qq_36523839/article/details/82919412))
from sklearn import preprocessing
std_x = preprocessing.StandardScaler().fit_transform(x)
標準化的好處

數據標準化也就是統計數據的指數化。數據標準化處理主要包括數據同趨化處理和無量綱化處理兩個方面。數據同趨化處理主要解決不同性質數據問題,對不同性質指標直接加總不能正確反映不同作用力的綜合結果,須先考慮改變逆指標數據性質,使所有指標對測評方案的作用力同趨化,再加總才能得出正確結果。數據無量綱化處理主要解決數據的可比性。經過上述標準化處理,原始數據均轉換爲無量綱化指標測評值,即各指標值都處於同一個數量級別上,可以進行綜合測評分析。(原文鏈接:https://blog.csdn.net/pipisorry/article/details/52247379


中心化(Zero-centered 或 Mean-subtraction)

  • 把數據整體移動到以0爲中心點的位置
  • 平均值爲0,對標準差無要求
  • 減去平均數,但沒有除以標準差的操作(只有平移,沒有縮放)

在這裏插入圖片描述

  • PCA的時候需要做中心化(centering)(參考:CSDN博文

  • 與標準化的區別:(參考:CSDN博文

    • 對數據進行中心化預處理,這樣做的目的是要增加基向量的正交性
    • 對數據標準化的目的是消除特徵之間的差異性。便於對一心一意學習權重。
    img

歸一化和標準化的比較:

  • 如果對輸出結果範圍有要求,用歸一化
  • 如果數據較爲穩定,不存在極端的最大最小值,用歸一化
  • 如果數據存在異常值和較多噪音,用標準化,可以間接通過中心化避免異常值和極端值的影響
  • 在分類、聚類算法中,需要使用距離來度量相似性的時候、或者使用PCA技術進行降維的時候,標準化表現更好。

(參考來源:知乎回答

  • 歸一化和標準化,都是將點平移然後縮短距離,但標準化不改變數據分佈(幾何距離)

    • 平移對於歸一化以一個最小值爲參照,標準化以均值爲參照。
    • 縮放對於歸一化以最大差值爲參照,標準化以標準差爲參照。
    • 標準化不改變幾何距離是其公式定義的原因。
    • 需要根據實際的數據或場景需求來使用,以免適得其反,如:歸一化後雖然平衡了權重,但也會或多或少破壞數據的結構。原文鏈接
    img
如果採用標準化,不改變樣本在這兩個維度上的分佈,則左圖還會保持二維分佈的一個扁平性;
而採用歸一化則會在不同維度上對數據進行不同的伸縮變化(歸一區間,會改變數據的原始距離,分佈,信息),使得其呈類圓形。雖然這樣樣本會失去原始的信息,但這防止了歸一化前直接對原始數據進行梯度下降類似的優化算法時最終解被數值大的特徵所主導。歸一化後,各個特徵對目標函數的影響權重是一致的。這樣的好處是在提高迭代求解的精度。
(原文鏈接:https://blog.csdn.net/qq_36523839/article/details/82919412)

選擇特徵縮放方法的經驗

⭐以下參考來源:GitHub項目:feature-engineering-and-feature-selection

Method Definition Pros Cons
Normalization - Standardization (Z-score scaling) removes the mean and scales the data to unit variance.
z = (X - X.mean) / std
feature is rescaled to have a standard normal distribution that centered around 0 with SD of 1 compress the observations in the narrow range if the variable is skewed or has outliers, thus impair the predictive power.
Min-Max scaling transforms features by scaling each feature to a given range. Default to [0,1].
X_scaled = (X - X.min / (X.max - X.min)
/ compress the observations in the narrow range if the variable is skewed or has outliers, thus impair the predictive power.
Robust scaling removes the median and scales the data according to the quantile range (defaults to IQR)
X_scaled = (X - X.median) / IQR
better at preserving the spread of the variable after transformation for skewed variables /
from sklearn.preprocessing import RobustScaler
RobustScaler().fit_transform(X)

Z-score 和 Min-max方法將把大部分數據壓縮到一個狹窄的範圍,
robust scaler 在保持數據整體情況方面做得更好,儘管它不能從處理結果中移除異常值。
(但是請記住,清除/查找離羣值是數據清理中的另一個主題,應該事先完成。)

  1. 如果特性不是高斯型的,例如,skewed distribution 或有異常值,Normalization - Standardization 不是一個好的選擇,因爲它將把大多數數據壓縮到一個狹窄的範圍。
  2. 但是,可以先轉換成高斯型,再使用Normalization - Standardization。(這在3.4節 Feature Transformation中討論。
  3. 在計算距離或協方差計算時(聚類、PCA和LDA等算法),最好採用Normalization - Standardization,因爲它將消除尺度對方差和協方差的影響。( Explanation here
  4. Min-Max Scaling有着和 Normalization - Standardization 一樣的缺點,而且新的數據可能不會被限制到[0, 1],因爲它們可能超出了原來的範圍。一些算法,例如 深度神經網絡更喜歡限制在0-1的輸入,所以這是一個很好的選擇。

⭐附加參考資源:

  • A comparison of the three methods when facing skewed variables can be found here6.3. Preprocessing data —— sklearn官方文檔


附:對樣本(而不是特徵)進行Normalization

另外,在sklearn官方文檔 中還有個Normalization(正則化),定義爲:the process of scaling individual samples to have unit norm.

from sklearn import preprocessing
preprocessing.Normalizer(norm="l2").fit_transform(x)
# norm: The norm to use to normalize each non zero sample.
# ‘l1’, ‘l2’, or ‘max’, optional (‘l2’ by default)
  • l1_norm 變換後每個樣本的各維特徵的絕對值和爲1,,
  • l2_norm 變換後每個樣本的各維特徵的平方和爲1,,
  • max_norm 變換將每個樣本的各維特徵除以該樣本的最大值。

❗ 特別注意這裏的 Normalizer 是對行(對樣本)進行處理,而本文前面提到的都是對列(對特徵)進行處理。

from sklearn import preprocessing
X = [[ 1., -1.,  2.],
     [ 2.,  0.,  0.],
     [ 0.,  1., -1.],
     [ 0.,  1., -1.]
     ]
preprocessing.normalize(X, norm='l1', return_norm =True)
Out[1]: 
(array([[ 0.25, -0.25,  0.5 ],
        [ 1.  ,  0.  ,  0.  ],
        [ 0.  ,  0.5 , -0.5 ],
        [ 0.  ,  0.5 , -0.5 ]]), array([4., 2., 2., 2.]))
preprocessing.normalize(X, norm='l2', return_norm =True)
Out[2]: 
(array([[ 0.40824829, -0.40824829,  0.81649658],
        [ 1.        ,  0.        ,  0.        ],
        [ 0.        ,  0.70710678, -0.70710678],
        [ 0.        ,  0.70710678, -0.70710678]]),
 array([2.44948974, 2.        , 1.41421356, 1.41421356]))
preprocessing.normalize(X, norm='max', return_norm =True)
Out[3]: 
(array([[ 0.5, -0.5,  1. ],
        [ 1. ,  0. ,  0. ],
        [ 0. ,  1. , -1. ],
        [ 0. ,  1. , -1. ]]), array([2., 2., 1., 1.]))
發佈了27 篇原創文章 · 獲贊 26 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章