The practical guide to Random Forests – Big Data Exploration Part II
(Using Kaggle’s Titanic Data with R code)


Photo source: http://www.pageresource.com/wallpapers/wallpaper/fantasy-solaris-sea-moon.jpg

Part I的連結在此
上一篇文章介紹了R data.table Query功能,這篇將繼續完成data.table的介紹,最後會利用data.table進行分析和建立預測模型。

Summarizing Data Within Groups


data.table的優勢在於data aggregation能力, 並且可以和R的繪圖package – ggplot2整合, 圖像化數據結果。結合data.tableggplot2兩個package, 讓我們擁有一個全新的強大數據探勘分析工具。

 

首先, 我們想知道Titanic資料中, 男女生分別的平均年齡; 使用na.omit指令, 可以在計算平均數時排除AgeNA的資料。 

dtTrain[,mean(na.omit(Age)),by=Sex]
在彙整計算時, 同樣能進行資料的篩選; 例如只想知道Pclass這個欄位為1的資料中, 男女生分別的平均年齡。

dtTrain[Pclass==1,mean(na.omit(Age)),by=Sex]

一樣,可以將上列程式碼轉換理解為如下SQL:  
SELECT  Sex,mean(Age) 
   FROM  dtTrain
   WHERE Pclass=1
   AND    Age IS NOT NA
   GROUP BY Sex
針對data aggregation結果欄位名稱, data.table是用代號顯示;我們可以自行命名為有意義的欄位名稱。data aggregation可以一次進行多種計算。

dtTrain[,list(avg_Age=mean(na.omit(Age)) ,max_Age=max(na.omit(Age)) ),by=Sex]
(Optional step)針對較大的數據集, 可以使用setkey function 加速數據的運算
setkey(dtTrain, Sex)


學會了data.table的運算操作後, 我們可以開始進行數據分析了。Trevor Stephens的原文中針對Titanic資料, 使用了下列想法進行數據的預測。

首先, 根據對於Titanic事件的了解, 我們會猜測是否女性的passenger生還機率比較高? Trevor Stephens使用tableprop.table指令, 檢視女性passenger生還比率
summary(train$Sex)
prop.table(table(train$Sex, train$Survived)
prop.table指令的Default設定是計算每一個entry(Sex=female & Survived=0, Sex=female & Survived=1等共4entry)占所有passenger數量的比率。這不是我們需要的資訊。我們期望的數據是在Sex=female, Survived=0占多少比率, Survived=1占多少? 這兩個數字相加總應該為1. 換句話說, 我們是要針對row計算比率, 因此我們需要加入一個參數1prop.table指令

prop.table(table(train$Sex, train$Survived),1)
若是要改為Column計算比率,則參數設定為2


我們可以使用data.table取得一樣的結果。首先我想先解釋如何計算數量。在SQL中,有count function可以計算數量,在R環境,我們可以使用length() function; 由於PassengerId是Titanic資料集中Key值(即若資料集共有1000筆, 則就會有1000筆完全不一樣的PassengerId數值), 我們可以length() function來計算PassengerId數量,就可以取得各group的總數

dtTrain[,length(PassengerId),by=Sex]
 

資料集中,男性共577, 女性314, 此數據和summary(train$Sex)的結果相同。 



由於[是否生還]欄位survived為數字欄位, 生還者用1表示,因此我們可以將此欄位直接加總,就可以取得所有的生還者總數。

dtTrain[,sum(Survived),by=Sex]
 

女性數量比男性少, 但是女性生還者比男性多; 讓我們來計算比例可以看得更明顯。 


dtTrain[,sum(Survived)/length(PassengerId),by=Sex]



我將使用data.table結果Trevor Stephens原文比較, 確認計算的結果是正確一致的。然後以柱狀圖顯示此分析結果。

table(train$Sex, train$Survived)
dtTrain[,list(total=length(PassengerId),survived=sum(Survived),perish=length(PassengerId)-sum(Survived)),by=Sex]



dtTrain$chrSv='0'
dtTrain$chrSv[dtTrain$Survived==1]='1'
library(ggplot2)
ggplot(dtTrain, aes(x=Sex, fill=chrSv)) + geom_histogram()


由於女性的存活率超過74%, 所以我們可以更新我們一開始全部沒有生還的預測,改為全部的女性都生還。
test$Survived <- 0
test$Survived[test$Sex == 'female'] <- 1
我們可以將上述的預測結果submit至Kaggle看看預測成效如何


Trevor Stephens的原文中分析Titanic事件甚麼樣的人存活率較高, 提出的一個想法是”saving women and children first”. 因此, 除了上述Sex變數之外, 我們將繼續分析Age變數, 然後整合此兩個變數看看women and children的存活率是否真的較高?


分析Age變數的第一件事情, 是要處理177筆沒有Age數值的乘客(passengers)資料。在此, 我們假設這177筆乘客Age數值為所有乘客的Age平均值;我們可以使用mean(train$Age,na.rm = TRUE)指令,計算出除了這177筆資料之外所有乘客的Age平均值=29.699


接下來, 我們create一個新的變數, Child. 乘客年齡(Age)未滿18, 將其視為Child, 將其數值設定為1; 18以上視為成人, 數值設定為0。由於我們假設沒有Age數值的乘客其Age數值為所有乘客的Age平均值, 因此可以一律將其視為成人, 數值設定為0Child變數設定完成後, 我們針對Sex變數和Child變數進行分析。 
dtTrain$Child = 0  #Adult
dtTrain$Child[dtTrain$Age < 18] = 1
dtTrain[,sum(Survived)/length(PassengerId),by=list(Sex,Child)]



從上圖看來,只要乘客為女性(female), 其存活率都高出很多, 無論其是否為Child. 因此我們不使用此新的變數更新我們的預測。


讓我們繼續看看其他的變數,是否能提供不一樣的預測數據。首先看到Fare(船票價錢)這個變數,由於此變數值是一個continuous variable, 為了簡化分析, 我們create一個新的變數, Fare2, 將所有數據分類成4群組:<10, 10~20,20~30,以及>30. 然後, 我們將此新的變數Fare2, 加上Pclass(艙等)Sex兩個變數一併分析。 
dtTrain$Fare2 = '30+'
dtTrain$Fare2[dtTrain$Fare < 30 & dtTrain$Fare >= 20] = '20-30'
dtTrain$Fare2[dtTrain$Fare < 20 & dtTrain$Fare >= 10] = '10-20'
dtTrain$Fare2[dtTrain$Fare < 10] = '<10'
dtTrain[,sum(Survived)/length(PassengerId),by=list(Fare2,Pclass,Sex)]


dtx=dtTrain[,sum(Survived)/length(PassengerId),by=list(Fare2,Pclass,Sex)]
dtx[order(V1),]


我們可以發現,Pclass=3的女性, 若其所買的船票票價高於$20, 她的存活率明顯地偏低很多。我們用上列新的發現更新預測。



 Data Exploration 在此告一段落; 下一篇將介紹決策樹CART模型, 並利用CART模型對Titanic 資料集做更進一步的分析, 我們將發現此模型可以大幅提升我們預測能力, 並發現更深入的數據內涵資訊。

by J.D.


 

0 意見: