sklearn 數(shù)據(jù)預處理

數(shù)據(jù)預處理

官方文檔

在機器學習算法實踐中怎茫,往往需要把不同規(guī)格的數(shù)據(jù)轉(zhuǎn)換到同一規(guī)格辛馆,或者不同分布的數(shù)據(jù)轉(zhuǎn)換到同一分布停忿,這個過程叫做"無量綱化"颜启。

數(shù)據(jù)的無量綱化可以是線性的日杈,也可以是非線性的衡载。線性的無量綱化包括"中心化" (Zero-centered or Mean-substraction)處理和縮放處理 (Scale)奏路。中心化的本質(zhì)是讓所有紀錄減去一個固定值阵幸,即讓數(shù)據(jù)平移到某個位置(通常是0);縮放的本質(zhì)是通過除以一個固定值坡慌,將數(shù)據(jù)固定掛在某個范圍之中黔酥,取對數(shù)也是一種縮放處理。

Note:決策樹即基于決策樹的算法不需要對數(shù)據(jù)進行無量綱化處理洪橘,幾乎可以應對任何形式的數(shù)據(jù)跪者。

標準化 (standardization),也稱為去均值和方差按比例縮放

數(shù)據(jù)集的標準化對于 sklearn 中實現(xiàn)的很多機器學習算法來說都是常見的要求熄求。如果個別特征或多或少看起來不像是標準正態(tài)分布 (具有零均值和單位方差)渣玲,那么它們的表現(xiàn)能力可能會很差。

在實際過程中弟晚,經(jīng)常會忽略特征的分布形狀忘衍,直接經(jīng)過去均值對某個特征進行中心化,再通過除以非常量特征的標準差進行縮放卿城。

函數(shù)scale為數(shù)組形狀的數(shù)據(jù)集的標準化提供了一個快捷實現(xiàn):

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

>>> from sklearn import preprocessing
>>> import numpy as np
>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
>>> X_scaled = preprocessing.scale(X_train)

>>> X_scaled
array([[ 0.  ..., -1.22...,  1.33...],
       [ 1.22...,  0.  ..., -0.26...],
       [-1.22...,  1.22..., -1.06...]])

>>> X_scaled.mean(axis=0)
array([0., 0., 0.])

>>> X_scaled.std(axis=0)
array([1., 1., 1.])

預處理 (preprocessing) 模塊還提供了一個實用類 StandardScaler枚钓,它對標準化常用的函數(shù)進行了分裝,常應用于 sklearn.pipeline.Pipeline的早期步驟:

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

  • copy=True:將計算結(jié)果進行返回瑟押;

  • with_mean=True: 對數(shù)據(jù)進行去中心化搀捷,即將其轉(zhuǎn)為了均值為0;

  • with_std=True: 對數(shù)據(jù)進行縮放勉耀,使其方差為標準差指煎;

    常用的屬性 (attribute) 和方法 (method):

    • scale_: 返回該數(shù)組的標準差;
    • mean_: 返回原數(shù)組的平均值便斥;
    • var_: 返回原數(shù)組的方差至壤;
    • fit_transform(): 計算該數(shù)組的平均值和方差,并對其進行轉(zhuǎn)換枢纠;
    • fit(): 計算該數(shù)組的平均值和方差像街;
    • transform(): 根據(jù)平均值和方差 (由調(diào)用fit()方法時計算得出,不包含該數(shù)組),轉(zhuǎn)換該數(shù)組镰绎;
    • inverse_transform():可將標準化之后的數(shù)據(jù)反標準化脓斩,返回原始數(shù)據(jù);
>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
...
>>> scaler = preprocessing.StandardScaler().fit(X_train)
>>> scaler
StandardScaler(copy=True, with_mean=True, with_std=True)

>>> scaler.mean_                                      
array([ 1. ...,  0. ...,  0.33...])

>>> scaler.scale_                                       
array([ 0.81...,  0.81...,  1.24...])

>>> scaler.transform(X_train)                           
array([[ 0.  ..., -1.22...,  1.33...],
       [ 1.22...,  0.  ..., -0.26...],
       [-1.22...,  1.22..., -1.06...]])

StandardScaler()scale() 的計算方法為:

z=(x-\mu)/s

Note:

  • 當設置 with_mean = False 時畴栖,不對數(shù)組去中心化随静,這是可以用來處理稀疏矩陣,而且能保持其稀疏性吗讶。
  • fit()fit_transform() 接受的數(shù)據(jù)必須是二維數(shù)據(jù)燎猛,如果對某個特征向量單獨進行標準化,需要首先使用 .reshape(-1,1)將其由一維數(shù)組轉(zhuǎn)化為二維數(shù)組照皆。

Normalization 將特征向量縮放至特定范圍內(nèi)

另一種標準化方法是將特征數(shù)組縮放到某一范圍之內(nèi)重绷,通常為(0,1)或 (-1膜毁,1) 之間昭卓,可以使用 MinMaxScalerMaxAbsScaler實現(xiàn)。

class sklearn.preprocessing.MinMaxScaler(feature_range=(0, 1), copy=True)

class sklearn.preprocessing.MaxAbsScaler(copy=True)

這兩個類的用法和 StandardScaler類的用法幾乎一樣瘟滨,其對應的函數(shù)分別為 minmax_scale()maxabs_scale()候醒。

其中:MinMaxScaler類的計算方式為:

x_{std}=\frac{x-min(x)}{max(x)-min(x)}

x_{scaled}=x_{std}*(max(x)-min(x))+min(x)

MaxAbsScaler 的計算方法為:

x^,=\frac{x}{|max(x)|}

NoteMaxAbsScaler 不但可以處理一般矩陣,還可以處理稀疏矩陣室奏,并且能保持其稀疏性火焰。

StandardScaler 與 MinMaxScaler 該如何選擇

大多數(shù)機器學習算法中劲装,會選擇 StandardScaler 來進行特征縮放胧沫,因為 MinMaxScaler 對異常值非常敏感。在 PCA占业、聚類绒怨、邏輯回歸、支持向量機谦疾、神經(jīng)網(wǎng)絡這些算法中南蹂,StandardScaler 往往是最好的選擇。在不涉及距離度量念恍、梯度六剥、協(xié)方差計算以及數(shù)據(jù)需要被壓縮到特定區(qū)間時,比如數(shù)字圖像處理中量化像素強度時峰伙,往往會使用 MinMaxScaler 將數(shù)據(jù)壓縮到 [0,1] 區(qū)間疗疟。

縮放稀疏矩陣

中心化稀疏矩陣會破壞矩陣的稀疏結(jié)構(gòu),但是對稀疏矩陣進行縮放是有意義的瞳氓,尤其是當幾個特征在不同的量級范圍時策彤。

MaxAbsScaler 以及 maxabsscale 是專門為縮放稀疏矩陣而設計的,并且是縮放稀疏矩陣的推薦方法。同時店诗,scale()StanderdScaler 也可以對稀疏矩陣進行縮放裹刮,必須設置參數(shù) with_mean=False,否則會破壞其稀疏性庞瘸,當數(shù)據(jù)量很大時捧弃,很容易引起 ValueError 的錯誤。

縮放有離群點 (outflier)的數(shù)據(jù)

對于帶有很多帶有離群點的數(shù)據(jù)擦囊,使用均值和方差進行縮放可能不是很好的選擇塔橡,這時可以使用 robust_scale 函數(shù)或者RobustScaler,它們對于數(shù)據(jù)的中心和范圍使用更有魯棒性的估計霜第。

sklearn.preprocessing.robust_scale (X, axis=0, with_centering=True, with_scaling=True, quantile_range=(25.0, 75.0), copy=True)

class sklearn.preprocessing.RobustScaler (with_centering=True, with_scaling=True, quantile_range=(25.0, 75.0), copy=True)

RobustScalerrobust_scale也會對數(shù)據(jù)進行去中心化和縮放葛家,但是使用的數(shù)據(jù)不是均值和標準差,而是中間值和第一四分位點和第三四分位點泌类,所以可以很好的降低離群點的影響癞谒。具體計算方法為:
x_{scaled}=\frac{x-x.median()}{x.quantile(0.75)-x.quantile(0.25)}

QuantileTransformer 類

preprocessing.``QuantileTransformer(n_quantiles=1000, output_distribution='uniform', ignore_implicit_zeros=False, subsample=100000, random_state=None, copy=True)

preprocessing.``quantile_transform(X, axis=0, n_quantiles=1000, output_distribution='uniform', ignore_implicit_zeros=False, subsample=100000, random_state=None, copy='warn')

QuantileTransformer 類和 quantile_transformer() 函數(shù)提供了一個基于分位數(shù)函數(shù)的無參數(shù)轉(zhuǎn)換,能夠?qū)?shù)據(jù)映射到 [0,1] 區(qū)間上的均勻分布刃榨,這種變換能夠平滑異常分布弹砚,比縮放方法受異常值的影響更小,但是它也使特征間及特征內(nèi)的關(guān)聯(lián)和距離失真枢希。

PowerTransformer 類

在很多機器學習模型中桌吃,都會假設數(shù)據(jù)服從高斯分布,都是實際數(shù)據(jù)可能會存在偏度等問題苞轿,不完全符合高斯分布茅诱,這時需要先把數(shù)據(jù)轉(zhuǎn)換為高斯分布。

PowerTransformer 可以將數(shù)據(jù)集從任何分布映射到盡可能接近高斯分布搬卒,以便穩(wěn)定方差和最小化偏斜瑟俭。

preprocessing.``QuantileTransformer(n_quantiles=1000, output_distribution='uniform', ignore_implicit_zeros=False, subsample=100000, random_state=None, copy=True)

歸一化 (Normalization)

"歸一化"是縮放單個樣本以使其具有單位范數(shù)。如果你計劃使用二次形式 (比如點積或者任何其他核函數(shù)) 來量化任意樣本間的相似度契邀,這個過程將會非常有用摆寄。

這種假設是"向量空間模型"的根本,經(jīng)常在文本分類和內(nèi)容聚類中使用坯门。

Normalizer類和函數(shù) normalize() 則提供了一個快速簡單的方法在類似于數(shù)組的數(shù)據(jù)結(jié)構(gòu)上執(zhí)行操作微饥,使其具有 l1 或者 l2 范式。

>>> X = [[ 1., -1.,  2.],
...      [ 2.,  0.,  0.],
...      [ 0.,  1., -1.]]
>>> X_normalized = preprocessing.normalize(X, norm='l2')

>>> X_normalized                                      
array([[ 0.40..., -0.40...,  0.81...],
 [ 1.  ...,  0.  ...,  0.  ...],
 [ 0.  ...,  0.70..., -0.70...]])

備注:

  • l1 范式是指該樣本各個特征值的絕對值之和等于 1古戴,即:\sum |x_i|=1;
  • l2 范式是指該樣本各個特征值的平方和等于 1欠橘,即:\sum x_i^2=1.
  • 該類和函數(shù)接受一般矩陣和稀疏矩陣作為輸入。

處理分類型數(shù)據(jù):編碼與啞變量

sklearn 當中允瞧,除了專門用來處理文字的算法简软,其他算法在 fit() 的時候要求全部數(shù)組必須為數(shù)值類型蛮拔。

preprocessing.LabelEncoder()

能夠?qū)撕炥D(zhuǎn)化為數(shù)值類型,范圍是 (0痹升,N-1)建炫,N是類型數(shù)。

Note:該類時標簽專用疼蛾,即專門用來轉(zhuǎn)換 y肛跌,因此輸入默認是一維數(shù)組。

preprocessing.OrdinalEncoder()

特征矩陣專用察郁,能夠?qū)⒎诸愄卣鬓D(zhuǎn)換為分類數(shù)值衍慎,輸入默認是二維數(shù)組。

preprocessing.OrdinalEncoder (categories=auto, dtype=np.float64)

>>> enc = preprocessing.OrdinalEncoder()
>>> X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
>>> enc.fit(X)  
OrdinalEncoder(categories='auto', dtype=<... 'numpy.float64'>)
>>> enc.transform([['female', 'from US', 'uses Safari']])
array([[0., 1., 1.]])

這樣將類別數(shù)據(jù)轉(zhuǎn)化為整數(shù)特征的變換會帶來另一個問題皮钠,sklearn 中的估計器會將該特征當做是有序稳捆,并且是有一定含義,但實際上是無序的麦轰。另一種轉(zhuǎn)換方式是 one-of-K, 又稱為 dummy encoding乔夯。

preprocessing.OneHotEncoder()

對特征進行啞變量編碼;把每一個具有 n_categories 個可能取值的 categorical 特征變換為長度為 n_categories 的二進制特征向量款侵,里面只有一個值為 1末荐,其他值為 0。

preprocessing.``OneHotEncoder(categories='auto', drop=None, sparse=True, dtype=, handle_unknown='error')

如果訓練數(shù)據(jù)集可能缺少部分分類特征新锈,最好設置 handle_unknown=ignore, 這樣在轉(zhuǎn)換過程中遇到未知類別時甲脏,就不會報錯,而是將其特征全部設置為 0.

>>> enc = preprocessing.OneHotEncoder()
>>> X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
>>> enc.fit(X)  
OneHotEncoder(categorical_features=None, categories=None,
       dtype=<... 'numpy.float64'>, handle_unknown='error',
       n_values=None, sparse=True)
>>> enc.transform([['female', 'from US', 'uses Safari'],
...                ['male', 'from Europe', 'uses Safari']]).toarray()
array([[1., 0., 0., 1., 0., 1.],
       [0., 1., 1., 0., 0., 1.]])

離散化:二值化和bins

離散化是將連續(xù)性特征劃分為離散特征的方法妹笆,進行離散化處理可以給線性模型引入非線性块请。

preprocessing.Binarizer()

根據(jù)閾值將數(shù)據(jù) (連續(xù)性數(shù)據(jù)和離散型數(shù)據(jù)都可以) 二值化 (0 或者 1)。大于閾值的值映射為1晾浴,小于或等于閾值的值映射為0.

preprocessing.Binarizer(threshold=0.0, copy=True)

>>> binarizer = preprocessing.Binarizer(threshold=1.1)
>>> binarizer.transform(X)
array([[ 0.,  0.,  1.],
 [ 1.,  0.,  0.],
 [ 0.,  0.,  0.]])

preprocessing.KBinsDiscretizer()

能夠?qū)⑦B續(xù)性變量劃分到 K 個不同的 bins 當中负乡,轉(zhuǎn)化為分類變量,既可以將其轉(zhuǎn)化為 OrdinalEncoder() 這樣的數(shù)字分類變量脊凰,又可以轉(zhuǎn)換為 One Hot 編碼。

preprocessing.KBinsDiscretizer(n_bins=5, encode='onehot', strategy='quantile')

>>> X = np.array([[ -3., 5., 15 ],
...               [  0., 6., 14 ],
...               [  6., 3., 11 ]])
>>> est = preprocessing.KBinsDiscretizer(n_bins=[3, 2, 2], encode='ordinal').fit(X)
>>> est.transform(X)                      
array([[ 0., 1., 1.],
       [ 1., 1., 1.],
       [ 2., 0., 0.]])

單變量插補

SimpleImpute類提供了計算缺失值的基本策略茂腥,既可以使用常值填充狸涌,又可以使用缺失值所在行的統(tǒng)計數(shù)據(jù) (平均值、中位數(shù)或眾數(shù))來計算最岗,同時也支持不同的缺失值編碼方式

class sklearn.impute.SimpleImputer (missing_values=nan, strategy='mean', fill_value=None, verbose=0, copy=True, add_indicator=False)

missing_values:缺失值在數(shù)據(jù)中的體現(xiàn)形式帕胆;

strategy: ‘mean’, ‘median’, ‘most_frequent’, ‘constant’, 決定由平均值,中值或者總數(shù)進行填充般渡。

>>> import numpy as np
>>> from sklearn.impute import SimpleImputer
>>> imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean')
>>> imp_mean.fit([[7, 2, 3], [4, np.nan, 6], [10, 5, 9]])
SimpleImputer()
>>> X = [[np.nan, 2, 3], [4, np.nan, 6], [10, np.nan, 9]]
>>> print(imp_mean.transform(X))
[[ 7.   2.   3. ]
 [ 4.   3.5  6. ]
 [10.   3.5  9. ]]

當使用 most_frequent or constant 策略進行填充時懒豹,SimpleImpute 類還支持以 string values or pandas.Categoricals 表示的分類數(shù)據(jù)芙盘。

>>> import pandas as pd
>>> df = pd.DataFrame([["a", "x"],
...                    [np.nan, "y"],
...                    ["a", np.nan],
...                    ["b", "y"]], dtype="category")
...
>>> imp = SimpleImputer(strategy="most_frequent")
>>> print(imp.fit_transform(df))      
[['a' 'x']
 ['a' 'y']
 ['a' 'y']
 ['b' 'y']]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市脸秽,隨后出現(xiàn)的幾起案子儒老,更是在濱河造成了極大的恐慌,老刑警劉巖记餐,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驮樊,死亡現(xiàn)場離奇詭異,居然都是意外死亡片酝,警方通過查閱死者的電腦和手機囚衔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雕沿,“玉大人练湿,你說我怎么就攤上這事∩舐郑” “怎么了鞠鲜?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長断国。 經(jīng)常有香客問我贤姆,道長,這世上最難降的妖魔是什么稳衬? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任霞捡,我火速辦了婚禮,結(jié)果婚禮上薄疚,老公的妹妹穿的比我還像新娘碧信。我一直安慰自己,他們只是感情好街夭,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布砰碴。 她就那樣靜靜地躺著,像睡著了一般板丽。 火紅的嫁衣襯著肌膚如雪呈枉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天埃碱,我揣著相機與錄音猖辫,去河邊找鬼。 笑死砚殿,一個胖子當著我的面吹牛啃憎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播似炎,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辛萍,長吁一口氣:“原來是場噩夢啊……” “哼悯姊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贩毕,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤悯许,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后耳幢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岸晦,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年睛藻,在試婚紗的時候發(fā)現(xiàn)自己被綠了启上。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡店印,死狀恐怖冈在,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情按摘,我是刑警寧澤包券,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站炫贤,受9級特大地震影響溅固,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兰珍,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一侍郭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掠河,春花似錦亮元、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至勾拉,卻和暖如春煮甥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背望艺。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工苛秕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人找默。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像吼驶,于是被迫代替她去往敵國和親惩激。 傳聞我的和親對象是個殘疾皇子店煞,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容