數據預處理是我們在做機器學習之前必經的一個過程,在機器學習中常見的數據預處理包括缺失值處理,縮放數據以及對數據進行標準化處理這三個過程。
01|缺失值處理:缺失值處理是我們在做數據分析/機器學習過程中經常會遇到的問題,我們需要一種處理不完整數據的策略/方法。對缺失值處理有兩種方法,一種是直接對某一列中的缺失值進行處理,一種是根據類別標籤,分類別對缺失值進行處理。
我們先看如何在沒有類別標籤的情形下修補數據。比較簡單粗暴的方法就是直接忽略,也就是刪除缺失值,這種策略適用於數據集中缺失值佔比很小,去掉其以後對整體影響不大的情況。這裡需要注意的是刪除某一個缺失值時,需要把和該值一個維度/行的值也一起刪除,但是其他值可能對數據整體的影響比較大,所以用這種方法的時候要慎重。
一種可以避免這種情況的方法就是給缺失值賦予一個值,這個值一般就是該缺失值所在列的均值、中位數之類的。我們這裡用sklearn庫中的preprocessing模塊中的Imputer()函數來處理缺失值。
#加載庫
from sklearn.datasets import load_iris
from sklearn.preprocessing import Imputer
import numpy as np
import numpy.ma as ma
#加載數據集
data=load_iris()
x=data["data"]
y=data["target"]
#將原始數據複製一份
x_t=x.copy()
#在第2行製造一些缺失值
x_t[2,:]=np.repeat(0,x.shape[1])
#創建Imputer對象,採用平均值策略
imputer=Imputer(missing_values=0,strategy="mean")#先聲明一個替換策略
x_imputed=imputer.fit_transform(x_t)#讓x_t利用該策略
print(x_t)
製造缺失值以後的數據填充缺失以後的數據preprocessing.Imputer函數解釋:
sklearn.preprocessing.Imputer(missing_values=』NaN』, strategy=’mean』, axis=0, verbose=0, copy=True)
#missing_values為待替換的缺失值,可以為NaN,也可以為具體數值
#strategy為替換策略,有mean、medium、most_frequent分別表示均值、中位數、眾數三者來填充
#axis=0表示按列填充,1表示按行填充
#copy設置為False時表示不在原數據基礎上修改
關於Imputer的用法缺失值處理對應於pandas庫中的方法為dropna()刪除缺失值;fillna()填充缺失值。
dropna()默認刪除任何含有缺失值的行;傳入參數「how=」all」」表示刪除全是缺失值的行;傳入參數「axis=1」可刪除含有缺失值的列。
fillna()一般情況下會給定一個常數,會把數據集中的所有缺失值替換成該常數,比如fillna(0);也可以實現對不同列中的缺失值進行不同的替換,比如df.fillna({1:0.5,3:1})表示將第一列(從0開始計數)中的缺失值替換成0.5,第三列中的缺失值替換成1;傳入參數「inplace=True」表示對源數據進行修改。這裡面填充的具體的常數值也可以直接換為中位數,平均數之類的,比如df.fillna(data.mean())就表示用平均值填充。
我們有的時候可能需要根據類別(比如我們要根據性別這個分類來分別給身高這個缺失值進行填充)分別進行缺失值的處理,這個時候需要先把不同類別的數據找出來,這裡用的是np.where()函數,該函數在前面有提到,用該函數找出不同類別以後,處理方法就和不分類別處理的方法一致,只不過是根據類別的不同,處理的次數不同。
02|縮放數據:縮放數據集的目的是為了防止「大數吃小數」的現象發生,大數吃小數就類似於生活中同樣一個環境下聲音大的蓋過聲音小的,最後導致只能聽見聲音大的發聲,導致了最後的結果只考慮了聲音較大的那一部分,而忽略了聲音較小的那一部分,但實際中聲音小的也需要被聽到,為了防止這種聲音大的蓋過聲音小的現象的發聲,我們採取了一定的限制,就是把所有的聲音按照一定的規則限制在某一個區間內(在這個區間內,能夠保證不管聲音大小都會被聽到),你聲音再大也不能超過這個限制的最大值。我們把這個過程稱為數據的縮放(當然了,剛剛舉得那個例子是縮的方面)。
上面那個在生活中的例子,而在機器學習的學習過程中,也會有很多特徵之間出現上面大數吃小數的問題,所以我們在進行學習之前,需要先對數據進行預處理以後再進行學習。
#加載庫
import numpy as np
#生成待縮放的隨機數
np.random.seed(10)
x=[np.random.randint(10,25)*1.0 for i in range(10)]
#定義縮放函數
def min_max(x):
return([round((xx-min(x))/(1.0*(max(x)-min(x))),2) for xx in x])
#對給定的數據進行縮放
print(x)
print(min_max(x))
np.random.seed()#用於指定隨機數生成時所用算法開始的整數值。
np.random.randint(low,high=None,size=None)#生成在半開半閉區間[low,high)上離散均勻分布的整數值,若high=None,則取值區間變為[0,low)。
round(x,a)#用來返回浮點數的四捨五入值,x表示待處理的值,a表示保留的位數。
np.round()實例把數據縮放到(0,1)範圍內除了上面提到的自定義一個函數以外,還可以通過preprocessing.MinMaxScaler()進行實現。
關於preprocessing.MinMaxScaler的一些注意事項,該函數對象需要是多維數組&float類型數,要不然會報錯,雖然也能出來結果。
關於數據縮放:
通常情況下是把數據縮放到[0,1]區間內,公式是(x-min(x)/(max(x)-min(x)),我們上面用到的就是這種方式,當然了也可以將值縮放到任意區間內[nr_min,nr_max],公式是(x-min(x))/(max(x)-min(x))*(nr_max-nr_min)+nr_min
所謂的標準化就是將給定向量轉換成平均值為0,標準差為1的形式。公式如下:X=x-mean(value)/std(x)
#加載庫
import numpy as np
from sklearn.preprocessing import scale
#生成隨機數
np.random.seed(10)
x=[np.random.randint(10,25)*1.0 for i in range(10)]
#數據標準化
x_centered=scale(x,with_mean=True,with_std=False)
x_standard=scale(x,with_mean=True,with_std=True)
print("x:{}".format(x))
print("x_centered:{}".format(x_centered))
print("x_standard:{}".format(x_standard))
輸出結果如下:
x:[19.0, 23.0, 14.0, 10.0, 11.0, 21.0, 22.0, 19.0, 23.0, 10.0]
x_centered:[ 1.8 5.8 -3.2 -7.2 -6.2 3.8 4.8 1.8 5.8 -7.2]
x_standard:[ 0.35059022 1.12967961 -0.62327151 -1.4023609 -1.20758855 0.74013492
0.93490726 0.35059022 1.12967961 -1.4023609 ]
關於preprocessing.scale函數解釋:
sklearn.preprocessing.scale(X, axis=0, with_mean=True,with_std=True,copy=True)
#參數解釋:
#X:數組或者矩陣
#axis:int類型,初始值為0,axis用來計算均值 means 和標準方差 standard deviations. 如果是0,則單獨的標準化每個特徵(列),如果是1,則標準化每個觀測樣本(行)。
#with_mean: boolean類型,默認為True,表示將數據均值規範到0
#with_std: boolean類型,默認為True,表示將數據方差規範到1
縮放和標準化分別是歸一化的兩種不同方式。關於歸一化具體在機器學習中的應用,我們在之後再說。