Re:從零開始的機器學習 - Titanic: Machine Learning from Disaster

樑王發表於2018-07-04

前言

本文以Kaggle比賽Titanic入手,介紹了特徵工程的幾個方法,最後訓練了三個模型(RF,GBDT,SVM)並使用了一個整合方法(Voting Classifier)進行預測。

完整程式碼及資料可以在ReMachineLearning(titanic) - Github中獲取

正文

下面是kaggle對於這個比賽的介紹。

The sinking of the RMS Titanic is one of the most infamous shipwrecks in history. On April 15, 1912, during her maiden voyage, the Titanic sank after colliding with an iceberg, killing 1502 out of 2224 passengers and crew. This sensational tragedy shocked the international community and led to better safety regulations for ships.

One of the reasons that the shipwreck led to such loss of life was that there were not enough lifeboats for the passengers and crew. Although there was some element of luck involved in surviving the sinking, some groups of people were more likely to survive than others, such as women, children, and the upper-class.

In this challenge, we ask you to complete the analysis of what sorts of people were likely to survive. In particular, we ask you to apply the tools of machine learning to predict which passengers survived the tragedy.

簡單來說就是已知乘客的各種資訊,去推斷這名乘客是否會倖存的一個二分類問題。

本文首先使用特徵工程的一些方法,然後使用隨機森林(Random Forests),GBDT(Gradient Boosting Decision Tree)和SVM(Support Vector Machine)作為訓練模型,最後用了投票分類器(Voting Classifier)整合方法做了模型的整合。

本文基於Python 3、sklearn以及Pandas(強烈建議按照Anaconda),資料來源於Kaggle,程式碼以及資料都可以在Github上獲取

資料結構

先簡單介紹下給的訓練資料的csv結構

PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
1,0,3,"Braund, Mr. Owen Harris",male,22,1,0,A/5 21171,7.25,,S
2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C
3,1,3,"Heikkinen, Miss. Laina",female,26,0,0,STON/O2. 3101282,7.925,,S
4,1,1,"Futrelle, Mrs. Jacques Heath (Lily May Peel)",female,35,1,0,113803,53.1,C123,S
複製程式碼
  • PassengerID(ID)
  • Survived(存活與否)
  • Pclass(客艙等級)
  • Name(名字)
  • Sex(性別)
  • Age(年齡)
  • Parch(子女父母關係人數)
  • SibSp(兄弟姐妹關係人數)
  • Ticket(票編號)
  • Fare(票價)
  • Cabin(客艙編號)
  • Embarked(上船的港口編號)

資料預處理

Sex

從資料裡面可以看到資料中性別(Sex)是一個列舉字串malefemale,為了讓計算機更好的處理這列資料,我們將其數值化處理

# API文件 https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.map.html
# map方法數字化處理並改變pandas的列型別
df['Sex'] = df['Sex'].map({'female': 1, 'male': 0}).astype(int)
複製程式碼

資料補全

df.info()可以簡單的發現哪類資料是不全的

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId    891 non-null int64
Survived       891 non-null int64
Pclass         891 non-null int64
Name           891 non-null object
Sex            891 non-null int64
Age            714 non-null float64
SibSp          891 non-null int64
Parch          891 non-null int64
Ticket         891 non-null object
Fare           891 non-null float64
Cabin          204 non-null object
Embarked       889 non-null object
dtypes: float64(2), int64(6), object(4)
memory usage: 83.6+ KB
複製程式碼

可以發現Age、Cabin,Embarked資訊是不全的,這時候我們需要對這些進行補全。對於機器學習如何處理缺失資料的理論學習可以參考連結中的內容

在這裡例子裡面我的解決方法是:

  1. Age的缺失值使用中位數補全。其實另一個合理的方法是建立一個模型來利用資料來“預測”缺失的資料。比如Age其實和Fare以及Pclass等有一定的聯絡(我這種萌新一般都是經ji艙)。

Parch 與 Sibsp

Sibsp指的是一同乘船的兄弟姐妹或配偶,Parch指的是一同乘船的父母或兒女。

新增familysize列作為sibsp和parch的和,代表總的家庭成員數。 這種從原始資料中挖掘隱藏屬性或屬性組合的方法叫做派生屬性。但是這些挖掘出來的特徵有幾個問題:

  1. 這些特徵間具有多重共線性,可能會導致空間的不穩定;
  2. 高維空間本身具有稀疏性,一維正態分佈有68%的值落於正負標準差之間,而在十維空間上只有0.02%;
  3. 過多的屬性會加大計算量。所以要用到資料歸約技術(降維),歸約後的資料集小得多,但基本保持原始資料的完整性。

其實這裡我有些沒有理解為什麼要把Sibsp和Parch相加為Familysize,我沒法解釋這樣做的合理性。

Fare

Fare指的是票價

資料探索分析

拿到資料後我們首先要做的是分析資料及特徵。

特徵相關性分析(feature correlations)

pandas可以通過DataFrame的corr方法計算資料的相關係數(方法包括三種:pearson,kendall,spearman),這裡也不擴充套件,反正能夠計算出資料之間的相關性。

# API文件 https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.corr.html
def plot_corr(df,size=10):
    '''Function plots a graphical correlation matrix for each pair of columns in the dataframe.

    Input:
        df: pandas DataFrame
        size: vertical and horizontal size of the plot'''

    corr = df.corr()
    fig, ax = plt.subplots(figsize=(size, size))
    ax.matshow(corr)
    for (i, j), z in np.ndenumerate(corr):
        ax.text(j, i, '{:.2f}'.format(z), ha='center', va='center')
    plt.xticks(range(len(corr.columns)), corr.columns)
    plt.yticks(range(len(corr.columns)), corr.columns)

# 特徵相關性圖表
plot_corr(df)
複製程式碼

Re:從零開始的機器學習 - Titanic: Machine Learning from Disaster
可以看到Survived(存活)與Pclass還有Sex以及Fare的關聯比較大,而和PassengerId幾乎沒有關係。所以我們基本可以把PassengerId刪了。

模型

之前也說到了我們會用到三個模型以及一個整合方法,這塊沒有什麼好細說的。

使用了隨機森林(Random Forests),GBDT(Gradient Boosting Decision Tree)和SVM(Support Vector Machine)作為訓練模型,最後用了投票分類器(Voting Classifier)整合方法做了模型的整合

結果

使用Voting以及單個模型的得分如下:

Re:從零開始的機器學習 - Titanic: Machine Learning from Disaster

後記

這篇博文裡面涉及的演算法每一個我後期都會單獨寫一篇博文(坑我先挖了),這篇部落格從開始寫到現在差不多2個月了=,=,中間斷了一次現在才寫完。

參考資料

從決策樹到隨機森林:樹型演算法的原理與實現

Kaggle比賽經驗總結之Titanic: Machine Learning from Disaster

Kaggle 入門 1.3——Titanic Solution Using speedml

相關文章