Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

천선생의 삶

[Kaggle] 타이타닉 생존자 예측 1부 - EDA(1) 본문

Kaggle/Titanic

[Kaggle] 타이타닉 생존자 예측 1부 - EDA(1)

천선생 2019. 7. 21. 16:54

안녕하세요. 천선생입니다.

 

 Predicting Titanic Survivors 1부에서는 각 변수를 탐색하며 데이터에 대한 이해도를 쌓고,

전체적인 분석에 대한 계획을 짜기 위하여 진행하는 EDA 에 대한 설명을 하도록 하겠습니다.

이번 포스트에서 우리의 목표는 다음과 같습니다.

1. 각 데이터의 성질 파악하기

2. 데이터 내부에 존재하는 NA값(결측값) 확인과 올바른 대치방법 고안

3. 모델링 이전에 진행하게 될 Feature Engineering 계획수립

 

- NA값 처리

 탐색하기 이전에, 데이터 내부에 존재하는 NA(결측값)은 없는지 확인하도록 하겠습니다.

만약 결측값이 존재한다면, 사용자 함수를 정의하여 각 열의 평균값으로 대치하도록 하겠습니다.

# 각 변수들에 존재하는 NA value의 수와 해당하는 비율
NA_num <- t(colSums(is.na(data)))
NA_prop <- t(colSums(is.na(data))) / nrow(data)
rbind(NA_num, NA_prop)
#      PassengerId    Survived Pclass Name Sex         Age SibSp Parch Ticket         Fare Cabin Embarked
# [1,]           0 418.0000000      0    0   0 263.0000000     0     0      0 1.0000000000     0        0
# [2,]           0   0.3193277      0    0   0   0.2009167     0     0      0 0.0007639419     0        0


# 벡터기준 : 결측값 대치하는 사용자 정의함수
imputation_NA <- function(vec, fun = mean) {
    vec_not_NA <- na.omit(vec)
    imp_val <- fun(vec_not_NA)
    
    vec[is.na(vec)] <- imp_val
    cat('NA value is imputed with ', imp_val, '\n') #결측값 대치 이후, 어떤 값으로 대치했는지 출력해줍니다.
    return(vec)
}

# For 문을 활용하여 한번에 결측값을 대치해줍니다.
for (col in c('Age', 'Fare')) {
    data[[col]] <- imputation_NA(data[[col]])
}
# NA value is imputed with  29.88114 
# NA value is imputed with  33.29548 

 Age 변수에서의 NA값(20%)과 Fare 변수에서의 NA값(0.07%, 1개의 값) 을 각 column의 평균값으로 대치하였습니다.

 

- Survived : 생존여부 (종속변수)

 Titanic 데이터에서, 우리가 예측하고자 하는 값(종속변수)은 생존여부(Survived)입니다. 

test 데이터의 생존여부를 예측이 목표이기 때문에 test 데이터의 Survived는 NA로 존재합니다.

따라서 train 데이터를 활용하여 탐색하도록 하겠습니다.

# table 함수를 통한, 빈도수 차이 확인
table(train$Survived)
#  No Yes 
# 549 342 

# barplot으로 시각화
ggplot(data = train) +
    geom_bar(aes(x = Survived, fill = Survived)) +
    labs(title = 'Distribution of Survived')

출력된 Survived의 Barplot

 수치 / 시각적으로 확인해봤을 때, No(사망)가 약 1.5배 많은 모양을 갖고 있는 것을 확인할 수 있습니다.

 

- PassengerId : 승객번호

 PassengerId 변수는 승객번호로 각 데이터를 구분하는 Index로 확인됩니다.

따라서 이 변수에서 확인할 부분은, Unique 성질(각 값이 고유한 지)의 유무입니다.

# unique(중복값 제거) 함수를 거친 벡터의 길이와, 원본 벡터의 길이를 비교합니다.
length(unique(data$PassengerId)) == length(data$PassengerId)
# [1] TRUE

PassengerId 변수에는 동일한 값을 갖는 관측치가 없는 것을 확인했습니다.

 

- Pclass : 객실등급

 Pclass 변수는 각 승객의 객실 등급을 의미하며 각 수치는 1등실, 2등실, 3등실 을 의미합니다. 

즉, 해당 변수는 범주형으로 바꾸는 것이 올바르다고 할 수 있습니다.

# Pclass 변수는 수치형으로 저장되어 있었으므로, 팩터형으로 변환시켜줍니다.
data$Pclass <- factor(data$Pclass, levels = c(1, 2, 3))

# Pclass의 각 level별 빈도수를 확인하겠습니다.
table(data$Pclass)
#   1   2   3 
# 323 277 709 

# 재미있는 사실은 1등석이 2등석 승객보다 많다는 사실입니다.  
# 시각화를 통하여 인원수를 더욱 명확하게 확인해보도록 하겠습니다.
ggplot(data = data) +
    geom_bar(aes(x = Pclass, fill = Pclass))

출력된 Pclass의 Barplot

- 종속변수와의 관계

 범주형 변수 2개의 관계를 Crosstable, Chisq.test, Mosaic plot 3가지 방법을 통하여 알아보겠습니다.

# Crosstable을 통해 관게를 확인해보겠습니다.
with(train, table(Survived, Pclass))
#         Pclass
# Survived   1   2   3
#      No   80  97 372
#      Yes 136  87 119
# 확인이 힘들기때문에, 카이스퀘어검정 또는 시각화를 통해 관계를 확인해보겠습니다.

# Chisquare test 독립성 검정
with(train, chisq.test(Pclass, Survived))
# Pearson's Chi-squared test
# 
# data:  Pclass and Survived
# X-squared = 102.89, df = 2, p-value < 2.2e-16
# P-value 확인 결과, 두 변수는 독립이 아님을 확인할 수 있습니다.

# 시각화를 통한 관계확인
mosaicplot(Pclass~Survived, data = train)

출력된 Mosaic plot. 수직 / 수평선의 평행여부로 독립성을 확인한다.

 Pclass 변수와 종속변수가 연관되어있음을 확인하였습니다.

 

- Name : 이름

 Name 변수는 각 승객의 이름을 의미합니다. 즉 factor가 아닌 character가 올바른 형태일 것입니다.

또한, 전처리를 통하여 유의미한 성질을 유도할 수 있을지 확인해봐야 합니다.

# Character형으로 변환합니다.
data$Name <- as.character(data$Name)

head(data$Name)
# [1] "Braund, Mr. Owen Harris"                             "Cumings, Mrs. John Bradley (Florence Briggs Thayer)"
# [3] "Heikkinen, Miss. Laina"                              "Futrelle, Mrs. Jacques Heath (Lily May Peel)"       
# [5] "Allen, Mr. William Henry"                            "Moran, Mr. James" 
# 확인결과, 유의미한 성질을 유도하려면 문자열을 분해하고 특성을 찾아내야 할 것 같습니다.  
# R basic 기반의 분석이기때문에 분석의 간소화를 위하여 Name변수는 삭제하도록 합니다.

data$Name <- NULL

 본 프로젝트는 초급자를 위한 분석과정이기때문에, Name 의 세부 전처리를 활용하기보다는 삭제하도록 하겠습니다.

그렇다고해서 Name 변수가 중요하지 않다는 뜻은 절대 아닙니다.

실제로 Kaggle의 커널을 찾아보면 Name 변수만으로 생존여부를 예측한 커널도 존재하며 높은 정확도를 보여줍니다!

https://www.kaggle.com/cdeotte/titanic-using-name-only-0-81818

 

Titanic using Name only [0.81818]

Using data from multiple data sources

www.kaggle.com

 

- 마치며

 이번 포스트에서는 Survived, PassengerId, Pclass, Name 변수에 대한 탐색을 다뤘습니다.

다음 포스트에서는 Sex, Age, Sibsp / Parch 변수에 대한 탐색을 다루도록 하겠습니다.

변수에 대한 탐색은 분석에서 80%이상을 차지한다고 할 정도로 분량이 많습니다.

변수에 빠져 길을 잃기 쉽기때문에 우리는 최종 목표를 항상 상기할 필요가 있습니다!

최종 목표를 마지막으로 포스트를 마치도록 하겠습니다.

'타이타닉 데이터의 승객 정보를 활용하여 생존여부를 예측해본다!'

Comments