特征放縮Feature Scaling
在運(yùn)用一些機(jī)器學(xué)習(xí)算法的時(shí)候不可避免地要對(duì)數(shù)據(jù)進(jìn)行特征縮放,比如:在隨機(jī)梯度下降(stochastic gradient descent)算法中,特征縮放有時(shí)能提高算法的收斂速度。
什么是特征縮放
特征縮放是用來(lái)標(biāo)準(zhǔn)化數(shù)據(jù)特征的范圍。
機(jī)器算法為什么要特征縮放
特征縮放還可以使機(jī)器學(xué)習(xí)算法工作的更好。比如在K近鄰算法中,分類器主要是計(jì)算兩點(diǎn)之間的歐幾里得距離,如果一個(gè)特征比其它的特征有更大的范圍值,那么距離將會(huì)被這個(gè)特征值所主導(dǎo)。因此每個(gè)特征應(yīng)該被歸一化,比如將取值范圍處理為0到1之間。
特征縮放的一些方法
調(diào)節(jié)比例(Rescaling)
這種方法是將數(shù)據(jù)的特征縮放到[0,1]或[-1,1]之間??s放到什么范圍取決于數(shù)據(jù)的性質(zhì)。對(duì)于這種方法的公式如下:x是最初的特征值, x′是縮放后的值。
![][equation2]
[equation2]: http://latex.codecogs.com/svg.latex?x'=\frac{x-min(x)}{max(x)-min(x)}標(biāo)準(zhǔn)化(Standardization)
特征標(biāo)準(zhǔn)化使每個(gè)特征的值有零均值(zero-mean)和單位方差(unit-variance)。這個(gè)方法在機(jī)器學(xué)習(xí)地算法中被廣泛地使用。例如:SVM,邏輯回歸和神經(jīng)網(wǎng)絡(luò)。這個(gè)方法的公式如下:
![][equation3]
[equation3]: http://latex.codecogs.com/svg.latex?x'=\frac{x-\bar{x}}{\sigma}
One-Hot Encoding
One-Hot編碼,主要是采用位狀態(tài)寄存器來(lái)對(duì)每個(gè)狀態(tài)進(jìn)行編碼,每個(gè)狀態(tài)都由他獨(dú)立的寄存器位,并且在任意時(shí)候只有一位有效。在實(shí)際的機(jī)器學(xué)習(xí)的應(yīng)用任務(wù)中,特征有時(shí)候并不總是連續(xù)值,有可能是一些分類值,如性別可分為“male”和“female”。
另外有些看似連續(xù)的特征實(shí)際上并不具有可加性。比如統(tǒng)計(jì)喝咖啡的偏好杯型,分[中杯,超大杯],如果我們誤認(rèn)為這是一個(gè)連續(xù)特征,那么我們會(huì)誤認(rèn)為該特征的均值是大杯,從而產(chǎn)生謬誤。
在機(jī)器學(xué)習(xí)任務(wù)中,對(duì)于這樣的特征,通常我們需要對(duì)其進(jìn)行特征數(shù)字化,如下面的例子:
有如下三個(gè)特征屬性:
性別:["male","female"]
地區(qū):["Europe","US","Asia"]
瀏覽器:["Firefox","Chrome","Safari","Internet Explorer"]
對(duì)于某一個(gè)樣本,如["male","US","Internet Explorer"],我們需要將這個(gè)分類值的特征數(shù)字化,最直接的方法,我們可以采用序列化的方式:[0,1,3]。但是這樣的特征處理并不能直接放入機(jī)器學(xué)習(xí)算法中。
One-Hot Encoding的處理方法
對(duì)于上述的問(wèn)題,性別的屬性是二維的,同理,地區(qū)是三維的,瀏覽器則是四維的,這樣,我們可以采用One-Hot編碼的方式對(duì)上述的樣本“["male","US","Internet Explorer"]”編碼,“male”則對(duì)應(yīng)著[1,0],同理“US”對(duì)應(yīng)著[0,1,0],“Internet Explorer”對(duì)應(yīng)著[0,0,0,1]。則完整的特征數(shù)字化的結(jié)果為:[1,0,0,1,0,0,0,0,1]。這樣導(dǎo)致的一個(gè)結(jié)果就是數(shù)據(jù)會(huì)變得非常的稀疏。
實(shí)際的Python代碼
sklearn中有現(xiàn)成的OneHot方法,直接調(diào)用即可。
首選對(duì)原本的特征進(jìn)行序列化編碼,然后一鍵完成OneHot。
enc = preprocessing.OneHotEncoder()
enc.fit([[0,0,3],[1,1,0],[0,2,1],[1,0,2]])
array = enc.transform([[0,1,3]]).toarray()
print array