Background

Introduction

Pada 15 April 1912 tepatnya pukul 02.20, kapal laut Inggris Titanic mulai tenggelam di Samudra Atlantik Utara sekitar 400 mil selatan Newfoundland, Kanada. Kapal besar nan mewah itu mengangkut 2.200 penumpang dan awak kapal. Dua setengah jam sebelumnya, kapal menabrak gunung es. Dilansir History, pada 10 April kapal termewah dalam sejarah pembuatannya itu berangkat dari Southampton, Inggris pada perjalanan perdananya melintasi Samudra Atlantik.

Data yang akan kita explore merupakan data penumpang titanic yang diambil dari kaggle. Nantinya kita akan memprediksi penumpang yang selamat atau tidak selamat dengan menggunakan logistic regrresion untuk mengklasifikasikan hal tersebut.

Library

library(dplyr)
library(caret)
library(GGally)
library(MLmetrics)
library(rsample)
library(lmtest)
library(car)

Data Preparation

Read Data

Pertama yang akan kita lakukan adalah memanggil data yang telah kita siapkan.

titanic <- read.csv("train.csv")

Struktur Data

Lalu dengan menggunakan fungsi glimpse kita dapat melihat gambaran data yang telah kita ambil

glimpse(titanic)
## Rows: 891
## Columns: 12
## $ PassengerId <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,…
## $ Survived    <int> 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1…
## $ Pclass      <int> 3, 1, 3, 1, 3, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 2, 3, 3…
## $ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
## $ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
## $ Age         <dbl> 22, 38, 26, 35, 35, NA, 54, 2, 27, 14, 4, 58, 20, 39, 14, …
## $ SibSp       <int> 1, 1, 0, 1, 0, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 0, 1, 0…
## $ Parch       <int> 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0…
## $ Ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
## $ Fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 8.4583, 51.8625,…
## $ Cabin       <chr> "", "C85", "", "C123", "", "", "E46", "", "", "", "G6", "C…
## $ Embarked    <chr> "S", "C", "S", "S", "S", "Q", "S", "S", "S", "C", "S", "S"…

Data titanic terdiri dari 891 baris dan 12 kolom. Kolomnya adalah sebagai berikut :

  • PassangerID : unique ID dari tiap penimpang
  • Survived : bernilai 1 (selamat) dan 0 (tidak selamat)
  • PClass : Kelas dari tiap penumpang
  • Name : Nama penumpang
  • Sex : Jenis kelamin penumpang
  • Age : Umur penumpang
  • SibSp : Jumlah saudara kandung/pasangan
  • Parch : Jumlah orangtua/anak-anak
  • Ticket : Nomer dari tiket penumpang
  • Fare : tarif
  • Cabin : kabin
  • Embarked : pelabuhan keberangkatan

Missing Values

Kemudian kita dapat mengecek apakah ada nilai NA di setiap kolom data titanic.

anyNA(titanic)
## [1] TRUE
colSums(is.na(titanic))
## PassengerId    Survived      Pclass        Name         Sex         Age 
##           0           0           0           0           0         177 
##       SibSp       Parch      Ticket        Fare       Cabin    Embarked 
##           0           0           0           0           0           0

Dari kedua fungsi diatas, kita dapat mengetahui bahwa ada nilai NA sebanyak 177 pada kolom age, yang nantikan akan kita handle pada proses berikutnya.

Data Cleansing & Wrangling

Kita akan membuang kolom-kolom yang tidak dibutuhakn dalam membuat model. Kolom-kolom yang akan kita buang adalah age, name, ticket, cabin. Age dibuang karena pada kolom tersebut terdapat 177 nilai NA. Selain itu, kita juga harus mengubah beberapa tipe kolom karena belum sesuai. Kolom-kolom yang akan diubah adalah survived, PClass, SibSp, Parch, Sex, Embarked. Semua kolom tersebut akan diubah tipe datanya menjadi factor.

titanic_clean <- titanic %>% 
  select(-Age,-Name, -Ticket, -Cabin, -PassengerId) %>% 
  mutate(Survived = as.factor(Survived),
         Pclass =  as.factor(Pclass),
         SibSp =  as.factor(SibSp),
         Parch = as.factor(Parch),
         Sex = as.factor(Sex),
         Embarked =  as.factor(Embarked))

EDA

summary(titanic_clean)
##  Survived Pclass      Sex      SibSp   Parch        Fare        Embarked
##  0:549    1:216   female:314   0:608   0:678   Min.   :  0.00    :  2   
##  1:342    2:184   male  :577   1:209   1:118   1st Qu.:  7.91   C:168   
##           3:491                2: 28   2: 80   Median : 14.45   Q: 77   
##                                3: 16   3:  5   Mean   : 32.20   S:644   
##                                4: 18   4:  4   3rd Qu.: 31.00           
##                                5:  5   5:  5   Max.   :512.33           
##                                8:  7   6:  1

Dari summary diatas dapat dilihat proporsi data kolom survived, Pclass, Sex, SibSp, Parch, dan Embarked. Kita dapat melihat juga nilai min, median, mean, dan max dari variabel Fare.

Modeling

#Cross Validation Dalalm melakukan pembuatan mdoel, kita harus melakukan cross validation terlebih dahulu.Cross validation dibuat untuk memisahkan data menjadi data train dan data test. Data train digunakan untuk melakukan pemodelan, sedangkan data test digunakan untuk menguji hasil prediksi dari model yang telah dibuat.

set.seed(2012)

index <- initial_split(data = titanic_clean, prop = 0.8,strata = "Survived")
data_train <- training(index)
data_test <- testing(index)

Langkah selanjutnya adalah melakukan pengecekan proporsi data pada kolom survived baik pada data test, maupun pada data train

prop.table(table(data_train$Survived))
## 
##        0        1 
## 0.616573 0.383427
nrow(data_train)
## [1] 712
prop.table(table(data_test$Survived))
## 
##         0         1 
## 0.6145251 0.3854749
nrow(data_test)
## [1] 179

Dari hasil diatas, data train dan data test bisa dikatakan sudah seimbang

Model Logistic Regression

Model pertama yang akan kita buat adalah model dengan semua prediktor

model.titanic <- glm(formula = Survived ~ ., 
                     data = data_train, 
                     family = "binomial" )
summary(model.titanic)
## 
## Call:
## glm(formula = Survived ~ ., family = "binomial", data = data_train)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.4247  -0.6611  -0.4409   0.5474   2.6480  
## 
## Coefficients:
##                Estimate  Std. Error z value             Pr(>|z|)    
## (Intercept)   16.210355 1696.734364   0.010              0.99238    
## Pclass2       -0.451976    0.339139  -1.333              0.18263    
## Pclass3       -1.359054    0.326918  -4.157            0.0000322 ***
## Sexmale       -2.638935    0.226235 -11.665 < 0.0000000000000002 ***
## SibSp1        -0.043463    0.256770  -0.169              0.86558    
## SibSp2        -0.334364    0.633249  -0.528              0.59749    
## SibSp3        -2.830208    1.066680  -2.653              0.00797 ** 
## SibSp4        -1.872022    0.885943  -2.113              0.03460 *  
## SibSp5       -16.187495 1037.365573  -0.016              0.98755    
## SibSp8       -16.971900  907.602081  -0.019              0.98508    
## Parch1         0.827807    0.326486   2.536              0.01123 *  
## Parch2         0.573586    0.448326   1.279              0.20076    
## Parch3        -0.216474    1.179605  -0.184              0.85439    
## Parch4       -16.302097 1190.700511  -0.014              0.98908    
## Parch5        -1.304736    1.237164  -1.055              0.29160    
## Parch6       -17.053458 2399.544740  -0.007              0.99433    
## Fare           0.004446    0.003398   1.308              0.19071    
## EmbarkedC    -13.951724 1696.734377  -0.008              0.99344    
## EmbarkedQ    -14.132738 1696.734399  -0.008              0.99335    
## EmbarkedS    -14.528986 1696.734371  -0.009              0.99317    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 947.98  on 711  degrees of freedom
## Residual deviance: 615.15  on 692  degrees of freedom
## AIC: 655.15
## 
## Number of Fisher Scoring iterations: 15

Kita juga akan membuat model dengan menggunakan stepwise backward

model.titanic_2 <- step(model.titanic,
                 direction = "backward",
                 trace = F)
summary(model.titanic_2)
## 
## Call:
## glm(formula = Survived ~ Pclass + Sex + SibSp + Parch + Fare, 
##     family = "binomial", data = data_train)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.5376  -0.6845  -0.4695   0.6484   2.6506  
## 
## Coefficients:
##                Estimate  Std. Error z value             Pr(>|z|)    
## (Intercept)    1.899458    0.355816   5.338         0.0000000938 ***
## Pclass2       -0.579677    0.331900  -1.747              0.08072 .  
## Pclass3       -1.387968    0.316972  -4.379         0.0000119318 ***
## Sexmale       -2.698964    0.222216 -12.146 < 0.0000000000000002 ***
## SibSp1        -0.061903    0.255783  -0.242              0.80877    
## SibSp2        -0.348728    0.621752  -0.561              0.57488    
## SibSp3        -3.138440    1.078226  -2.911              0.00361 ** 
## SibSp4        -2.012099    0.892895  -2.253              0.02423 *  
## SibSp5       -16.372892 1032.722171  -0.016              0.98735    
## SibSp8       -17.177349  901.470528  -0.019              0.98480    
## Parch1         0.864878    0.325695   2.655              0.00792 ** 
## Parch2         0.554011    0.444771   1.246              0.21291    
## Parch3        -0.206330    1.162010  -0.178              0.85907    
## Parch4       -16.486664 1183.833326  -0.014              0.98889    
## Parch5        -1.368678    1.229865  -1.113              0.26576    
## Parch6       -17.259298 2399.544738  -0.007              0.99426    
## Fare           0.005195    0.003365   1.544              0.12265    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 947.98  on 711  degrees of freedom
## Residual deviance: 620.63  on 695  degrees of freedom
## AIC: 654.63
## 
## Number of Fisher Scoring iterations: 15

Berikutnya kita akan memprediksi target variable survived berdasarkan model yang telah kita buat dengan dengan threshold 0.5, yang artinya apabilah hasil prediksi diatas 0.5 penumpang selamat dan bila di bawah 0.5 penumpang tidak selamat.

pred <- predict(object = model.titanic,
                newdata = data_test,
                type = "response")
pred <- ifelse(pred > 0.5 , yes = 1 , no = 0)
pred <- as.factor(pred)
pred.2 <- predict(object = model.titanic_2,
                newdata = data_test,
                type = "response")
pred.2 <- ifelse(pred.2 > 0.5 , yes = 1 , no = 0)
pred.2 <- as.factor(pred.2)

#Evaluation Model Confusion Matrix digunakan untuk membandingkan prediksi yang dibuat oleh model dengan nilai riil pada data test.

confusionMatrix(data = pred , 
                data_test$Survived,
                positive = "1")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  0  1
##          0 90 22
##          1 20 47
##                                           
##                Accuracy : 0.7654          
##                  95% CI : (0.6964, 0.8254)
##     No Information Rate : 0.6145          
##     P-Value [Acc > NIR] : 0.00001317      
##                                           
##                   Kappa : 0.5021          
##                                           
##  Mcnemar's Test P-Value : 0.8774          
##                                           
##             Sensitivity : 0.6812          
##             Specificity : 0.8182          
##          Pos Pred Value : 0.7015          
##          Neg Pred Value : 0.8036          
##              Prevalence : 0.3855          
##          Detection Rate : 0.2626          
##    Detection Prevalence : 0.3743          
##       Balanced Accuracy : 0.7497          
##                                           
##        'Positive' Class : 1               
## 

Model pertama memiliki tingkat accuracy dalam meprediksi sebesar 76% dengan sensitivity sebesar 68% dan precision (post pred values) sebesar 70%.

confusionMatrix(data = pred.2 , 
                data_test$Survived,
                positive = "1")
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  0  1
##          0 92 22
##          1 18 47
##                                           
##                Accuracy : 0.7765          
##                  95% CI : (0.7084, 0.8353)
##     No Information Rate : 0.6145          
##     P-Value [Acc > NIR] : 0.000002852     
##                                           
##                   Kappa : 0.5232          
##                                           
##  Mcnemar's Test P-Value : 0.6353          
##                                           
##             Sensitivity : 0.6812          
##             Specificity : 0.8364          
##          Pos Pred Value : 0.7231          
##          Neg Pred Value : 0.8070          
##              Prevalence : 0.3855          
##          Detection Rate : 0.2626          
##    Detection Prevalence : 0.3631          
##       Balanced Accuracy : 0.7588          
##                                           
##        'Positive' Class : 1               
## 

Model kedua memiliki tingkat accuracy dalam meprediksi sebesar 77% dengan sensitivity sebesar 68% dan presicion (post pred values) sebesar 72%.

Conclusion

Target variable adalah survived, artinya kita mau memprediksi apakah penumpang selamat atau tidak berdasark faktor-faktor yang ada. Dalam pembuatan model, model menggunakan prediktor : Pclass, Sex, SibSp, Parch, dam Fare. Model mampu memprediksi target dangan 77% Accuracy dan 72% precision.