1. 程式人生 > >sklearn-資料預處理

sklearn-資料預處理

資料預處理

概要

sklearn是一個比較常用的機器學習庫,其中的sklearn.preprocessing包含了常用的預處理函式,一般在kaggle等資料競賽網站拿到資料的時候,首先要觀察資料特徵,分佈等資訊,然後進行資料預處理。資料預處理有利於計算機進行計算。

原始資料存在的問題
1. 存在缺失值
2. 存在異常點及噪聲
3. 各個特徵的取值範圍比例不一
4. 資料表現形式不一
5. 維度過高,部分特徵間線性相關

Z-score標準化

Z-score標準化就是將資料變化為服從均值為0,方差為1的正太分佈,對於不知道資料最大最小值的時候適用,但是會改變資料的分佈。

x=xμsμs
from sklearn import preprocessing
import numpy as np

x = np.array([[1., 0., 2.],
              [0., -2., 1.],
              [-1., 1., 0.]])

#第一種方法
x_scale_1 = preprocessing.scale(x)
'''
[[ 1.22474487  0.26726124  1.22474487]
 [ 0.         -1.33630621  0.        ]
 [-1.22474487  1.06904497 -1.22474487]]
 '''
#第二種方法 scaler = preprocessing.StandardScaler() x_scale_2 = scaler.fit_transform(x) ''' [[ 1.22474487 0.26726124 1.22474487] [ 0. -1.33630621 0. ] [-1.22474487 1.06904497 -1.22474487]] ''' StandardScaler(copy=True, with_mean=True, with_std=True) with_mean=False #不減去均值 with_std=False
#不除以標準差


紅色為隨機資料,藍色為Z-score標準化後資料

MinMax標準化

MinMax標準化適用於知道最大值和最小值的資料,標準化後的資料將會落在[0,1]區間內,如果有異常值則會將資料分佈不均勻,向異常值的另一側堆積。

x=xminmaxminminmax
scaler = preprocessing.MinMaxScaler()
x_scaled = scaler.fit_transform(x)
'''
before
[[ 1.  0.  2.]
 [ 0. -2.  1.]
 [-1.  1.  0.]]
 after
[[ 1.          0.66666667  1.        ]
 [ 0.5         0.          0.5       ]
 [ 0.          1.          0.        ]]
'''


紅色為隨機資料,藍色為MinMax標準化後資料


異常點出現

MaxAbs標準化

MaxAbs標準化根據最大值的絕對值進行標準化,標準化後的資料將會落在[1,1]區間內

x=xabs(max)absmax
scaler = preprocessing.MaxAbsScaler()
x_scaled = scaler.fit_transform(x)
'''
before
[[ 1.  0.  2.]
 [ 0. -2.  1.]
 [-1.  1.  0.]]
 after
[[ 1.   0.   1. ]
 [ 0.  -1.   0.5]
 [-1.   0.5  0. ]]
'''


紅色為隨機資料,藍色為MaxAbs標準化後資料

中心化資料會破壞原有稀疏資料的結構

正則化

正則化資料和之前的標準化資料不同,之前標準化資料是針對特徵來說的,而現在正則化是對樣本來做的,是用樣本資料除以他的正規化

x=<x1,x2,...,xn>Lp(x)=i=0n|xi|ppxi=xiLp(x)p12
x_scaled = preprocessing.normalize(x, norm = 'l1')
#norm = 'l1' or 'l2'
#或者使用
normalizer = preprocessing.Normalizer()#l2正則化
normalizer.fit(x)#這個fit函式沒有任何作用
x = normalizer.transform(x)
'''
before
[[ 1.  0.  2.]
 [ 0. -2.  1.]
 [-1.  1.  0.]]
after
[[ 0.33333333  0.          0.66666667]
 [ 0.         -0.66666667  0.33333333]
 [-0.5         0.5         0.        ]]
 '''


紅色為隨機資料點,藍色為l1正則化後資料點


紅色為隨機資料點,藍色為l2正則化後資料點

閾值劃分

連續特徵值可以根據閾值劃分進行二值化,大於閾值的值為1,否則為0

f(x)={10,,x>thresholdelse
scaler = preprocessing.Binarizer(threshold=0.5)#threshold為閾值
x_scaled = scaler.fit_transform(x)

'''
before
[[ 1.  0.  2.]
 [ 0. -2.  1.]
 [-1.  1.  0.]]
after
[[ 1.  0.  1.]
 [ 0.  0.  1.]
 [ 0.  1.  0.]]
'''

離散變數編碼

例如性別有‘男’, ‘女’,然而計算機的許多模型都只能在數值型資料當中進行計算,如果我們簡單的將‘男’為1,‘女’為0,雖然也可以完成轉換,但是在轉換的過程當中我們引入了大小關係,就是‘女’ < ‘男’,這會對後續模型應用造成不必要的困擾。
解決方法為OneHotEncode,就是將其轉化為二進位制串,除了當前值所在位置為1,其他全部為0,如[0,0,1,0,0], [0,1,0,0,0].。性別可表示為男為[1,0],女為[0,1],這樣一個性別特徵就轉化成了兩個特徵。

df = pd.DataFrame({'pet': ['cat', 'dog', 'dog', 'fish'],'age': [4 , 6, 3, 3],
'salary':[4, 5, 1, 1]})
#例如有資料比較大,OneHotEncoder會生成非常多的特徵,或者為字串資料,先轉化為數字,所以先用LabelEncoder處理。
label = preprocessing.LabelEncoder()
df['pet'] = label.fit_transform(df['pet'])
one_hot = preprocessing.OneHotEncoder(sparse = False)
print one_hot.fit_transform(df[['pet']])
'''
before
   age  pet  salary
0    4    0       4
1    6    1       5
2    3    1       1
3    3    2       1
after
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]
'''

缺失值處理

由於資料收集的過程,部分樣本的屬性值有缺失,在處理這部分值的時候可以人工根據經驗補充,或者使用均值,出現頻率較高的值,中值補充。

imp = Imputer(missing_values=0, strategy='mean', axis=0)
#strategy = 'mean', 'median', 'most_frequent'
x = imp.fit_transform(x)

維度拓展

我們可以考慮複雜化非線性特徵,就是生成多項式特徵,例如(x1,x2)>(x1,x2,x21,x1x2,x22),會使特徵數量增加

poly = PolynomialFeatures(2)#引數為階數
poly.fit_transform(X) 
'''
before 
[[0, 1],
 [2, 3],
 [4, 5]]
after
[[  1.,   0.,   1.,   0.,   0.,   1.],
 [  1.,   2.,   3.,   4.,   6.,   9.],
 [  1.,   4.,   5.,  16.,  20.,  25.]]

自定義變換規則

sklearn 還可以提供自定義變換函式,使用者只需要提供相應操作,然後用FunctionTransformer包裝就可以了。

transformer = FunctionTransformer(np.log1p)
#np.log1p(x) = np.log(1 + x)
X = np.array([[0, 1], [2, 3]])
transformer.transform(X)
'''
array([[ 0.        ,  0.69314718],
       [ 1.09861229,  1.38629436]])
'''