學(xué)習(xí)sklearn和kagggle時(shí)遇到的問題,什么是獨(dú)熱編碼?為什么要用獨(dú)熱編碼吮螺?什么情況下可以用獨(dú)熱編碼?以及和其他幾種編碼方式的區(qū)別帕翻。
首先了解機(jī)器學(xué)習(xí)中的特征類別:連續(xù)型特征和離散型特征鸠补。
拿到獲取的原始特征,必須對(duì)每一特征分別進(jìn)行歸一化嘀掸,比如紫岩,特征A的取值范圍是[-1000,1000],特征B的取值范圍是[-1,1].如果使用logistic回歸睬塌,w1x1+w2x2泉蝌,因?yàn)閤1的取值太大了,所以x2基本起不了作用揩晴。所以勋陪,必須進(jìn)行特征的歸一化,每個(gè)特征都單獨(dú)進(jìn)行歸一化文狱。
對(duì)于連續(xù)性特征:
Rescale bounded continuous features: All continuous input that are bounded, rescale them to [-1, 1] through x = (2x - max - min)/(max - min). 線性放縮到[-1,1]
Standardize all continuous features: All continuous input should be standardized and by this I mean, for every continuous feature, compute its mean (u) and standard deviation (s) and do x = (x - u)/s. 放縮到均值為0粥鞋,方差為1
Binarize categorical/discrete features: 對(duì)于離散的特征基本就是按照one-hot(獨(dú)熱)編碼缘挽,該離散特征有多少取值瞄崇,就用多少維來表示該特征。
一. 什么是獨(dú)熱編碼壕曼?
獨(dú)熱碼苏研,在英文文獻(xiàn)中稱做 one-hot code, 直觀來說就是有多少個(gè)狀態(tài)就有多少比特,而且只有一個(gè)比特為1腮郊,其他全為0的一種碼制摹蘑。舉例如下:
假如有三種顏色特征:紅、黃轧飞、藍(lán)衅鹿。 在利用機(jī)器學(xué)習(xí)的算法時(shí)一般需要進(jìn)行向量化或者數(shù)字化撒踪。那么你可能想令 紅=1,黃=2大渤,藍(lán)=3. 那么這樣其實(shí)實(shí)現(xiàn)了標(biāo)簽編碼制妄,即給不同類別以標(biāo)簽。然而這意味著機(jī)器可能會(huì)學(xué)習(xí)到“紅<黃<藍(lán)”泵三,但這并不是我們的讓機(jī)器學(xué)習(xí)的本意耕捞,只是想讓機(jī)器區(qū)分它們,并無大小比較之意烫幕。所以這時(shí)標(biāo)簽編碼是不夠的俺抽,需要進(jìn)一步轉(zhuǎn)換。因?yàn)橛腥N顏色狀態(tài)较曼,所以就有3個(gè)比特磷斧。即紅色:1 0 0 ,黃色: 0 1 0诗芜,藍(lán)色:0 0 1 瞳抓。如此一來每?jī)蓚€(gè)向量之間的距離都是根號(hào)2,在向量空間距離都相等伏恐,所以這樣不會(huì)出現(xiàn)偏序性孩哑,基本不會(huì)影響基于向量空間度量算法的效果。
自然狀態(tài)碼為:
000,001,010,011,100,101
獨(dú)熱編碼為:
000001,000010,000100,001000,010000,100000
來一個(gè)sklearn的例子:
from sklearn import preprocessing
enc = preprocessing.OneHotEncoder()
enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]) # fit來學(xué)習(xí)編碼
enc.transform([[0, 1, 3]]).toarray() # 進(jìn)行編碼
輸出:array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]])
數(shù)據(jù)矩陣是4*3翠桦,即4個(gè)數(shù)據(jù)横蜒,3個(gè)特征維度。
0 0 3 觀察左邊的數(shù)據(jù)矩陣销凑,第一列為第一個(gè)特征維度丛晌,有兩種取值0\1. 所以對(duì)應(yīng)編碼方式為10 、01
1 1 0 同理斗幼,第二列為第二個(gè)特征維度澎蛛,有三種取值0\1\2,所以對(duì)應(yīng)編碼方式為100蜕窿、010谋逻、001
0 2 1 同理,第三列為第三個(gè)特征維度桐经,有四中取值0\1\2\3毁兆,所以對(duì)應(yīng)編碼方式為1000、0100阴挣、0010气堕、0001
1 0 2
再來看要進(jìn)行編碼的參數(shù)[0 , 1, 3], 0作為第一個(gè)特征編碼為10, 1作為第二個(gè)特征編碼為010, 3作為第三個(gè)特征編碼為0001. 故此編碼結(jié)果為 1 0 0 1 0 0 0 0 1
二. 為什么要獨(dú)熱編碼茎芭?
正如上文所言揖膜,獨(dú)熱編碼(啞變量 dummy variable)是因?yàn)榇蟛糠炙惴ㄊ腔谙蛄靠臻g中的度量來進(jìn)行計(jì)算的,為了使非偏序關(guān)系的變量取值不具有偏序性梅桩,并且到圓點(diǎn)是等距的次氨。使用one-hot編碼,將離散特征的取值擴(kuò)展到了歐式空間摘投,離散特征的某個(gè)取值就對(duì)應(yīng)歐式空間的某個(gè)點(diǎn)煮寡。將離散型特征使用one-hot編碼,會(huì)讓特征之間的距離計(jì)算更加合理犀呼。離散特征進(jìn)行one-hot編碼后幸撕,編碼后的特征,其實(shí)每一維度的特征都可以看做是連續(xù)的特征外臂。就可以跟對(duì)連續(xù)型特征的歸一化方法一樣坐儿,對(duì)每一維特征進(jìn)行歸一化。比如歸一化到[-1,1]或歸一化到均值為0,方差為1宋光。
為什么特征向量要映射到歐式空間貌矿?
將離散特征通過one-hot編碼映射到歐式空間,是因?yàn)樽锛眩诨貧w逛漫,分類,聚類等機(jī)器學(xué)習(xí)算法中赘艳,特征之間距離的計(jì)算或相似度的計(jì)算是非常重要的酌毡,而我們常用的距離或相似度的計(jì)算都是在歐式空間的相似度計(jì)算,計(jì)算余弦相似性蕾管,基于的就是歐式空間枷踏。
三 .獨(dú)熱編碼優(yōu)缺點(diǎn)
優(yōu)點(diǎn):獨(dú)熱編碼解決了分類器不好處理屬性數(shù)據(jù)的問題,在一定程度上也起到了擴(kuò)充特征的作用掰曾。它的值只有0和1旭蠕,不同的類型存儲(chǔ)在垂直的空間。
缺點(diǎn):當(dāng)類別的數(shù)量很多時(shí)旷坦,特征空間會(huì)變得非常大掏熬。在這種情況下,一般可以用PCA來減少維度塞蹭。而且one hot encoding+PCA這種組合在實(shí)際中也非常有用孽江。
四. 什么情況下(不)用獨(dú)熱編碼讶坯?
用:獨(dú)熱編碼用來解決類別型數(shù)據(jù)的離散值問題番电,
不用:將離散型特征進(jìn)行one-hot編碼的作用,是為了讓距離計(jì)算更合理,但如果特征是離散的漱办,并且不用one-hot編碼就可以很合理的計(jì)算出距離这刷,那么就沒必要進(jìn)行one-hot編碼。 有些基于樹的算法在處理變量時(shí)娩井,并不是基于向量空間度量暇屋,數(shù)值只是個(gè)類別符號(hào),即沒有偏序關(guān)系洞辣,所以不用進(jìn)行獨(dú)熱編碼咐刨。 Tree Model不太需要one-hot編碼: 對(duì)于決策樹來說,one-hot的本質(zhì)是增加樹的深度扬霜。
總的來說定鸟,要是one hot encoding的類別數(shù)目不太多,建議優(yōu)先考慮著瓶。
五. 什么情況下(不)需要?dú)w一化联予?
需要: 基于參數(shù)的模型或基于距離的模型,都是要進(jìn)行特征的歸一化材原。
不需要:基于樹的方法是不需要進(jìn)行特征的歸一化沸久,例如隨機(jī)森林,bagging 和 boosting等余蟹。
六. 標(biāo)簽編碼LabelEncoder
作用: 利用LabelEncoder() 將轉(zhuǎn)換成連續(xù)的數(shù)值型變量卷胯。即是對(duì)不連續(xù)的數(shù)字或者文本進(jìn)行編號(hào)例如:
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit([1,5,67,100])
le.transform([1,1,100,67,5])
輸出: array([0,0,3,2,1])
>>> le = preprocessing.LabelEncoder()
>>> le.fit(["paris", "paris", "tokyo", "amsterdam"])
LabelEncoder()
>>> list(le.classes_)
['amsterdam', 'paris', 'tokyo'] # 三個(gè)類別分別為0 1 2
>>> le.transform(["tokyo", "tokyo", "paris"])
array([2, 2, 1]...)
>>> list(le.inverse_transform([2, 2, 1])) # 逆過程
['tokyo', 'tokyo', 'paris']
限制:上文顏色的例子已經(jīng)提到標(biāo)簽編碼了。Label encoding在某些情況下很有用威酒,但是場(chǎng)景限制很多诵竭。再舉一例:比如有[dog,cat,dog,mouse,cat],我們把其轉(zhuǎn)換為[1,2,1,3,2]兼搏。這里就產(chǎn)生了一個(gè)奇怪的現(xiàn)象:dog和mouse的平均值是cat卵慰。所以目前還沒有發(fā)現(xiàn)標(biāo)簽編碼的廣泛使用。
附:基本的機(jī)器學(xué)習(xí)過程
我們使用sklearn進(jìn)行虛線框內(nèi)的工作(sklearn也可以進(jìn)行文本特征提确鹕搿)裳朋。通過分析sklearn源碼,我們可以看到除訓(xùn)練吓著,預(yù)測(cè)和評(píng)估以外鲤嫡,處理其他工作的類都實(shí)現(xiàn)了3個(gè)方法:fit、transform和fit_transform绑莺。從命名中可以看到暖眼,fit_transform方法是先調(diào)用fit然后調(diào)用transform,我們只需要關(guān)注fit方法和transform方法即可纺裁。
transform方法主要用來對(duì)特征進(jìn)行轉(zhuǎn)換诫肠。從可利用信息的角度來說司澎,轉(zhuǎn)換分為無信息轉(zhuǎn)換和有信息轉(zhuǎn)換。無信息轉(zhuǎn)換是指不利用任何其他信息進(jìn)行轉(zhuǎn)換栋豫,比如指數(shù)挤安、對(duì)數(shù)函數(shù)轉(zhuǎn)換等。有信息轉(zhuǎn)換從是否利用目標(biāo)值向量又可分為無監(jiān)督轉(zhuǎn)換和有監(jiān)督轉(zhuǎn)換丧鸯。無監(jiān)督轉(zhuǎn)換指只利用特征的統(tǒng)計(jì)信息的轉(zhuǎn)換蛤铜,統(tǒng)計(jì)信息包括均值、標(biāo)準(zhǔn)差丛肢、邊界等等围肥,比如標(biāo)準(zhǔn)化、PCA法降維等蜂怎。有監(jiān)督轉(zhuǎn)換指既利用了特征信息又利用了目標(biāo)值信息的轉(zhuǎn)換虐先,比如通過模型選擇特征、LDA法降維等派敷。通過總結(jié)常用的轉(zhuǎn)換類蛹批,我們得到下表:
不難看到,只有有信息的轉(zhuǎn)換類的fit方法才實(shí)際有用篮愉,顯然fit方法的主要工作是獲取特征信息和目標(biāo)值信息腐芍,在這點(diǎn)上,fit方法和模型訓(xùn)練時(shí)的fit方法就能夠聯(lián)系在一起了:都是通過分析特征和目標(biāo)值试躏,提取有價(jià)值的信息猪勇,對(duì)于轉(zhuǎn)換類來說是某些統(tǒng)計(jì)量,對(duì)于模型來說可能是特征的權(quán)值系數(shù)等颠蕴。另外泣刹,只有有監(jiān)督的轉(zhuǎn)換類的fit和transform方法才需要特征和目標(biāo)值兩個(gè)參數(shù)。fit方法無用不代表其沒實(shí)現(xiàn)犀被,而是除合法性校驗(yàn)以外椅您,其并沒有對(duì)特征和目標(biāo)值進(jìn)行任何處理,Normalizer的fit方法實(shí)現(xiàn)如下:
def fit(self, X, y=None):
"""Do nothing and return the estimator unchanged
This method is just there to implement the usual API and hence
work in pipelines.
"""
X = check_array(X, accept_sparse='csr')
return self
轉(zhuǎn)自:https://blog.csdn.net/ccblogger/article/details/80010974