機器學習第三週 簡單的數據預處理和特徵工程
一、學習目標
🔽無量綱化:最值歸一化、均值方差歸一化及sklearn中的Scaler
🔽缺失值處理
🔽處理分類型特徵:編碼與啞變量
🔽處理連續型特徵:二值化與分段
二、參考資料
關於最值歸一化、均值方差歸一化及sklearn中的Scaler方面的學習,可以參考:《機器學習的敲門磚:歸一化與KD樹》及《特徵工程系列:特徵預處理(上)》)中相關部分。
推薦博文:https://www.cnblogs.com/juanjiang/archive/2019/05/30/10948849.html
https://mp.weixin.qq.com/s/RkenakI_DSXoMLwNNvUAAw 《機器學習的敲門磚:歸一化與KD樹》
https://mp.weixin.qq.com/s/qWO9zgKyntvyWfftpGqrHQ 《特徵工程系列:特徵預處理(上)》
三、學習記錄
-
特徵工程:
下面開始特徵工程內容,覺得https://mp.weixin.qq.com/s/qWO9zgKyntvyWfftpGqrHQ 居士說的 “數據和特徵決定了機器學習的上限,而模型和算法只是逼近這個上限而已”這句話 應該是一條定律。給定的數據和選定的特徵,可以認爲這已經在潛在確定了一個上限,雖然這個上限我們可能無法找出,但是我們可以不斷逼近。在前提條件給定的狀況下,結果最佳也就是已經確定,無論我們模擬的結果是什麼,都不會超出這個。
**特徵工程:**利用數據領域的相關知識來創建能夠使機器學習算法達到最佳性能的特徵的過程。
特徵工程包含內容:DataPreProcessing數據預處理、Feature Extraction 特徵提取 、Feature Selection特徵選擇 和Feature Construction特徵構造等。
數據預處理則包括數據清洗和特徵預處理等問題。
(1)數據型特徵無量綱化
在實際常常使用數據中一般都是帶有單位的,無量綱化就是將他們變得沒有單位。可以使用標準化或者歸一化。
-
最值歸一化和均值方差歸一化
在數據做訓練前,由於數據大小的差異,或者數據單位量綱的不同,導致運算結果差異較大。這就需要在模型的開始對數據進行歸一化操作normalize。在常用的數據歸一化有兩種:
最值歸一化normalization和均值方差歸一化standardization
**最值歸一化normalization:**把所有數據映射到0,1之間。其特徵是具有明顯邊界,但受outlier影響較大
**均值方差歸一化:**把所有數據歸一到均值爲0方差爲1的分佈中。適用於數據中沒有明顯的邊界,有可能存在極端數據值的情況
import numpy as np x = np.random.randint(0,100,size=100) #最值歸一化 (x--np.min(x))/(np.max(x)-np.min(x))
#最值歸一化矩陣 X = np.random.randint(0,100,(50,2)) #將矩陣改爲浮點型 X = np.array(X, dtype = float) #對其每一維度進行歸一化 X[:,0] = (X[:,0] - np.min(X[:,0])) /(np.max(X[:,0])-np.min(X[:,0])) X[:,0] X[:,1] = (X[:,1] - np.min(X[:,1])) /(np.max(X[:,1])-np.min(X[:,1])) X[:,1]
在均一化後可以通過繪製圖形顯示具體分佈情況。
均值方差歸一化實現:
X2 = np.random.randint(0,100,[50,2]) X2 = np.array(X2 , dtype = float) for i in range(0,2): X2[:,i] = (X2[:,i]-np.mean(X2[:,i]))/np.std(X2[:,i]) plt.scatter(X2[:,0],X2[:,1]) plt.show()
隨機函數:np.random.randint()
最小值:np.min()
最大值:np.max()
均值np.mean()
方差:np.std()
調整數組數值類型:np.array(data, dtype=’’)
-
Sklearn中的歸一化
在劃分訓練數據集和測試數據集,訓練數據集進行歸一化處理,計算了訓練數據集的均值和方差,在對測試數據集時使用的均值仍然是訓練集的,方差也是。歸一化:(x_test-mean_train)/std_train
sklearn中數據歸一化的方法:StandardScaler
import numpy as np from sklearn import datasets from sklearn.model_selection import train_test_split iris = datasets.load_iris() X = iris.data y = iris.target X_train, X_test ,y_train ,y_test = train_test_split(X,y,test_size = 0.2 ,random_state = 2)
from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt standardScaler = StandardScaler() #求得均值和方差 standardScaler.fit(X_train) standardScaler.mean_ standardScaler.scale_ #歸一化 X_train_standard = standardScaler.transform(X_train) X_test_standard = standardScaler.transform(X_test) plt.scatter(X_test[:,0],X_test[:,2]) plt.show()
求出每個列的均值:
self.mean_ = np.array([np.mean(X[:,i] for i in range(X.shape[1]))])
self.scale_ = np.array([np.std(X[:,i] for i in range(X.shape[1])])
創建一個空的浮點型矩陣,大小和X相同
np.empty(shape=X.shape, dtype= float)
計算每一列都計算
for col in range(X.shape[1]):
X[:,col] = (X[:,col]-self.mean[col])/self.scale_[col]
數據標準化原因:a. 算法要求數據是均值爲0,方差爲1;b. 消除樣本不同屬性具有不同量級時的影響。
數據標準化:條件:特徵服從正態分佈,標準化後轉換爲標準正態分佈
數據標準化定義:基於原始數據的均值和標準差,進行數據標準化。相當於對數據做變換,變換公式如下:
注:這裏均值和標準差是針對整個樣本集上的,而不是某個樣本。
這裏類似下面所說的均值歸一化(代碼實現也如下)。
優點:計算簡單;缺點:總體均值和方差獲得不方便,常使用樣本均值與標準差;要求正態分佈;存在異常值時無法保證結果。
MinMax歸一化
優缺點:當有新數據時需要重新計算最大最小值,更新數值,同時對異常值敏感。
MaxAbs歸一化:將數據轉換爲[-1,1]區間,且最大絕對值爲1.
MaxAbs也要與MinMax歸一化相類似問題。
3.正態分佈化Normalization
定義:將每個樣本縮放到單位範數。對每個樣本計算其p範數,然後對該樣本中每個元素除以該範數,結果是使每個處理後樣本的p-範數等於1.
在文本分析和聚類分析中常使用的向量空間模型常使用此內容。
p-範數:P-2 I2-norm:
歸一化與標準化對比(以後補上)
(2)數值型特徵分享-數據離散化(連續值特徵離散化)
1.無監督分箱法
自定義分箱:根據業務經驗或常識等自行設定劃分的區間,然後將原始數據劃分到各個區間中。
等距分箱:根據相同寬度將數據分成幾等份。類似頻率分佈直方圖,等間距,寬度相同。
pandas.cut可以吧一組數據分割成離散的區間
pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates=‘raise’) #0.23.4
x必須是一維的數據,不能用DataFrame,可以取dataframe裏面的一列;bins被切割後的區間,一個int型的標量、標量序列(數組)或者pandas.IntervalIndex 。
-
一個int型的標量
當bins爲一個int型的標量時,代表將x平分成bins份。x的範圍在每側擴展0.1%,以包括x的最大值和最小值。import numpy as np import pandas as pd ages = np.array([1,5,10,40,36,12,58,62,77,89,100,18,20,25,30,32]) df_ages = pd.cut(ages, 5) display(df_ages)
[(0.901, 20.8], (0.901, 20.8], (0.901, 20.8], (20.8, 40.6], (20.8, 40.6], ..., (0.901, 20.8], (0.901, 20.8], (20.8, 40.6], (20.8, 40.6], (20.8, 40.6]] Length: 16 Categories (5, interval[float64]): [(0.901, 20.8] < (20.8, 40.6] < (40.6, 60.4] < (60.4, 80.2] < (80.2, 100.0]]
很明顯,等距分箱極易受到異常值的影響。
等頻分箱:將數據分成幾等份,每等分中數據的個數相同。
pd.qcut(df[‘age’],3) 可以實現。
**聚類分箱:**K均值聚類法,將在聚類過程中保證分箱有序性,第一個分箱中所有觀測值都要小於第二個分箱中觀測值,第二個分箱中觀測值都要小於第三個分箱中觀測值
**二值化:**將數值feature進行閾值化得到boolean型數據。
from sklearn.preprocessing import Binarizer # Binarizer函數也可以設定一個閾值,結果數據值大於閾值的爲1,小於閾值的爲0 binarizer = Binarizer(threshold=5).fit(ages.reshape(-1,1)) binarizer.transform(ages.reshape(-1,1))
array([[0], [0], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]])
preprocessing.KBinsDiscretizer 這是將連續型變量劃分爲分類變量的類,能夠將連續型變量排序後按順序分箱後編碼
2.有監督分箱法
卡方分箱:
定義:自底向上的數據離散化方法。它依賴於卡方檢驗:具有最小卡方值的相鄰區間合併在一起,直到滿足確定的停止準則。如果兩個相鄰的區間具有非常類似的分佈,則這兩個區間可以合併;否則他們應當保持分開。
最小熵法分箱
這兩個概念有點難懂…
3.sklearn
摘自:https://www.cnblogs.com/juanjiang/archive/2019/05/30/10948849.html
模塊preprocessing 幾乎包含數據預處理的所有內容
模塊Impute填補缺失值專用
模塊feature_selection 包含特徵選擇的各種方法的實踐
模塊decomposition 包含降維算法
**缺失值:**當用於訓練的數據中含有缺失值時,可以通過
impute.SimpleImputer進行填補
class sklearn.impute.SimpleImputer
(missing_values=nan, strategy=’mean’, fill_value=None, verbose=0, copy=True)
missing_values :默認缺失值爲np.nan
stratepy填補缺失值的策略,默認爲均值mean ;median中值;most_frequent衆數,constant參考fill_value中的值(配合fill_value使用)
copy默認爲True,將創建特徵矩陣的副本,反之將缺失值填補到原本的特徵矩陣中去。
注:sklearn中特徵矩陣必須是二維的
Age = data.loc[:,"Age"].values.reshape(-1,1) #sklearn當中特徵矩陣必須是二維
Age[:20]
from sklearn.impute import SimpleImputer
imp_mean = SimpleImputer() #實例化,默認均值填補
imp_median = SimpleImputer(strategy="median") #用中位數填補
imp_0 = SimpleImputer(strategy="constant",fill_value=0) #用0填補
imp_mean = imp_mean.fit_transform(Age) #fit_transform一步完成調取結果
imp_median = imp_median.fit_transform(Age)
imp_0 = imp_0.fit_transform(Age)
imp_mean[:20]
imp_median[:20]
imp_0[:20]
#在這裏我們使用中位數填補Age
data.loc[:,"Age"] = imp_median
data.info()
#使用衆數填補Embarked
Embarked = data.loc[:,"Embarked"].values.reshape(-1,1)
imp_mode = SimpleImputer(strategy = "most_frequent")
data.loc[:,"Embarked"] = imp_mode.fit_transform(Embarked)
data.info()
使用pandas numpy 進行填補
#參考:
import pandas as pd
data = pd.read_csv(r"行行行ata.csv",index_col=0)
data.head()
data.loc[:,"Age"] = data.loc[:,"Age"].fillna(data.loc[:,"Age"].median())
#.fillna 在DataFrame裏面直接進行填補
data.dropna(axis=0,inplace=True)
#.dropna(axis=0)刪除所有有缺失值的行,.dropna(axis=1)刪除所有有缺失值的列
#參數inplace,爲True表示在原數據集上進行修改,爲False表示生成一個複製對象,不修改原數據,默認False
處理分類型特徵:編碼和啞變量
編碼:即將數據進行編碼,可以將文字型數據轉換爲數值型,方便只能處理數值型的算法進行運算。
preprocessing.LabelEncoder :標籤專業,能夠將分類轉換爲分類數值
一般的使用方法:先實例化,在fit導入數據,在調用transform接口調取結果,最終查看結果。
#舉例如下:
le = LabelEncoder() #實例化
le = le.fit(y) #導入數據
label = le.transform(y) #transform接口調取結果
le.classes_ #屬性.classes_查看標籤中究竟有多少類別
label #查看獲取的結果label
le.fit_transform(y) #也可以直接fit_transform一步到位
from sklearn.preprocessing import OrdinalEncoder
能夠將分類特徵轉換爲分類數值
preprocessing.OneHotEncoder :獨熱編碼,創建啞變量
啞變量這個概念…解決分類數據轉化爲數值後,能夠體現其中邏輯,不丟失信息的一種表示。
上圖參考自:https://www.cnblogs.com/juanjiang/archive/2019/05/30/10948849.html