Predicting Survival on the Titanic

Ryu

2020-03-25


Github Code: Jun4871 Github

개요

과거 의사결정 나무 기법을 통해 타이타닉 생존자 예측을 해본 적이 있었는데, 사람마다 분석하는 방식이 전부 다를 수 있고 이것에 대해 추가적인 공부가 더 필요할 것 같아 다른 사람들의 분석과정을 참고하여 분석을 진행해보고자 한다. 이번 타이타닉 생존자 예측에 있어, 3가지 머신러닝 기법을 사용할 것이다.


  • 랜덤 포레스트(Random Forest)
  • 로지스틱 회귀(Logistic Regression)
  • 나이브 베이즈(Naive Bayes

패키지 로드

분석에 필요한 라이브러리를 불러오는 과정이다. 아래 패키지들을 이번 분석에 활용할 것이다.

데이터 읽어오기

지정한 데이터를 R로 읽어오는 과정이며, Kaggle에서 받은 train과 test 데이터를 bind_row() 함수로 묶어서 진행할 것이다. (DPLYR 패키지에 내장되어 있다)

head() 함수를 통해 합쳐진 데이터의 6th 행까지 탐색해보고, summary() 함수를 통해 통계적 요약치를 확인해보자.

##   PassengerId      Survived          Pclass          Name          
##  Min.   :   1   Min.   :0.0000   Min.   :1.000   Length:1309       
##  1st Qu.: 328   1st Qu.:0.0000   1st Qu.:2.000   Class :character  
##  Median : 655   Median :0.0000   Median :3.000   Mode  :character  
##  Mean   : 655   Mean   :0.3838   Mean   :2.295                     
##  3rd Qu.: 982   3rd Qu.:1.0000   3rd Qu.:3.000                     
##  Max.   :1309   Max.   :1.0000   Max.   :3.000                     
##                 NA's   :418                                        
##      Sex           Age            SibSp            Parch      
##  female:466   Min.   : 0.17   Min.   :0.0000   Min.   :0.000  
##  male  :843   1st Qu.:21.00   1st Qu.:0.0000   1st Qu.:0.000  
##               Median :28.00   Median :0.0000   Median :0.000  
##               Mean   :29.88   Mean   :0.4989   Mean   :0.385  
##               3rd Qu.:39.00   3rd Qu.:1.0000   3rd Qu.:0.000  
##               Max.   :80.00   Max.   :8.0000   Max.   :9.000  
##               NA's   :263                                     
##     Ticket               Fare            Cabin           Embarked  
##  Length:1309        Min.   :  0.000   Length:1309        C   :270  
##  Class :character   1st Qu.:  7.896   Class :character   Q   :123  
##  Mode  :character   Median : 14.454   Mode  :character   S   :914  
##                     Mean   : 33.295                      NA's:  2  
##                     3rd Qu.: 31.275                                
##                     Max.   :512.329                                
##                     NA's   :1


탐색적 데이터 분석

우리의 변수 중 일부를 그래프로 그려 그것들이 생존율에 어떤 영향을 미치는지 시각화해보자.

# Survival
g1 <- ggplot(full_data[1:891,], aes(x = factor(Survived), fill = factor(Survived))) +
  geom_bar(position = 'dodge') +
  scale_x_discrete() +
  labs(title = 'Survival on the Titanic', x = "outcome", y = "Count") +
  scale_fill_discrete(name = "Outcome", labels = c("Died", "Survived")) +
  theme(legend.position = "right") +
  theme_classic()

# Sex
g2 <- ggplot(full_data[1:891,], aes(x = factor(Sex), fill = factor(Survived))) +
  geom_bar(position = 'dodge') +
  scale_x_discrete() +
  labs(title = "Survival by Gender", x = "Gender", y = "Rate") +
  scale_fill_discrete(name = "Outcome", labels = c("Died", "Survived")) +
  theme(legend.position = "right") +
  theme_classic()

# Pclass
g3 <- ggplot(full_data[1:891,], aes(x = factor(Pclass), fill = factor(Survived))) +
  geom_bar(position = "dodge") +
  scale_x_discrete() +
  labs(title = "Survival by passenger Class", x = "Passenger Class", y = "Count") +
  scale_fill_discrete(name = "Outcome", labels = c("Died", "Survived")) +
  theme(legend.position = "right") +
  theme_classic()

# Embarkment 
g4 <- ggplot(full_data[1:891,], aes(x = factor(Embarked), fill = factor(Survived))) +
  geom_bar(position = "dodge") +
  theme(legend.position = "right") +
  theme_classic()

# Age 
g5 <- ggplot(full_data[1:981,]) +
  geom_freqpoly(aes(x = Age, color = factor(Survived)), binwidth = 1) +
  theme_classic() +
  theme(legend.position = "none") +
  labs(title = "Survival by Age", x = "Age", y = "Count")

# Fare
g6 <- ggplot(full_data[1:891,]) +
  geom_freqpoly(aes( x = Fare, color = factor(Survived)), binwidth = 0.05) +
  scale_x_log10() +
  theme_classic() +
  theme(legend.position = "none") +
  labs(title = "Survival by Fare(log10)", x = "Fare(log10)", y ="Count")

grid.arrange(g1,g2,g3,g4,g5,g6, ncol=2)

탐색적 데이터 분석을 통해 우리는 다음과 같은 사실을 알 수 있다.

  • 타이타닉 호의 승객의 대부분은 죽었다.
  • 대부분의 생존자에 있어서 여성의 생존 기회가 남성보다 더 많았다.
  • 보다 높은 등급의 승객이 생존의 기회가 더 많았다.
  • C 구역에서 탑승한 사람들이 다른 구역에서 탑승한 사람보다 조금 더 높은 생존률을 모였다.
  • 16세 이하가 높은 생존률을 보이는 경향이 있으며, 다른 연령대는 죽음에 대한 높은 리스크가 있었다.
  • 높은 요금을 지불한 승객은 일반적으로, 상대적으로 적은 요금을 지불한 승객에 비해 생존률이 높았다.

변수와 생존 사이의 상관관계 검증

여기서 성별, 승객 등급, 그리고 운임비 변수가 생존과 낮거나 중간정도의 상관관계를 가지고 있음을 알 수 있다. 이것은 생존을 예측하는 데 중요할 수 있다는 것을 의미한다.


변수 가공

새로운 변수들을 생성해서 특징들을 파악해 볼 것이다

  • Family_size
  • Title
  • Cabin_letter
  • Ticket_number

Family size

Family size 생성을 위해 Sibsp(siblings + spouse) 와 Parch(parents + children) + 1 조합으로 변수를 만들어 특장을 살펴볼 것이다. (개인 고객이 있으므로 + 1을 해줌)

새롭게 만들어진 Family_size 변수가 그래프로 어떻게 표현되는지 확인해보자.

그래프를 보니 2 ~ 4명 가족단위가 생존에 있어 혜택을 받은 것으로 보인다. 반면에 1명이거나 5명 이상 단위의 그룹은 생존에 있어 그 기회가 적었음을 확인할 수 있다. 이러한 구분을 보여주는 새로운 변수를 만들어 예측모델의 성능을 향상시킬 수 있는 가능성을 보자.

그래프를 통해 Family_size 변수와 비교했을 때 어떨지 확인해보자.

여기서 우리는 조금 더 확실하게 2~4명 단위의 승객의 생존률이 한 명이나 다섯명 단위 승객의 생존률 보다 높음을 알 수 있다.


Title

계속해서 두 번째 변수인 Title 을 만들어보자. 기존의 변수 ‘이름’ 변수에서 타이틀 정보를 추출할 것이다. 이 변수가 생존을 예측하는데 유용한 정보를 제공하기를 바라며, 정규식 표현을 사용하여 Title 을 추출해보자.

Title의 테이블을 한 번 살펴보도록 하자.

## 
##         Capt          Col          Don         Dona           Dr     Jonkheer 
##            1            4            1            1            8            1 
##         Lady        Major       Master         Miss         Mlle          Mme 
##            1            2           61          260            2            1 
##           Mr          Mrs           Ms          Rev          Sir the Countess 
##          757          197            2            8            1            1

몇몇 직함들은 거의 없는 것이나 다름이 없었기 때문에 이것들을 새로운 카테고리인 rare_title에 재할당할 것이다.

적당한 카테고리에 재할당해주자.

그래프화해서 직함이 생존률에 어떤 영향을 끼치는지 보자.

이 그래프에서 우리는 Miss 와 Mrs 호칭을 가진 사람들의 생존률이 가장 높은 것을 확인할 수 있다. 여성들 사이에서 생존률이 높았기 때문에 예상과 일치하는 결과라고 볼 수 있다. 또 Maser 호칭을 가진 사람들 또한 생존률이 높았다. 이 그래프에서 Mr호칭은 죽음에 대한 확실한 경향을 보여주고 있다.


Cabin

여기서는 cabin letter 를 Cabin 컬럼에서 추출하여, 새로운 Cabin_letter 라는 컬럼을 생성할 것이다.

정규식 표현을 사용하여 cabin letter을 추출해보자.

어떤 선실들은 적은 데이터를 가지고 있고, 어떤 선실들은 두 개의 선실로 분류된다. 우리는 이것들을 결합하여 EFGT라고 명명하여 새로운 이름을 만들 것이다. 그리고 기내 문자가 없는 것을 “빈칸”으로 리코딩할 것이다.

Cabin_letter 가 생존에 어떠한 영향을 미치는지 그래프로 확인해보자.

그래프를 보고나니, Cabin 을 가진 사람의 생존률이 높고 그러지 못한 사람은 생존률이 떨어지다는 것을 알 수 있었다. 조금 더 자세히 보도록 하자.

다시 그래프를 띄워보자.

역시 cabin 을 배정받은 사람의 생존률이 더 높았다.


Ticket number

정규표현식을 사용하여 숫자데이터가 아닌 것은 전부 제거하여 Ticket에서 Ticket_number 를 추출할 것이다.

티켓 번호에서 모든 글자를 삭제하는 과정에서 일부 글자는 공백("") 그들 중 몇 명이 비어 있는지 보고 그들에게 값을 재할당하자.

## 
## FALSE  TRUE 
##  1305     4

티켓번호 log 를 그래프화 해보자.

티켓 번호와 생존 사이에 명확한 추세가 보이지 않는다. 두 변수의 상관관계를 확인해보자.

## [1] -0.01561505

여기에는 실질적인 상관관계가 없는 것 같으니, 티켓 번호 변수를 예측 모델에서 제외시키도록 한다.


결측치 조작

결측치 처리

우리는 이제 FareAge 에 대한 우리의 누락된 값을 처리할 것이다. 데이터에서 누락된 값이 무엇인지 확인하는 것부터 알아보자. 여기에 VIM 패키지의 aggr()를 사용할 것이다.

## 
##  Variables sorted by number of missings: 
##           Variable Count
##           Survived   418
##                Age   263
##               Fare     1
##             Pclass     0
##                Sex     0
##              Title     0
##     cabin_presence     0
##  family_size_range     0

이제 "preProcess() 기능을 사용하여 누락된 값 모델을 nnImpute로 사전에 처리하겠다. 이렇게 하면 데이터가 확장된다. 우리는 생존 변수를 사전 프로세스 모델에서 제외시킨 후 나중에 다시 추가할 것이다.

## Created from 1045 samples and 7 variables
## 
## Pre-processing:
##   - centered (3)
##   - ignored (4)
##   - 5 nearest neighbor imputation (3)
##   - scaled (3)

이제, 우리는 우리가 만든 모델을 사용하여 지속적인 우리의 결측치, 즉 페어와 에이지를 예측할 것이다. 우리는 나중에 착수할 NA를 계산할 것이다.

전에 만든 모델을 사용하여 잔존하는 missing value를 예측할 것이다. 즉 Fare 와 Age 가 되겠다. 그리고 embarked later 에 대한 NA 값을 계산할 것이다.

이제 데이터 프레임에 ’Survived’를 다시 추가하고, full_data_complete 와 full_data의 변수들을 새로운 데이터 프레임으로 만들어보자.

‘full_data.Survived’ 컬럼이름을 다시 ’Survived’로 명명하고 새로운 데이터 프레임을 만든다.


머신러닝 알고리즘

데이터 모델링을 시작하기 전에 데이터 셋을 train 및 test 데이터로 분할하자.

랜덤 포레스트(Random Forest)

이제 타이타닉에서 생존을 예측할 수 있는 예측 모델을 만들어보자. 우리가 사용할 첫번째 분류 알고리즘은 랜덤 포리스트이다.

CARET 패키지의 train() 기능을 활용하여 training model을 만들 것이다.

## Random Forest 
## 
## 891 samples
##   8 predictor
##   2 classes: '0', '1' 
## 
## No pre-processing
## Resampling: Bootstrapped (25 reps) 
## Summary of sample sizes: 891, 891, 891, 891, 891, 891, ... 
## Resampling results across tuning parameters:
## 
##   mtry  Accuracy   Kappa    
##    2    0.8289915  0.6307177
##    7    0.8217978  0.6163333
##   13    0.8080451  0.5866530
## 
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was mtry = 2.

혼동행렬을 사용하여 방금 만든 랜덤포레스트 모델의 점검해보자. 이것은 우리에게 우리의 모델의 예상 전반적인 정확성 뿐만 아니라 뿐만 아니라 죽음과 생존예측에 대한 정확성을 알 수 있다.

## Bootstrapped (25 reps) Confusion Matrix 
## 
## (entries are percentual average cell counts across resamples)
##  
##           Reference
## Prediction    0    1
##          0 55.1 10.5
##          1  6.6 27.8
##                             
##  Accuracy (average) : 0.8288

우리의 예측에 모델 오차율을 표시한다.

여기서 우리는 우리의 전반적인 예측에 대한 오류율과 죽음과 생존에 대한 오류율을 별도로 볼 수 있다. 흥미롭게도, 우리는 생존보다 더 정확하게 죽음을 예측하고 있다.

우리의 예측에서 각 변수의 중요성을 시각화하는 플롯을 만들자.

예측 : 랜덤 포레스트

이제 랜덤 포레스트 모델을 만들었으니, test 데이터 세트에서 생존을 예측하는 데 사용할 것이다.

테스트 셋을 사용하여 예측해보자.

solution_rf를 PeakerId 및 Surved라는 두 개의 데이터가 있는 데이터 프레임에 저장하자.

파일로 저장하자.

랜덤 포레스트 정확도 : 0.8288


로지스틱 회귀(Logistic Regression0

로지스틱 회귀를 사용하여 분류를 시도해보자. 새 오브젝트를 10개 변수에 맞춰 생성하고, 이것을 train 모델에 사용할 것이다.

예측 모델을 train으로 만들고, 모델에 옵션 값을 지정해주자.

## Generalized Linear Model 
## 
## 891 samples
##   8 predictor
##   2 classes: '0', '1' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 802, 801, 802, 802, 802, 802, ... 
## Resampling results:
## 
##   Accuracy   Kappa    
##   0.8271411  0.6290895

로지스틱 회귀 모형의 정확도를 확인해보자.

## Cross-Validated (10 fold) Confusion Matrix 
## 
## (entries are percentual average cell counts across resamples)
##  
##           Reference
## Prediction    0    1
##          0 54.2  9.9
##          1  7.4 28.5
##                             
##  Accuracy (average) : 0.8272

로지스틱 회귀 분석 모델에서 각 특성별로 중요성을 확인해보자.

예측: 로지스틱 회귀

테스트 셋을 사용하여 예측해보자

solution_lr 을 데이터 프레임 형식으로 저장하자.

solution_lr 을 파일로 만들자

로지스틱 회귀 정확도 : 0.8272


나이브 베이즈(Naive Bayes)

이제 마지막 머신러닝 알고리즘인 네이브 베이즈를 사용해 보자.

응답 변수인 "Survived*"가 없는 training 데이터 세트를 생성만들고, 다음으로 생존 변수만 포함된 세트를 만들어보자.

Naive Bayes를 크로스 유효성 검사로 모델링.

train의 변수를 활용하여 모델 생성.

## Naive Bayes 
## 
## 891 samples
##   8 predictor
##   2 classes: '0', '1' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 802, 801, 802, 802, 802, 802, ... 
## Resampling results across tuning parameters:
## 
##   usekernel  Accuracy   Kappa    
##   FALSE      0.8024844  0.5783244
##    TRUE      0.7923596  0.5276528
## 
## Tuning parameter 'fL' was held constant at a value of 0
## Tuning
##  parameter 'adjust' was held constant at a value of 1
## Accuracy was used to select the optimal model using the largest value.
## The final values used for the model were fL = 0, usekernel = FALSE and adjust
##  = 1.

모델의 정확도를 확인해자.

## Cross-Validated (10 fold) Confusion Matrix 
## 
## (entries are percentual average cell counts across resamples)
##  
##           Reference
## Prediction    0    1
##          0 52.5 10.7
##          1  9.1 27.7
##                             
##  Accuracy (average) : 0.8025

각 변수별로 나이브 베이즈 모델에서의 중요도를 확인해보자.

예측: 나이브 베이즈

생존률 예측에 있어, 생성한 나이브 베이즈 모델을 사용하여 test data set을 예측하지 않을 것이다.

test data로 예측을 할 것이다.

solution_nb를 데이터 프레임 형식으로 저장하자.

파일로 저장하자.

나이브 베이즈 정확도 : 0.8025


결과

결과 테이블:

분류기법 예측 정확도
랜덤 포레스트 0.8272
로지스틱 회귀 0.8272
나이브 베이즈 0.8025

Kaggle 출처 :Referenced Address