kaggle數據挖掘競賽初步--Titanic<數據變換>

完整代碼: https://github.com/cindycindyhi/kaggle-Titanichtml

特徵工程系列:git

Titanic系列之原始數據分析和數據處理github

Titanic系列之數據變換算法

Titanic系列之派生屬性&維歸約網絡

缺失值填充以後,就要對其餘格式有問題的屬性進行處理了。好比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)
相關文章
相關標籤/搜索