完整代碼: https://github.com/cindycindyhi/kaggle-Titanic
特征工程系列:
Titanic系列之原始數(shù)據(jù)分析和數(shù)據(jù)處理
缺失值填充之后,就要對(duì)其他格式有問(wèn)題的屬性進(jìn)行處理了。比如Sex Embarked這些屬性的值都是字符串類(lèi)型的,而scikit learn中的模型都只能處理數(shù)值型的數(shù)據(jù),需要將這些原始的字符串類(lèi)型的數(shù)據(jù)轉(zhuǎn)為數(shù)值型數(shù)據(jù)。所有數(shù)據(jù)通??梢苑殖蓛煞N類(lèi)型:定量與定性。定量的屬性(數(shù)值屬性)通常蘊(yùn)涵著可排序性,比如在泰坦尼克號(hào)數(shù)據(jù)集中,年齡就是一個(gè)定量屬性。定性屬性(標(biāo)稱(chēng) 序數(shù) 二元屬性)的值是一些符號(hào)或事務(wù)的名稱(chēng),每個(gè)值代表某種類(lèi)別編碼或狀態(tài),不是可測(cè)量量,是不具有排序意義的,比如Embarked(登船地點(diǎn))。
一 定性屬性的數(shù)據(jù)變換
對(duì)于字符串型的定性屬性轉(zhuǎn)換,如果單純的用數(shù)字來(lái)代替的化,比如對(duì)于Embarked的三個(gè)值S Q C分別用1 2 3來(lái)代替,模型會(huì)把它當(dāng)成是有順序的數(shù)值屬性,對(duì)于一些根據(jù)距離來(lái)確定分類(lèi)的算法來(lái)說(shuō),就不能準(zhǔn)確運(yùn)行啦。那么應(yīng)該怎么將定性屬性轉(zhuǎn)為數(shù)字呢?
(1)dummy varibles(不知道中文應(yīng)該說(shuō)成啥。。虛設(shè)屬性?)
什么是dummy呢,舉個(gè)栗子,Emarked屬性的取值有三個(gè)S Q C,分別代表三個(gè)上船地點(diǎn)。dummy這個(gè)屬性呢,就是向數(shù)據(jù)集里再加入三個(gè)屬性暫且命名為Embarked_S Embarkde_Q 和Embarked_C,如果一個(gè)人是在S地點(diǎn)上船的,那么這三個(gè)屬性的值就是(1,0,0),在Q點(diǎn)上船的就是(0,1,0),每個(gè)屬性都是二元屬性,1代表是,0代表否。所以dummy適用于值范圍相對(duì)較少的屬性。
1 import pandas as pd
#creat dummy varibles from raw data2 dummies_df = pd.get_dummies(df.Embarked)3 #remana the columns to Embarked_S...4 dummies_df = dummies_df.rename(columns=lambda x:'Embarked_'+str(x))5 df = pd.concat([df,dummies_df],axis=1)
這樣就會(huì)3個(gè)dummy屬性加到數(shù)據(jù)集里啦,用df.info()看一下:
(2)factorizing(因子分解?)
用dummy可以處理像Embarked這樣的值域范圍較小的標(biāo)稱(chēng)屬性。對(duì)于Cabin(船艙號(hào),A43 B55這種)這種標(biāo)稱(chēng)屬性,用dummy就不好處理了。pandas提供了一個(gè)factorize()函數(shù),用以將標(biāo)稱(chēng)屬性的字符串值映射為一個(gè)數(shù)字,相同的字符串映射為同一個(gè)數(shù)字。不同于dummy,這種映射最后只生成一個(gè)屬性。對(duì)于Cabin屬性,我們可以將其分成兩部分,字符串+數(shù)字,新建兩個(gè)屬性。對(duì)于字符串(A-E & U),可以用factorize()將其處理成數(shù)字。
1 import re2 df['CabinLetter'] = df['Cabin'].map( lambda x: re.compile("([a-zA-Z]+)")./3 search(x).group() )4 df['CabinLetter'] = pd.factorize(df.CabinLetter)[0]
上一步呢,只是把Cabin船艙號(hào)前面的字母提出來(lái)作為一個(gè)新的屬性,船艙號(hào)中的數(shù)字當(dāng)然也要提出來(lái)作為一個(gè)新的屬性啦。
1 #plus one for laplace assumption2 df['CabinNumber'] = df['Cabin'].map( lambda x: getCabinNumber(x) )./3 astype(int) +14 def getCabinNumber(cabin):5 match = re.compile("([0-9]+)").search(cabin)6 if match:7 return match.group()8 else:9 return 0
二 定量屬性的數(shù)據(jù)變換
(1)數(shù)據(jù)規(guī)范化
數(shù)據(jù)規(guī)范化通過(guò)將數(shù)據(jù)壓縮到一個(gè)范圍內(nèi)(通常是0-1或者-1-1)賦予所有屬性相等的權(quán)重。對(duì)于涉及神經(jīng)網(wǎng)絡(luò)的分類(lèi)算法或者基于距離度量的分類(lèi)和聚類(lèi),規(guī)范化特別有用。規(guī)范化方法有多種,如rescaling logarithmic normalize等,可以在這里找到各種規(guī)范化方法的具體實(shí)現(xiàn)。但是有些時(shí)候并不需要規(guī)范化,比如算法使用相似度函數(shù)而不是距離函數(shù)的時(shí)候,比如隨機(jī)森林,它從不比較一個(gè)特征與另一個(gè)特征,因此也不許要規(guī)范化,關(guān)于這個(gè)問(wèn)題,詳細(xì)信息可以參考這篇文章www.faqs.org/faqs/ai-faq/neural-nets/part2/section-16.html
如果對(duì)Age屬性進(jìn)行規(guī)范化的話(huà)(看最后分類(lèi)算法使用哪種再確定要不要規(guī)范化,如果要規(guī)范化的話(huà),其他屬性也要處理),代碼如下:
1 if keep_scaled:2 scaler = PReprocessing.StandardScaler()3 df['Age_Scaled'] = scaler.fit_transform(df['Age'])
StandardScaler將數(shù)值壓縮到[-1,1]區(qū)間,計(jì)算公式為(2x - max(x) - min(x)) / (max(x) - min(x)).
(2)Binning
就像直方圖的bin將數(shù)據(jù)劃分成幾塊一樣,我們也可以將數(shù)值屬性劃分成幾個(gè)bin,這是一種連續(xù)數(shù)據(jù)離散化的處理方式。我們使用pandas.qcut()函數(shù)來(lái)離散化連續(xù)數(shù)據(jù),它使用分位數(shù)對(duì)數(shù)據(jù)進(jìn)行劃分,可以得到大小基本相等的bin。以下以Fare(船票價(jià)格)為例,對(duì)于其他連續(xù)屬性如Age SibSp等也可以劃分成bin。
1 def processFare():2 global df3 df['Fare'][df.Fare.isnull()] = df.Fare.dropna().mean()4 #zero values divide -- laplace5 df['Fare'][np.where(df['Fare']==0)[0]] = df['Fare'][df.Fare./6 nonzero()[0] ].min() / 107 df['Fare_bin'] = pd.qcut(df.Fare, 4)
這樣產(chǎn)生的df['Fare_bin']的值是這樣的,
0 [0.401, 7.91] 3 (31, 512.329]
1 (31, 512.329] 4 (7.91, 14.454]
2 (7.91, 14.454] 5 (7.91, 14.454]
因?yàn)槭莃in,所以屬性都是一個(gè)個(gè)區(qū)間,代表這個(gè)數(shù)據(jù)屬于哪個(gè)區(qū)間。對(duì)于這樣的數(shù)據(jù),我們需要factorize下,轉(zhuǎn)為數(shù)值型數(shù)據(jù)。
1 df['Fare_bin_id'] = pd.factorize(df.Fare_bin)[0]+12 scaler = preprocessing.StandardScaler()3 df['Fare_bin_id_scaled'] = scaler.fit_transform(df.Fare_bin_id)
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注