一、standardization
之所以標准化的原因是,如果數據集中的某個特征的取值不服從標准的正太分布,則性能就會變得很差
①函數scale提供了快速和簡單的方法在單個數組形式的數據集上來執行標准化操作
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) print(X_scaled) """ [ 1.22474487 0. -0.26726124] [-1.22474487 1.22474487 -1.06904497]] """ #尺度調整之后的數據有0均值和淡乏味方差(==1) print(X_scaled.mean(axis=0)) #[ 0. 0. 0.] print(X_scaled.std(axis=0)) #[ 1. 1. 1.]
②Preprocessing還提供了一個類StandarScaler,該類實現了變換器的API用於計算訓練數據集的均值和標准差,然后將均值與標准差用到對測試數據集的變換操作中去,所以這個標准化過程應該被應用到Pipeline的早起階段
scaler=preprocessing.StandardScaler().fit(X) print(scaler) #StandardScaler(copy=True, with_mean=True, with_std=True) print(scaler.mean_) #[ 1. 0. 0.33333333] print(scaler.scale_) #[ 0.81649658 0.81649658 1.24721913] print(scaler.transform(X)) """ [[ 0. -1.22474487 1.33630621] [ 1.22474487 0. -0.26726124] [-1.22474487 1.22474487 -1.06904497]] """
在上面的代碼在,scalar實例已經訓練完畢,就可以用來對新的數據執行在訓練集上同樣的變換操作
print(scaler.transform([[-1,1,0]])) #[[-2.44948974 1.22474487 -0.26726124]]
③將特征變換到指定范圍內,
可以把特征的取值設置到最小值和最大值之間,通常是【0,1】區間或每個特征分量的最大絕對值被縮放為單位值,這樣的特征變換可以使用MinMaxScaler 或 MaxAbsScaler
這些變換的作用主要是為那些變動范圍特別小的 特征分量添加一定的魯棒性,並且可以防止zero entries in sparse data
min_max_scaler=preprocessing.MinMaxScaler() X_train_minmax=min_max_scaler.fit_transform(X) print(X_train_minmax) """ [[ 0.5 0. 1. ] [ 1. 0.5 0.33333333] [ 0. 1. 0. ]] """
上面的X上訓練好的MinMaxScaler就可以通過transform函數被用到新的數據上:同樣的縮放和評議操作被用到測試數據集
X_test=np.array([[-3,-1,4]]) X_test_minmax=min_max_scaler.transform(X_test) print(X_test_minmax) #[[-1.5 0. 1.66666667]]
print(min_max_scaler.scale_)
#[ 0.5 0.5 0.33333333]
print(min_max_scaler.min_)
#[ 0. 0.5 0.33333333]

④Scaling features to a range

max_abs_scaler=preprocessing.MaxAbsScaler() X_train_maxabs=max_abs_scaler.fit_transform(X) print(X_train_maxabs) """ [[ 0.5 -1. 1. ] [ 1. 0. 0. ] [ 0. 1. -0.5]] """ X_test=np.array([[-3,-1,4]]) X_test_maxabs=max_abs_scaler.transform(X_test) print(X_test_maxabs) #[[-1.5 -1. 2. ]] print(max_abs_scaler.scale_) #[ 2. 1. 2.]
⑤縮放稀疏矩陣

⑥Scaling data with outliers

二、normalization


函數normalize提供了快速簡單的方法,使用L1或L2范數執行規范化操作是:
from sklearn import preprocessing x=[[1,-1,2], [2,0,0], [0,1,-1]] x_normalized=preprocessing.normalize(x,norm="l2") print(x_normalized) """ 按行操作,把每一行變成單位長度!! [[ 0.40824829 -0.40824829 0.81649658] [ 1. 0. 0. ] [ 0. 0.70710678 -0.70710678]] """

規范化操作類Normalizer作為數據預處理步驟,應該用在sklearn.pipeline.Pipeline
normalizer=preprocessing.Normalizer().fit(x) print(normalizer) #Normalizer(copy=True, norm='l2') print(normalizer.transform(x)) """ [[ 0.40824829 -0.40824829 0.81649658] [ 1. 0. 0. ] [ 0. 0.70710678 -0.70710678]] """ print(normalizer.transform([[1,1,0]])) #[[ 0.70710678 0.70710678 0. ]]


三、二值化
Feat binarization:將數值型特征取值閾值化轉變為布爾形特征取值,這一過程主要是概率型的學習器提供數據預處理機制

binarizer=preprocessing.Binarizer().fit(x) print(binarizer) #Binarizer(copy=True, threshold=0.0) print(binarizer.transform(x)) """ [[1 0 1] [1 0 0] [0 1 0]] """
還可以通過參數指定binarizer對象實例的閾值

四、離散化
有些情況下,某些特征的取值不是連續的數值,而是離散的標稱變量
比如一個人的特征描述取值有以下幾種:
"male","female" "Europe","US","Asia" "Firefox","chrome","Safari","IE"
這樣的特征可以被有效的編碼為整型特征值。樣本實例:["Europe","US","Asia"]對於為[0,1,3],["chrome","Safari","IE"]對應於[1,2,1]
但是上面的這些整數型的特征向量是無法直接被sklearn的學習器使用的,因為學習器希望輸入的是連續變化的量或者可以比較大小的量,但是上述特征向量里邊的數字大小的比較是沒有任何意義的
一種變換標稱型特征的方法是使用one-of-K或者叫one-hot encoding,在類OneHotEncoder里面就已實現,這個編碼器將每個標稱型特征編碼成一個m維二值特征,其中每一個樣本特征向量就只有一個位置是1,其余位置全是0.
from sklearn import preprocessing enc=preprocessing.OneHotEncoder() enc.fit([[0,0,3],[1,1,0],[0,2,1],[1,0,2]]) print(enc) """ OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>, handle_unknown='error', n_values='auto', sparse=True) """ print(enc.transform([[0,1,3]]).toarray()) #[[ 1. 0. 0. 1. 0. 0. 0. 0. 1.]]
默認情況下,每個特征分量需要多少個值是從數據集自動推斷出來的,我們還可以通過參數n_values進行顯式的指定,上面的數據集中,有兩種性別,三個可能的地方以及四個瀏覽器,然后we fit the estimator,再對每一個樣本進行變換,結果里面,前兩個值編碼了性別,接下來的三個值編碼了地方,最后的四個編碼了瀏覽器。
注意:如果訓練數據集中某個標稱型分量的取值沒有完全覆蓋其所有可能的情況,則必須給OneHotEncoder指定每個標稱型特征分量的取值個數,設置參數:n_values
enc=preprocessing.OneHotEncoder(n_values=[2,3,4]) enc.fit([[1,2,3],[0,2,0]]) print(enc) """ OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>, handle_unknown='error', n_values=[2, 3, 4], sparse=True) """ print(enc.transform([[1,0,0]]).toarray()) #[[ 0. 1. 1. 0. 0. 1. 0. 0. 0.]]
五、缺失值補充
一種方法是直接丟掉包含缺失值的整行或整列,然而這樣可能丟失很多有價值的數據
另一種方法是從已知的部分數據中推斷出未知的數據
Imputer Class提供了補全缺失值的基本策略:使用一行或一列的均值,中值,出現次數最多的值,該類也允許不同缺失值的編碼。
下面的例子展示了如何替代缺失值,缺失值編碼為np.nan:策略是使用包含缺失值的列均值來替代
#用中值來補充缺失值 import numpy as np from sklearn.preprocessing import Imputer imp=Imputer(missing_values="NaN",strategy="mean",axis=0) print(imp.fit([[1,2],[np.nan,3],[7,6]])) """ Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0) """ x=[[np.nan,2],[6,np.nan],[7,6]] print(imp.transform(x)) """ [[ 4. 2. ] [ 6. 3.66666667] [ 7. 6. ]] """
Inputer 類支持稀疏矩陣
import scipy.sparse as sp X=sp.csc_matrix([[1,2],[0,3],[7,6]]) imp=Imputer(missing_values=0,strategy='mean',axis=0) print(imp.fit(X)) """ Imputer(axis=0, copy=True, missing_values=0, strategy='mean', verbose=0) """ X_test=sp.csc_matrix([[0,2],[6,0],[7,6]]) print(imp.transform(X_test)) """ [[ 4. 2. ] [ 6. 3.66666667] [ 7. 6. ]] """
六、產生多項式特征
為輸入數據添加非線性特征可以增加模型的復雜度,實現這一點的常用的簡單方法是使用多項式特征,他可以引入特征的高階項和互乘積項。
Sklearn的類PolynomialFeatures可以用來在輸入數據的基礎上構造多項式特征
轉化前的特征為(X1,X2),轉化后的特征為(1,X1,X2,X1X1,X1X2,X2X2)
#引入特征的高階項和互乘積項 import numpy as np from sklearn.preprocessing import PolynomialFeatures X=np.arange(6).reshape(3,2) print(X) """ [[0 1] [2 3] [4 5]] """ poly=PolynomialFeatures(2) print(poly.fit_transform(X)) """ [[ 1. 0. 1. 0. 0. 1.] [ 1. 2. 3. 4. 6. 9.] [ 1. 4. 5. 16. 20. 25.]] """
有些情況下,我們只想要原始特征分量之間的互乘積項,這時可以設置參數做到:interaction_only=True
#只想要原始特征分量之間的互乘積項 X=np.arange(9).reshape(3,3) print(X) """ [[0 1 2] [3 4 5] [6 7 8]] """ poly=PolynomialFeatures(degree=3,interaction_only=True) print(poly.fit_transform(X)) """ [[ 1. 0. 1. 2. 0. 0. 2. 0.] [ 1. 3. 4. 5. 12. 15. 20. 60.] [ 1. 6. 7. 8. 42. 48. 56. 336.]] """
轉化前的特征為(X1,X2,X3),轉化后的特征為(1,X1,X2,X3,X1X2,X1X3,X2X3,X1X2X3)
七、利用已有的函數自定義transformer
借助於FunctionTransformer類,可以從任意的Python函數實現一個transformer,比如,構造一個transformer實現對數變換
#構造一個transformer實現對數變換 import numpy as np from sklearn.preprocessing import FunctionTransformer transformer=FunctionTransformer(np.log1p) X=np.array([[0,1],[2,3]]) print(transformer.transform(X)) """ [[ 0. 0.69314718] [ 1.09861229 1.38629436]] """
