Você está na página 1de 11

Sobrevivência Titânic

Prever a Sobrevivência do Titanic


Sena (versão Português) Do original coreano de Suengjae Hong
17 de junho de 2019

# Setando codificacao para representar qualquer caractere universal padrao Unicode.


options(encoding="UTF-8")

# Setando o local da pasta de trabalho.


setwd("E:/Outras Analises R/Sobrevivencia Titanic")

Exercícios de modelo para prever a Sobrevivência do Titanic. (Ver-


são 1.0)
(1) O modelo é construído com base nas variáveis do conjunto de dados básicos.

(2) Regressão logística apenas.

Planejamos aumentar a precisão através de várias modelagens e várias configurações de var-


iáveis no futuro.
E-mail: suengjae.hong@gmail.com
Linkedin: www.linkedin.com/in/suengjaehong

Os pacotes
Acrescentei este trecho de código R a fim de faciliar na instalação dos pacotes utilizados nesta análise.
# Verificar e instalar o(s) pacote(s) a utilizar na analise.
pacotes_analise <- c("leaps")

# Necessarios apenas para RMarkdown.


pacotes_padrao <- c("installr","rmarkdown","knitr","tinytex","prettydoc")
if (length(setdiff(c(pacotes_padrao, pacotes_analise), rownames(installed.packages()))) > 0) {
install.packages(setdiff(c(pacotes_padrao, pacotes_analise), rownames(installed.packages())))
# RMarkdown precisa de Pandoc e MiKTeX instalados. https://miktex.org/2.9/setup.
require(installr)
install.pandoc()
}

suppressMessages(library("rmarkdown"))

library(dplyr)
library(ggplot2) # visualizacao
library(scales) # visualizacao
library(caTools) # previsao - dividindo o conjunto de dados
library(car) # previsao - multicolinearidade e vif
library(leaps) # para regsubsets

# desativar as opções de aviso

1
options(avisar = -1) # Se definir como 0 indica ativar as opções de aviso

# ler todos os dados


train <- read.csv ('train.csv')
test <- read.csv ('test.csv')

# combina dataset
titanic <- bind_rows(train, test)

Primeiro carreguei os pacotes e combinei o conjunto de dados do dataset com o conjunto de dados de teste.
No conjunto de dados de teste não há coluna de variável de resultado associada a sobrevivência, portanto, o
resultado da mesclagem retornará NA.
str(titanic) # mostra a descricao

## 'data.frame': 1309 obs. of 12 variables:


## $ PassengerId: int 1 2 3 4 5 6 7 8 9 10 ...
## $ Survived : int 0 1 1 1 0 0 0 0 1 1 ...
## $ Pclass : int 3 1 3 1 3 3 1 3 3 2 ...
## $ Name : chr "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)"
## $ Sex : Factor w/ 2 levels "female","male": 2 1 1 1 2 2 2 2 1 1 ...
## $ Age : num 22 38 26 35 35 NA 54 2 27 14 ...
## $ SibSp : int 1 1 0 1 0 0 0 3 0 1 ...
## $ Parch : int 0 0 0 0 0 0 0 1 2 0 ...
## $ Ticket : chr "A/5 21171" "PC 17599" "STON/O2. 3101282" "113803" ...
## $ Fare : num 7.25 71.28 7.92 53.1 8.05 ...
## $ Cabin : chr "" "C85" "" "C123" ...
## $ Embarked : chr "S" "C" "S" "S" ...
str(train) # mostra a descricao

## 'data.frame': 891 obs. of 12 variables:


## $ PassengerId: int 1 2 3 4 5 6 7 8 9 10 ...
## $ Survived : int 0 1 1 1 0 0 0 0 1 1 ...
## $ Pclass : int 3 1 3 1 3 3 1 3 3 2 ...
## $ Name : Factor w/ 891 levels "Abbing, Mr. Anthony",..: 109 191 358 277 16 559 520 629 417 581
## $ Sex : Factor w/ 2 levels "female","male": 2 1 1 1 2 2 2 2 1 1 ...
## $ Age : num 22 38 26 35 35 NA 54 2 27 14 ...
## $ SibSp : int 1 1 0 1 0 0 0 3 0 1 ...
## $ Parch : int 0 0 0 0 0 0 0 1 2 0 ...
## $ Ticket : Factor w/ 681 levels "110152","110413",..: 524 597 670 50 473 276 86 396 345 133 ...
## $ Fare : num 7.25 71.28 7.92 53.1 8.05 ...
## $ Cabin : Factor w/ 148 levels "","A10","A14",..: 1 83 1 57 1 1 131 1 1 1 ...
## $ Embarked : Factor w/ 4 levels "","C","Q","S": 4 2 4 4 4 3 4 4 4 2 ...
O primeiro resumo é a tabela de resumo depois de combinar treinar e testar. E o segundo resumo é uma tabela
de resumo do trem. Esses dados incluem nome, sexo, idade, parentesco e outras informações relacionadas ao
ingresso (número do ingresso, taxa do ingresso, tripulação, área de embarque), bem como o PassengerId e a
sobrevivência de seus passageiros.
head(train,10)

## PassengerId Survived Pclass


## 1 1 0 3
## 2 2 1 1
## 3 3 1 3

2
## 4 4 1 1
## 5 5 0 3
## 6 6 0 3
## 7 7 0 1
## 8 8 0 3
## 9 9 1 3
## 10 10 1 2
## Name Sex Age SibSp
## 1 Braund, Mr. Owen Harris male 22 1
## 2 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 38 1
## 3 Heikkinen, Miss. Laina female 26 0
## 4 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35 1
## 5 Allen, Mr. William Henry male 35 0
## 6 Moran, Mr. James male NA 0
## 7 McCarthy, Mr. Timothy J male 54 0
## 8 Palsson, Master. Gosta Leonard male 2 3
## 9 Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) female 27 0
## 10 Nasser, Mrs. Nicholas (Adele Achem) female 14 1
## Parch Ticket Fare Cabin Embarked
## 1 0 A/5 21171 7.2500 S
## 2 0 PC 17599 71.2833 C85 C
## 3 0 STON/O2. 3101282 7.9250 S
## 4 0 113803 53.1000 C123 S
## 5 0 373450 8.0500 S
## 6 0 330877 8.4583 Q
## 7 0 17463 51.8625 E46 S
## 8 1 349909 21.0750 S
## 9 2 347742 11.1333 S
## 10 0 237736 30.0708 C
Aqui está um resumo dos dez dados para o conjunto de trens. Os pontos que podem ser deduzidos são
de primeira classe a terceira classe porque a tarifa é maior quando a pclass é menor. A próxima melhor
informação é que você pode usar o SibSp e o Parch para descobrir o relacionamento familiar de cada passageiro.
Talvez possamos distinguir pelo sobrenome. Eu não sei o que significa a classificação de cabine.
Finalmente, há uma seção de C, Q, S em relação ao Embarked, a área de embarque, e parece estar faltando.
# colSums(is.na(titanic)|titanic=='')
sapply(train, function(x) sum(is.na(x))) # encontrar valores ausentes

## PassengerId Survived Pclass Name Sex Age


## 0 0 0 0 0 177
## SibSp Parch Ticket Fare Cabin Embarked
## 0 0 0 0 0 0
Primeiro, verifiquei onde o valor ausente está no conjunto de dados.
Primeiro, 418 valores perdidos em Sobrevivido são o número de dados no conjunto de testes. Atualmente,
418 desaparecidos do Survived não são importantes porque é um processo de pré-processamento.
No entanto, para o Age, 263 estão faltando valores. A este respeito, vamos lidar com o valor em falta mais
tarde. Um valor em falta para a tarifa e 1014 valores em falta para a cabine. Finalmente, há duas falhas na
área Embarcada.
sapply(train, function(x) length(unique(x))) # encontrando valores únicos

## PassengerId Survived Pclass Name Sex Age


## 891 2 3 891 2 89

3
## SibSp Parch Ticket Fare Cabin Embarked
## 7 7 681 248 148 4
Em seguida, foi encontrada exclusividade para cada variável. Eu acho que é possível pensar por nível de dados.
No conjunto de dados atual do trem, o PassengerID consiste em 891 níveis. E como o nome é classificado de
acordo com esse número, os nomes das pessoas também podem ser deduzidos da ausência do mesmo nome.
Realizamos temporariamente a análise logit com base nos dados do trem.
# verifique a regressão logística
train$Pclass2 <- as.factor(train$Pclass)
glm_train <- glm(Survived ~ factor(Pclass2)+factor(Sex)+factor(Embarked)+Age+SibSp+Parch+Fare, data=trai
summary(glm_train)

##
## Call:
## glm(formula = Survived ~ factor(Pclass2) + factor(Sex) + factor(Embarked) +
## Age + SibSp + Parch + Fare, family = binomial(link = "logit"),
## data = train)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -2.7220 -0.6455 -0.3770 0.6293 2.4461
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 16.691979 607.920015 0.027 0.978095
## factor(Pclass2)2 -1.189637 0.329197 -3.614 0.000302 ***
## factor(Pclass2)3 -2.395220 0.343356 -6.976 3.04e-12 ***
## factor(Sex)male -2.637859 0.223006 -11.829 < 2e-16 ***
## factor(Embarked)C -12.259048 607.919885 -0.020 0.983911
## factor(Embarked)Q -13.082427 607.920088 -0.022 0.982831
## factor(Embarked)S -12.661895 607.919868 -0.021 0.983383
## Age -0.043308 0.008322 -5.204 1.95e-07 ***
## SibSp -0.362925 0.129290 -2.807 0.005000 **
## Parch -0.060365 0.123944 -0.487 0.626233
## Fare 0.001451 0.002595 0.559 0.576143
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 964.52 on 713 degrees of freedom
## Residual deviance: 632.34 on 703 degrees of freedom
## (177 observations deleted due to missingness)
## AIC: 654.34
##
## Number of Fisher Scoring iterations: 13
No conjunto de dados do trem A idade está ausente no modelo porque há 177 valores ausentes. Sugerir que
devemos fazer previsões sobre o valor ausente da Idade no futuro. A idade é uma variável muito importante
porque possui considerável poder explicativo. Com este modelo,
(1) os homens são mais propensos a morrer do que as mulheres
(2) os passageiros de passageiros de primeira classe são mais propensos a sobreviver
(3) Quanto mais jovem quanto mais jovem, maior a probabilidade de sobreviver

4
(4) Quanto menor o SibSp, menor o irmão / irmã, maior a probabilidade de sobreviver.
Se assim for, vamos tentar medir quais variáveis explicativas têm o maior poder preditivo.
regsub <- regsubsets(Survived ~ factor(Pclass)+factor(Sex)+factor(Embarked)+Age+SibSp+Parch+Fare, data=t
summary(regsub)

## Subset selection object


## Call: regsubsets.formula(Survived ~ factor(Pclass) + factor(Sex) +
## factor(Embarked) + Age + SibSp + Parch + Fare, data = train)
## 10 Variables (and intercept)
## Forced in Forced out
## factor(Pclass)2 FALSE FALSE
## factor(Pclass)3 FALSE FALSE
## factor(Sex)male FALSE FALSE
## factor(Embarked)C FALSE FALSE
## factor(Embarked)Q FALSE FALSE
## factor(Embarked)S FALSE FALSE
## Age FALSE FALSE
## SibSp FALSE FALSE
## Parch FALSE FALSE
## Fare FALSE FALSE
## 1 subsets of each size up to 8
## Selection Algorithm: exhaustive
## factor(Pclass)2 factor(Pclass)3 factor(Sex)male factor(Embarked)C
## 1 ( 1 ) " " " " "*" " "
## 2 ( 1 ) " " "*" "*" " "
## 3 ( 1 ) " " "*" "*" " "
## 4 ( 1 ) "*" "*" "*" " "
## 5 ( 1 ) "*" "*" "*" " "
## 6 ( 1 ) "*" "*" "*" "*"
## 7 ( 1 ) "*" "*" "*" " "
## 8 ( 1 ) "*" "*" "*" " "
## factor(Embarked)Q factor(Embarked)S Age SibSp Parch Fare
## 1 ( 1 ) " " " " " " " " " " " "
## 2 ( 1 ) " " " " " " " " " " " "
## 3 ( 1 ) " " " " "*" " " " " " "
## 4 ( 1 ) " " " " "*" " " " " " "
## 5 ( 1 ) " " " " "*" "*" " " " "
## 6 ( 1 ) " " " " "*" "*" " " " "
## 7 ( 1 ) "*" "*" "*" "*" " " " "
## 8 ( 1 ) "*" "*" "*" "*" " " "*"
A função regsubsets () é uma função que diz ao número de variáveis independentes a serem adotadas (N) a
melhor escolha para cada número de casos que podem existir, 2 ˆ N.
Se você verificar apenas os resultados, “sexo” é a variável mais importante se você colocar apenas uma
variável. Então você acha que tem um poder explicativo importante na ordem de Pclass3 (3ª classe), Age,
Pclass2 (2ª classe) e SibSp Você pode. De fato, a tarifa tem um segundo baixo poder explicativo, que pode
ser porque já é determinado pela Pclass. A tarifa será determinada por Embarked e Pclass.
Portanto, tentei analisar novamente, exceto essas duas variáveis.
glm_train2 <- glm(Survived ~ factor(Sex)+Age+SibSp+Parch+Fare, data=train, family =binomial(link='logit'
summary(glm_train2)

##

5
## Call:
## glm(formula = Survived ~ factor(Sex) + Age + SibSp + Parch +
## Fare, family = binomial(link = "logit"), data = train)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -2.5661 -0.6868 -0.5385 0.7323 2.3106
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.557319 0.286161 5.442 5.27e-08 ***
## factor(Sex)male -2.533418 0.205163 -12.348 < 2e-16 ***
## Age -0.021514 0.007182 -2.996 0.002739 **
## SibSp -0.408306 0.122608 -3.330 0.000868 ***
## Parch -0.232515 0.117337 -1.982 0.047523 *
## Fare 0.017247 0.003143 5.487 4.08e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 964.52 on 713 degrees of freedom
## Residual deviance: 695.26 on 708 degrees of freedom
## (177 observations deleted due to missingness)
## AIC: 707.26
##
## Number of Fisher Scoring iterations: 5
Como esperado, Fare explicou que o * em Pclass surgiu. Em seguida, analisamos quão alto é o poder
explicativo relativo a esses cinco fatores.
regsub2 <- regsubsets(Survived ~ factor(Sex)+Age+SibSp+Parch+Fare, data=train)
summary(regsub2)

## Subset selection object


## Call: regsubsets.formula(Survived ~ factor(Sex) + Age + SibSp + Parch +
## Fare, data = train)
## 5 Variables (and intercept)
## Forced in Forced out
## factor(Sex)male FALSE FALSE
## Age FALSE FALSE
## SibSp FALSE FALSE
## Parch FALSE FALSE
## Fare FALSE FALSE
## 1 subsets of each size up to 5
## Selection Algorithm: exhaustive
## factor(Sex)male Age SibSp Parch Fare
## 1 ( 1 ) "*" " " " " " " " "
## 2 ( 1 ) "*" " " " " " " "*"
## 3 ( 1 ) "*" " " "*" " " "*"
## 4 ( 1 ) "*" "*" "*" " " "*"
## 5 ( 1 ) "*" "*" "*" "*" "*"
Gênero, Taxa, SibSp, Idade, Parch.

6
sapply(titanic, function(x) sum(is.na(x))) # finding missing values

## PassengerId Survived Pclass Name Sex Age


## 0 418 0 0 0 263
## SibSp Parch Ticket Fare Cabin Embarked
## 0 0 0 1 0 0
Portanto, prevemos que o poder preditivo dos 418 conjuntos de testes restantes irá variar muito dependendo
de como o valor omisso é tratado para o Age. Nesse caso, você precisa saber se pode ignorar o valor ausente
ou o quanto prever.
ggplot(titanic,aes(Sex,Age)) +
geom_boxplot(aes(fill=factor(Sex)),alpha=0.5) +
ggtitle("Age distribution based on Gender")

Age distribution based on Gender


80

60

factor(Sex)
Age

40 female
male

20

female male
Sex

ggplot(titanic,aes(Pclass,Age)) +
geom_boxplot(aes(fill=factor(Pclass)),alpha=0.5) +
ggtitle("Age distribution based on Pclass")

7
Age distribution based on Pclass
80

60

factor(Pclass)
1
Age

40
2
3

20

1 2 3
Pclass

Eu tirei a distribuição de idade por gênero. Não há grande diferença entre os sexos. Eu desenhei a classe P, a
distribuição de idade de acordo com a classe da sala. A certeza é que os passageiros dos quartos de classe
alta são mais velhos.
FYI: Atualmente o Rggplot não está rodando no ambiente do Juypter Notebook. Como resultado, recebi a
imagem através do R Studio e anexei a imagem. (Eu corrigi o erro depois de instalar o pacote que roda no
notebook Jupyter no R depois)
# Imputação de idade com base em Pclass
impute.age <- function(age,class){
vector <- age
for (i in 1:length(age)){
if (is.na(age[i])){
if (class[i] == 1){
vector[i] <- round(mean(filter(titanic,Pclass==1)$Age, na.rm=TRUE),0)
}else if (class[i] == 2){
vector[i] <- round(mean(filter(titanic,Pclass==2)$Age, na.rm=TRUE),0)
}else{
vector[i] <- round(mean(filter(titanic,Pclass==3)$Age, na.rm=TRUE),0)
}
}else{
vector[i]<-age[i]
}
}
return(vector)
}
imputed.age <- impute.age(titanic$Age,titanic$Pclass)

8
titanic$Age <- imputed.age

Este código foi fornecido por Thilaksha Silva em Kaggle ( https://www.kaggle.com/thilakshasilva/


predicting-titanic-survival-using-five-algorithms/notebook ) para introduzir valores médios de idade de
acordo com o PClass. Aqui está uma breve descrição do código:
Impute.age é uma função que define a linha inteira em titanic $ Age como um único vetor, e se o vetor estiver
faltando, o valor médio dos valores não ausentes das pessoas na classe Para um vetor contendo o valor ausente.
Se não estiver faltando, insira o valor como está.
sapply(titanic, function(x) sum(is.na(x))) # encontrar valores ausentes

## PassengerId Survived Pclass Name Sex Age


## 0 418 0 0 0 0
## SibSp Parch Ticket Fare Cabin Embarked
## 0 0 0 1 0 0
Como resultado, há uma falta de tarifa, exceto a falta (último resultado previsto) do conjunto de dados
titânicos Sobrevivido.
# Dividindo o conjunto de dados no conjunto de treinamento e no conjunto de teste
trainset <- titanic[1:891, c("Survived","Sex","Age","SibSp","Parch","Fare")]
testset <- titanic[892:1309, c("Sex","Age","SibSp","Parch","Fare")]

Trainset e testset são diferenciados. Em seguida, amostramos aleatoriamente novamente para determinar
a precisão do treinamento no conjunto de trens. Geralmente, a estratificação (amostragem de camada) é
realizada (Raschka, 2016). No entanto, aqui nós amostramos aleatoriamente as amostras com números
aleatórios.
set.seed(123)
split = sample.split(trainset$Survived, SplitRatio = 0.8)
train_split = subset(trainset, split == TRUE)
test_split = subset(trainset, split == FALSE)

cor(train_split[,unlist(lapply(train_split,is.numeric))], use="pairwise.complete.obs")

## Survived Age SibSp Parch Fare


## Survived 1.00000000 -0.05240353 -0.03195028 0.08050072 0.2339924
## Age -0.05240353 1.00000000 -0.23516567 -0.16117344 0.1020722
## SibSp -0.03195028 -0.23516567 1.00000000 0.43707325 0.1994916
## Parch 0.08050072 -0.16117344 0.43707325 1.00000000 0.2391090
## Fare 0.23399240 0.10207219 0.19949163 0.23910895 1.0000000
Estou tentando prever Survived through Sex (variável de fator), Age, SibSp, Parch e Fare em meu modelo
atual. Portanto, a Tabela de Correlação dos valores, exceto a Variável Fatorial, é construída. A correlação
entre o SibSp e o Parch é de cerca de 0,44, mas não creio que exista um problema de multi-colinearidade.
# Ajustando a regressão logística ao conjunto de treinamento
classifier = glm(Survived ~ factor(Sex)+Age+SibSp+Parch+Fare, data=train_split, family =binomial(link='l
summary(classifier)

##
## Call:
## glm(formula = Survived ~ factor(Sex) + Age + SibSp + Parch +
## Fare, family = binomial(link = "logit"), data = train_split)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max

9
## -2.3610 -0.6504 -0.5480 0.7148 2.3136
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.612388 0.304442 5.296 1.18e-07 ***
## factor(Sex)male -2.696001 0.208182 -12.950 < 2e-16 ***
## Age -0.019058 0.008071 -2.361 0.018213 *
## SibSp -0.363280 0.107162 -3.390 0.000699 ***
## Parch -0.204586 0.125485 -1.630 0.103025
## Fare 0.012680 0.002757 4.599 4.24e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 949.90 on 712 degrees of freedom
## Residual deviance: 684.33 on 707 degrees of freedom
## AIC: 696.33
##
## Number of Fisher Scoring iterations: 4
vif(classifier)

## factor(Sex) Age SibSp Parch Fare


## 1.129681 1.107207 1.288170 1.314005 1.166215
durbinWatsonTest(classifier)

## lag Autocorrelation D-W Statistic p-value


## 1 -0.004349987 2.003968 0.952
## Alternative hypothesis: rho != 0
Como resultado da medição do VIF entre as variáveis, não há problema de multicolinearidade entre as
variáveis. (Em geral, se o coeficiente VIF for maior que 10, existe um problema). O teste de Durbin-Watson
foi utilizado para mensurar a autocorrelação da variável dependente (Sobrevivência), sendo o resultado 2,
praticamente independente entre as variáveis dependentes.
prob_pred <- predict(classifier, type = 'response', newdata = test_split)
y_pred <- ifelse(prob_pred > 0.5, 1, 0)

# Checking the prediction accuracy


table(test_split$Survived, y_pred > 0.5) # Confusion matrix

##
## FALSE TRUE
## 0 91 19
## 1 21 47
# print accuracy
error <- mean(test_split$Survived != y_pred) # Misclassification error
paste('Accuracy of this model is',round(1-error,4))

## [1] "Accuracy of this model is 0.7753"


Em seguida, usamos a função de previsão para medir o valor previsto do modelo. Em seguida, aplicamos o
valor previsto ao conjunto de dados separado por test_split. Depois disso, foi julgado que os dados (test_split)
sobreviveram se o valor previsto exceder 0,5 (porque é o resultado medido pela análise logit).
Depois disso, uma tabela true-false foi criada para o valor correspondente e o valor do erro foi medido.

10
Finalmente, a precisão do meu modelo atual foi medida em 77,53%.

Fonte dados: https://www.kaggle.com/sandeepcrpunk/titanic-survival-prediction-r/data

11

Você também pode gostar