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

常用的數(shù)據(jù)預(yù)處理方式

  1. Standardization, or mean removal and variance scaling
  2. Normalization: scaling individual to have unit norm
  3. Binarization: thresholding numerical features to get boolean values
  4. Encoding categorical feature
  5. Imputation of missing values
  6. Generating polynominal features
  7. Custom transformers
  • 標(biāo)準(zhǔn)化(Standardization)

對sklearn中的很多機器學(xué)習(xí)算法,他們都有一個共同的要求:數(shù)據(jù)集的標(biāo)準(zhǔn)化(Standardization)督弓。如果數(shù)
據(jù)集中某個特征的取值不服從保準(zhǔn)的正態(tài)分布(Gaussian with zero mean and unit variance)曙寡,則他們的
性能就會變得很差途事。

在實踐中良漱,我們經(jīng)常忽略分布的形狀(shape of the distribution)而僅僅通過除每個特征分量的均值
(Mean Removal)將數(shù)據(jù)變換到中心赔癌,然后通過除以特征分量的標(biāo)準(zhǔn)差對數(shù)據(jù)進(jìn)行尺度縮放(variance scaling)蔫仙。

舉例來說,在學(xué)習(xí)器的目標(biāo)函數(shù)中用到的很多元素(SVM中的RBF核函數(shù)巨坊,或線性代數(shù)中的L1和L2正則化)都假定了
所有特征分布在0周圍而且每個分量的方差都差不多大撬槽。如果一旦某個特征分量的方差幅度遠(yuǎn)大于其他特征分量的
方差幅度,那么這個大方差特征分量將會主導(dǎo)目標(biāo)函數(shù)的有優(yōu)化過程趾撵,使得學(xué)習(xí)器無法正確的從其他特征上學(xué)習(xí)恢氯。

from sklearn import preprocessing
import numpy as np

X = np.array([[1, -1, 2], [2, 0, 0], [0, 1, -1]])
X_scaled = preprocessing.scale(X)
X_scaled
image

尺度調(diào)整之后的數(shù)據(jù)有0均值和單位方差(==1):

print(X_scaled.mean(axis=0))
print(X_scaled.std(axis=0))
image

Preprocessing模塊進(jìn)一步提供了一個類StandardScaler,該類實現(xiàn)了變換器(Transformer)的API用于
計算訓(xùn)練數(shù)據(jù)集的均值和標(biāo)準(zhǔn)差鼓寺。然后將此均值與標(biāo)準(zhǔn)差用到對測試數(shù)據(jù)集的變換操作中去勋拟。所以這個標(biāo)準(zhǔn)化
的過程應(yīng)該被應(yīng)用到sklearn.pipeline.Pipeline的早期階段。

scaler = preprocessing.StandardScaler().fit(X)
print(scaler)
print('--------')
print(scaler.mean_)
print('--------')
print(scaler.transform(X))
image

在上面的代碼中妈候,scaler實例已經(jīng)訓(xùn)練完成敢靡,就可以再用來對新的數(shù)據(jù)執(zhí)行在訓(xùn)練集上同樣的變換操作。

image

我們還可以使用參數(shù)來進(jìn)一步的自定義苦银,with_mean=False, with_std=False來不去使用中心化和規(guī)男ル剩化。

把特征變換到指定范圍內(nèi)(Scaling feature to a range)

另外一種標(biāo)準(zhǔn)化是把特征的取值變換到指定的最小值和最大值之間幔虏,通常是[0,1]區(qū)間或每個特征分量的最大絕對值
被縮放為單位值幌甘,這樣的變換可以使用MinMaxScaler或者M(jìn)axAbsScaler。

X_train = np.array([[1., -1., 2.],
                   [2., 0., 0.],
                   [0., 1., -1.]])
min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
X_train_minmax
image

上面X_train上訓(xùn)練好的MinMaxScaler就可以通過transform函數(shù)被用到新的數(shù)據(jù)上蔑穴,同樣的縮放和平移操作被用到測試數(shù)據(jù)集

X_test = np.array([[-3., -1.,4. ]])
X_test_minmax = min_max_scaler.transform(X_test)
X_test_minmax
image

還可以通過MinMaxScaler對象的屬性來獲得在訓(xùn)練集上學(xué)習(xí)到的變換函數(shù)这嚣。

image

如果給MinMaxScaler對象一個顯式的區(qū)間范圍feature_range=(min,max),則其變換過程如下瑟蜈。

image

MaxAbsScaler的工作方式與MinMaxScaler很相似烟逊,但是其變換方式是讓訓(xùn)練數(shù)據(jù)處于區(qū)間[-1,1]。這可以通過把每個特征分量除以其對應(yīng)的最大值來做到铺根。這種變換要求數(shù)據(jù)集已經(jīng)被中心化到0或者是稀疏數(shù)據(jù)宪躯。

X_train = np.array([[1., -1., 2.],
                   [2., 0., 0. ],
                   [0., 1., -1.]])
max_abs_scaler = preprocessing.MaxAbsScaler()
X_train_maxabs = max_abs_scaler.fit_transform(X_train)
print(X_train_maxabs)
print('-------')
X_test = np.array([[-3., -1., 4.]])
X_test_maxabs = max_abs_scaler.transform(X_test)
print(X_test_maxabs)
print('-------')
print(max_abs_scaler.scale_)
image

縮放稀疏數(shù)據(jù)(Scaling sparse data)

中心化稀疏數(shù)據(jù)(Centering sparse data)將會破壞數(shù)據(jù)的稀疏型結(jié)構(gòu),因此很少這么做位迂。然而访雪,我們可以對稀疏的輸入進(jìn)行縮放(Scale sparse inputs),尤其是特征分量的尺度不一樣的時候掂林。

MaxAbsScaler和maxabs_scale都進(jìn)行了一些特別的設(shè)計專門用于變換稀疏數(shù)據(jù)臣缀,是推薦的做法。

scale和StandardScaler也可以接受scipy.sparse矩陣作為輸入党饮,只要參數(shù)with_mean=False被顯式的傳入構(gòu)造器就可以了肝陪,否則,會產(chǎn)生ValueErroe刑顺。

RobustScaler不能接受稀疏矩陣氯窍,但是你可以在稀疏輸入上使用transform方法饲常。

注意:變換器接受Compressed Sparse Rows和Compressed Sparse Columns格式(scipy.sparse.csr_marxi和scipy.sparse.csc_matrix)。其他任何的稀疏輸入會被轉(zhuǎn)換成Compressed Sparse Rows狼讨,為了避免不必要的內(nèi)存拷貝贝淤,推薦使用CSR和CSC。最后政供,如果你的稀疏數(shù)據(jù)比較小播聪,那么可以使用toarray方法吧稀疏數(shù)據(jù)轉(zhuǎn)換成Numpy array。

Scaling data with outliers

如果數(shù)據(jù)中有很多的outliers(明顯的噪點)布隔,均值和方差的估計就會有問題离陶,所以使用均值和方法的數(shù)據(jù)集也會偶遇問題。
在這種情況下衅檀,可以使用robust_scale和RobustScaler招刨,他們使用了更加魯棒的方式來估計數(shù)據(jù)中心和范圍。

  • 規(guī)范化(Normalization)

Normalization: scaling individual to have unit norm

規(guī)范化是指哀军,將單個的樣本特征向量變換成具有單位長度(unit norm)的特征向量的過程沉眶。當(dāng)你要使用二次形式(quadratic from)如點積或核變換運算來度量任意一堆樣本的相似性的時候,數(shù)據(jù)的規(guī)范化會非常的有用

假定是基于向量空間模型杉适,經(jīng)常被用于文本分類和內(nèi)容的聚類谎倔。

函數(shù)normalize提供了快速簡單的方法使用L1或L2范數(shù)(距離)執(zhí)行規(guī)范化操作:

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

注意:該函數(shù)按行操作,把每一行變成單位長度猿推。使用每一個元素去除以歐式距離片习。

preprocessing模塊也提供了一個類Normalizer實現(xiàn)了規(guī)范化操作,該類是一個變換器Transformer彤守,具有Transformer API(盡管fit方法在這種時候是沒有用的: 該類是一個靜態(tài)類因為歸一化操作是將每一個樣本單獨進(jìn)行變換毯侦,不存在在所有樣本上的統(tǒng)計學(xué)習(xí)過程。)

規(guī)范化操作類Normalizer作為數(shù)據(jù)預(yù)處理步驟具垫,應(yīng)該用在Pineline管道流的早期階段。

image

以上的transform過程不依賴于上面的X试幽,也就是說fit是多余的筝蚕,只是為了整個sklearn的統(tǒng)一。

Sparse input

normalize函數(shù)和Normalizer類都接受dense array-like and sparse matrics from scipy.sparse作為輸入铺坞。

對于稀疏輸入起宽,在進(jìn)入高效的Cython routines處理之前,都會將其轉(zhuǎn)化成CSR(Compressed Sparse Rows)格式(scipy.sparse.csr_matrix)济榨,為了避免不必要的數(shù)據(jù)拷貝坯沪,推薦使用CSR格式的稀疏矩陣。

  • 二值化(Binarize)

Binarization: thresholding numerical features to get boolean values

Feature binarization: 將數(shù)值型特征取值閾值化轉(zhuǎn)換為布爾型特征取值擒滑,這一過程主要是為概率型的學(xué)習(xí)器(probabilistic estimators)提供數(shù)據(jù)預(yù)處理機制腐晾。

概率型學(xué)習(xí)器(probabilistic estimators)假定輸入數(shù)據(jù)是服從于多變量伯努利分布(multi-variate Bernoulli distribution)的叉弦, 概率性學(xué)習(xí)器的典型的例子是sklearn.neural_network.BrenoulliRBM

在文本處理中,也普遍使用二值特征簡化概率推斷過程藻糖,即使歸一化的詞頻特征或TF-IDF特征的表現(xiàn)比而二值特征稍微好一點淹冰。

就像Normalizer,Binarizer也應(yīng)該用在sklearn.pipeline.Pipeline的早期階段巨柒。fit方法也是什么也不干樱拴,有或者沒有是一樣的。

X = [[1., -1., 2.], 
     [2., 0., 0.],
     [0., 1., -1.]]
binarizer = preprocessing.Binarizer().fit(X)
print(binarizer)
print('-----')
print(binarizer.transform(X))
image
binarizer = preprocessing.Binarizer(threshold=1.1)
binarizer.transform(X)
image

就像StandardScaler和Normalizer類一樣洋满,preprocessing模塊也為我們提供了一個方便的額binarize進(jìn)行數(shù)值特征的二值化晶乔。

Sparse input

normalize函數(shù)和Normalizer類都接受dense array-like and sparse matrics from scipy.sparse作為輸入。

對于稀疏輸入牺勾,在進(jìn)入高效的Cython routines處理之前瘪弓,都會將其轉(zhuǎn)化成CSR(Compressed Sparse Rows)格式(scipy.sparse.csr_matrix),為了避免不必要的數(shù)據(jù)拷貝禽最,推薦使用CSR格式的稀疏矩陣腺怯。

  • 標(biāo)稱型特征編碼(Encoding categorical feature)

有些情況下,某些特征的取值不是連續(xù)的數(shù)值川无,而是離散的標(biāo)稱變量(categorical)呛占。

比如一個人的特征描述可能是下面的或幾種:

features ['male', 'female'], ['from Europe', 'from US', 'from Asia'], ['use Firefox', 'use Chorme', 'use Safari', 'Use IE']。

這樣的特征可以被有效的編碼為整型特征值(interger number)懦趋。

['male', 'US', 'use IE']  -->>  [0,1,3]
['femel', 'Asia', 'use Chrome']  -->> [1,2,1]

但是這些整數(shù)型的特征向量是無法直接被sklearn的學(xué)習(xí)器使用的晾虑,因為學(xué)習(xí)器希望輸入的是連續(xù)變化的量或者可以比較大小的量,但是上述特征里面的數(shù)字大小的比較是沒有意義的仅叫。

一種變換標(biāo)稱型特征(categorical features)的方法是使用one-of-K或者叫one-hot encoding帜篇,在類OneHotEncoder里面就已經(jīng)實現(xiàn)了。這個編碼器將每一個標(biāo)稱型特征編碼成一個m維二值特征诫咱,其中每一個樣本特征向量就只有一個位置是1笙隙,其余位置全是0。

enc = preprocessing.OneHotEncoder()
enc.fit([[0,0,3],[1,1,0],[0,2,1],[1,0,2]])
image
enc.transform([[0,1,3]]).toarray()
image

第一列的取值有兩個坎缭,使用兩個數(shù)字編碼竟痰;第二列取值有單個,使用三個數(shù)字編碼掏呼;第三列取值有4個坏快,使用四個數(shù)字編碼。一共使用九個數(shù)字進(jìn)行編碼憎夷。

默認(rèn)情況下莽鸿,每個特征分量需要多少個值是從數(shù)據(jù)集中自動推斷出來的。我們還可以通過參數(shù)n_values進(jìn)行顯式的指定拾给。上面的數(shù)據(jù)集中祥得,有兩個性別兔沃,三個可能的地方以及四個瀏覽器。然后fit之后在對每一個樣本進(jìn)行變換啃沪。結(jié)果顯示粘拾,前兩個值編碼了性別,接下來的三個值編碼了地方创千,最后的四個值編碼了瀏覽器缰雇。

注意:如果訓(xùn)練數(shù)據(jù)中某個標(biāo)稱型特征分量的取值沒有完全覆蓋其所有可能的情況,則必須給OneHotEncoder指定每一個標(biāo)稱型特征分量的取值個數(shù)追驴,設(shè)置參數(shù):n_values械哟。

enc = preprocessing.OneHotEncoder(n_values=[2,3,4])
enc.fit([[1,2,3],[0,2,0]])
image
enc.transform([[1,0,0]]).toarray()
image
  • 缺失值處理(Imputation of missing values)

由于各種各樣的原因,很多真實世界中的數(shù)據(jù)集包含有缺失值殿雪,通常使用blanks暇咆,NaNs or other placeholders來代替。這樣的數(shù)據(jù)集是無法直接被sklearn的學(xué)習(xí)器模型處理的丙曙。

一個解決的辦法是將包含缺失值得整行或者整列直接丟棄爸业。然而這樣可能會丟失很多有價值的數(shù)據(jù)。

一個更好的辦法是補全缺失值亏镰,也就是從已知的部分?jǐn)?shù)據(jù)推斷出未知的數(shù)據(jù)扯旷。

Imputer類提供了補全缺失值得基本策略: 使用一行或者一列的均值,中值索抓,出現(xiàn)次數(shù)最多的值來補全钧忽,該類也允許不同缺失值得編碼。

from sklearn.preprocessing import Imputer

imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
imp.fit([[1,2], [np.nan,3], [7,6]])
image
X = [[np.nan,2], [6, np.nan], [7,6]]
imp.transform(X)
image

使用訓(xùn)練得數(shù)據(jù)來進(jìn)行補全逼肯。

Imputer類支持稀疏矩陣:

import scipy.sparse as sp
X = sp.csc_matrix([[1,2], [0,3], [7,6]])
imp = Imputer(missing_values=0, strategy='mean', axis=0)
imp.fit(X)

X_test = sp.csc_matrix([[0,2], [6,0], [7,6]])
imp.transform(X_test)
image
  • 多項式特征(Generating polynominal features)

為輸入數(shù)據(jù)添加非線性特征可以增加模型的復(fù)雜度耸黑,實現(xiàn)這一點的常用的簡單方法是使用多項式特征(polynominal features),他可以引入特征的高階項和互乘積項篮幢。

sklearn的PolynominalFeatures類可以用來在出入數(shù)據(jù)的基礎(chǔ)上構(gòu)造多項式特征大刊。

from sklearn.preprocessing import PolynomialFeatures

X = np.arange(6).reshape(3,2)
poly = PolynomialFeatures(2)   # 二階
poly.fit_transform(X)
image
image

有些情況下,我們只想要原始輸入特征分量之間的互乘積項洲拇,這時可以設(shè)置參數(shù):interaction_only=True奈揍,這時將不會出現(xiàn)次方項。

  • 自定義轉(zhuǎn)換器(Custom transformers)

有時候赋续,你需要把一個已經(jīng)有的Python函數(shù)變?yōu)橐粋€變換器transformer來進(jìn)行數(shù)據(jù)的清理和預(yù)處理。

借助于FunctionTransformer類另患,你可以從任意的Python函數(shù)實現(xiàn)一個transformer纽乱。比如,構(gòu)造一個transformer實現(xiàn)對數(shù)變換昆箕。

from sklearn.preprocessing import FunctionTransformer

transformer = FunctionTransformer(np.log1p)
X = np.array([[0,1], [2,3]])
transformer.transform(X
image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鸦列,一起剝皮案震驚了整個濱河市租冠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌薯嗤,老刑警劉巖顽爹,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異骆姐,居然都是意外死亡镜粤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門玻褪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肉渴,“玉大人,你說我怎么就攤上這事带射⊥妫” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵窟社,是天一觀的道長券勺。 經(jīng)常有香客問我,道長灿里,這世上最難降的妖魔是什么关炼? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮钠四,結(jié)果婚禮上盗扒,老公的妹妹穿的比我還像新娘。我一直安慰自己缀去,他們只是感情好侣灶,可當(dāng)我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缕碎,像睡著了一般褥影。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咏雌,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天凡怎,我揣著相機與錄音,去河邊找鬼赊抖。 笑死统倒,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的氛雪。 我是一名探鬼主播房匆,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了浴鸿?” 一聲冷哼從身側(cè)響起井氢,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岳链,沒想到半個月后花竞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡掸哑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年约急,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片举户。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡烤宙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出俭嘁,到底是詐尸還是另有隱情躺枕,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布供填,位于F島的核電站拐云,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏近她。R本人自食惡果不足惜叉瘩,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粘捎。 院中可真熱鬧薇缅,春花似錦、人聲如沸攒磨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娩缰。三九已至灸撰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拼坎,已是汗流浹背浮毯。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泰鸡,地道東北人债蓝。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像盛龄,于是被迫代替她去往敵國和親惦蚊。 傳聞我的和親對象是個殘疾皇子器虾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,509評論 2 348

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