完整代碼: https://github.com/cindycindyhi/kaggle-Titanichtml
特徵工程系列:git
Titanic系列之原始數據分析和數據處理github
缺失值填充以後,就要對其餘格式有問題的屬性進行處理了。好比Sex Embarked這些屬性的值都是字符串類型的,而scikit learn中的模型都只能處理數值型的數據,須要將這些原始的字符串類型的數據轉爲數值型數據。全部數據一般能夠分紅兩種類型:定量與定性。定量的屬性(數值屬性)一般蘊涵着可排序性,好比在泰坦尼克號數據集中,年齡就是一個定量屬性。定性屬性(標稱 序數 二元屬性)的值是一些符號或事務的名稱,每一個值表明某種類別編碼或狀態,不是可測量量,是不具備排序意義的,好比Embarked(登船地點)。ide
一 定性屬性的數據變換函數
對於字符串型的定性屬性轉換,若是單純的用數字來代替的化,好比對於Embarked的三個值S Q C分別用1 2 3來代替,模型會把它當成是有順序的數值屬性,對於一些根據距離來肯定分類的算法來講,就不能準確運行啦。那麼應該怎麼將定性屬性轉爲數字呢?編碼
(1)dummy varibles(不知道中文應該說成啥。。虛設屬性?)spa
什麼是dummy呢,舉個栗子,Emarked屬性的取值有三個S Q C,分別表明三個上船地點。dummy這個屬性呢,就是向數據集裏再加入三個屬性暫且命名爲Embarked_S Embarkde_Q 和Embarked_C,若是一我的是在S地點上船的,那麼這三個屬性的值就是(1,0,0),在Q點上船的就是(0,1,0),每一個屬性都是二元屬性,1表明是,0表明否。因此dummy適用於值範圍相對較少的屬性。code
1 import pandas as pd
#creat dummy varibles from raw data 2 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)
這樣就會3個dummy屬性加到數據集裏啦,用df.info()看一下:
(2)factorizing(因子分解?)
用dummy能夠處理像Embarked這樣的值域範圍較小的標稱屬性。對於Cabin(船艙號,A43 B55這種)這種標稱屬性,用dummy就很差處理了。pandas提供了一個factorize()函數,用以將標稱屬性的字符串值映射爲一個數字,相同的字符串映射爲同一個數字。不一樣於dummy,這種映射最後只生成一個屬性。對於Cabin屬性,咱們能夠將其分紅兩部分,字符串+數字,新建兩個屬性。對於字符串(A-E & U),能夠用factorize()將其處理成數字。
1 import re 2 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船艙號前面的字母提出來做爲一個新的屬性,船艙號中的數字固然也要提出來做爲一個新的屬性啦。
1 #plus one for laplace assumption 2 df['CabinNumber'] = df['Cabin'].map( lambda x: getCabinNumber(x) ).\ 3 astype(int) +1 4 def getCabinNumber(cabin): 5 match = re.compile("([0-9]+)").search(cabin) 6 if match: 7 return match.group() 8 else: 9 return 0
二 定量屬性的數據變換
(1)數據規範化
數據規範化經過將數據壓縮到一個範圍內(一般是0-1或者-1-1)賦予全部屬性相等的權重。對於涉及神經網絡的分類算法或者基於距離度量的分類和聚類,規範化特別有用。規範化方法有多種,如rescaling logarithmic normalize等,能夠在這裏找到各類規範化方法的具體實現。可是有些時候並不須要規範化,好比算法使用類似度函數而不是距離函數的時候,好比隨機森林,它從不比較一個特徵與另外一個特徵,所以也不準要規範化,關於這個問題,詳細信息能夠參考這篇文章www.faqs.org/faqs/ai-faq/neural-nets/part2/section-16.html
若是對Age屬性進行規範化的話(看最後分類算法使用哪一種再肯定要不要規範化,若是要規範化的話,其餘屬性也要處理),代碼以下:
1 if keep_scaled: 2 scaler = preprocessing.StandardScaler() 3 df['Age_Scaled'] = scaler.fit_transform(df['Age'])
StandardScaler將數值壓縮到[-1,1]區間,計算公式爲(2x - max(x) - min(x)) / (max(x) - min(x)).
(2)Binning
就像直方圖的bin將數據劃分紅幾塊同樣,咱們也能夠將數值屬性劃分紅幾個bin,這是一種連續數據離散化的處理方式。咱們使用pandas.qcut()函數來離散化連續數據,它使用分位數對數據進行劃分,能夠獲得大小基本相等的bin。如下以Fare(船票價格)爲例,對於其餘連續屬性如Age SibSp等也能夠劃分紅bin。
1 def processFare(): 2 global df 3 df['Fare'][df.Fare.isnull()] = df.Fare.dropna().mean() 4 #zero values divide -- laplace 5 df['Fare'][np.where(df['Fare']==0)[0]] = df['Fare'][df.Fare.\ 6 nonzero()[0] ].min() / 10 7 df['Fare_bin'] = pd.qcut(df.Fare, 4)
這樣產生的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]
由於是bin,因此屬性都是一個個區間,表明這個數據屬於哪一個區間。對於這樣的數據,咱們須要factorize下,轉爲數值型數據。
1 df['Fare_bin_id'] = pd.factorize(df.Fare_bin)[0]+1 2 scaler = preprocessing.StandardScaler() 3 df['Fare_bin_id_scaled'] = scaler.fit_transform(df.Fare_bin_id)