sklearn-資料預處理
資料預處理
概要
sklearn是一個比較常用的機器學習庫,其中的sklearn.preprocessing包含了常用的預處理函式,一般在kaggle等資料競賽網站拿到資料的時候,首先要觀察資料特徵,分佈等資訊,然後進行資料預處理。資料預處理有利於計算機進行計算。
原始資料存在的問題:
1. 存在缺失值
2. 存在異常點及噪聲
3. 各個特徵的取值範圍比例不一
4. 資料表現形式不一
5. 維度過高,部分特徵間線性相關
Z-score標準化
Z-score標準化就是將資料變化為服從均值為0,方差為1的正太分佈,對於不知道資料最大最小值的時候適用,但是會改變資料的分佈。
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 #不除以標準差
MinMax標準化
MinMax標準化適用於知道最大值和最小值的資料,標準化後的資料將會落在
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. ]]
'''
MaxAbs標準化
MaxAbs標準化根據最大值的絕對值進行標準化,標準化後的資料將會落在
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. ]]
'''
中心化資料會破壞原有稀疏資料的結構
正則化
正則化資料和之前的標準化資料不同,之前標準化資料是針對特徵來說的,而現在正則化是對樣本來做的,是用樣本資料除以他的正規化
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. ]]
'''
閾值劃分
連續特徵值可以根據閾值劃分進行二值化,大於閾值的值為1,否則為0
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)
維度拓展
我們可以考慮複雜化非線性特徵,就是生成多項式特徵,例如
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]])
'''