1 Introdução

O naufrágio do RMS Titanic, ocorrido em 1912, é considerado um dos maiores desastres marítimos da história moderna. Além de sua relevância histórica, o conjunto de dados do Titanic tornou-se amplamente utilizado em estudos de Ciência de Dados e Aprendizado de Máquina.

O dataset contém informações demográficas, econômicas e sociais dos passageiros, permitindo investigar quais fatores influenciaram diretamente as chances de sobrevivência.

Neste relatório, será utilizada uma abordagem de aprendizado supervisionado baseada em Árvores de Decisão para prever a sobrevivência dos passageiros.

Os principais objetivos deste trabalho são:

  • Realizar o pré-processamento dos dados;
  • Criar novas variáveis;
  • Explorar padrões estatísticos;
  • Construir modelos preditivos;
  • Avaliar o desempenho dos modelos;
  • Interpretar os resultados obtidos.

2 Fundamentação Teórica

2.1 Árvores de Decisão

Árvores de Decisão são modelos supervisionados utilizados para tarefas de classificação e regressão. Esses algoritmos realizam divisões sucessivas nos dados, criando subconjuntos mais homogêneos.

Neste trabalho, foi utilizado o algoritmo CART (Classification and Regression Trees), implementado no pacote rpart.

2.2 Critérios de Divisão

Os principais critérios utilizados em Árvores de Decisão incluem:

  • Entropia;
  • Ganho de Informação;
  • Índice Gini.

O pacote rpart utiliza o Índice Gini como critério padrão para seleção das divisões.


3 Carregamento e Pré-processamento

3.1 Carregamento dos Dados

df <- titanic_train

kable(
  head(df),
  caption = "Primeiras Linhas do Dataset Titanic"
) |>
  kable_styling(
    bootstrap_options = c(
      "striped",
      "hover",
      "condensed"
    ),
    full_width = FALSE
  )
Primeiras Linhas do Dataset Titanic
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
1 0 3 Braund, Mr. Owen Harris male 22 1 0 A/5 21171 7.2500 S
2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 38 1 0 PC 17599 71.2833 C85 C
3 1 3 Heikkinen, Miss. Laina female 26 0 0 STON/O2. 3101282 7.9250 S
4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35 1 0 113803 53.1000 C123 S
5 0 3 Allen, Mr. William Henry male 35 0 0 373450 8.0500 S
6 0 3 Moran, Mr. James male NA 0 0 330877 8.4583 Q

O conjunto de dados possui:

  • 891 observações;
  • 12 variáveis.

3.2 Transformação das Variáveis

df <- df %>%
  
  mutate(
    
    Survived = factor(
      Survived,
      levels = c(0, 1),
      labels = c("Morreu", "Sobreviveu")
    ),
    
    Pclass = factor(Pclass),
    
    Sex = factor(
      Sex,
      labels = c("Feminino", "Masculino")
    )
  )

str(df)
## 'data.frame':    891 obs. of  12 variables:
##  $ PassengerId: int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Survived   : Factor w/ 2 levels "Morreu","Sobreviveu": 1 2 2 2 1 1 1 1 2 2 ...
##  $ Pclass     : Factor w/ 3 levels "1","2","3": 3 1 3 1 3 3 1 3 3 2 ...
##  $ Name       : chr  "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ...
##  $ Sex        : Factor w/ 2 levels "Feminino","Masculino": 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" ...

As variáveis categóricas foram convertidas para o tipo factor, permitindo melhor interpretação e modelagem estatística.


3.3 Engenharia de Variáveis

df_filtrado <- df %>%
  
  filter(!is.na(Age)) %>%
  
  mutate(
    
    FaixaEtaria = case_when(
      Age < 12 ~ "Criança",
      Age < 18 ~ "Adolescente",
      Age < 60 ~ "Adulto",
      TRUE     ~ "Idoso"
    ),
    
    FaixaEtaria = factor(
      FaixaEtaria,
      levels = c(
        "Criança",
        "Adolescente",
        "Adulto",
        "Idoso"
      )
    ),
    
    TamanhoFamilia = SibSp + Parch + 1
  )

cat(
  "Quantidade de registros removidos:",
  nrow(df) - nrow(df_filtrado)
)
## Quantidade de registros removidos: 177

Foram removidos registros com idade ausente (NA) e criadas novas variáveis derivadas para enriquecer a análise.


4 Análise Exploratória

4.1 Sobrevivência por Sexo

O gráfico abaixo apresenta a relação entre sexo e taxa de sobrevivência.

ggplot(
  df_filtrado,
  aes(x = Sex, fill = Survived)
) +
  
  geom_bar(position = "fill") +
  
  scale_y_continuous(
    labels = percent
  ) +
  
  labs(
    title = "Taxa de Sobrevivência por Sexo",
    x = "Sexo",
    y = "Proporção"
  ) +
  
  theme_minimal()

Observa-se que passageiros do sexo feminino apresentaram probabilidade significativamente maior de sobrevivência.


4.2 Sobrevivência por Classe

ggplot(
  df_filtrado,
  aes(x = Pclass, fill = Survived)
) +
  
  geom_bar(position = "fill") +
  
  scale_y_continuous(
    labels = percent
  ) +
  
  labs(
    title = "Taxa de Sobrevivência por Classe",
    x = "Classe",
    y = "Proporção"
  ) +
  
  theme_minimal()

Passageiros da primeira classe apresentaram maiores taxas de sobrevivência.


4.3 Distribuição das Idades

ggplot(
  df_filtrado,
  aes(x = Age, fill = Survived)
) +
  
  geom_histogram(
    bins = 30,
    alpha = 0.7,
    position = "identity"
  ) +
  
  labs(
    title = "Distribuição das Idades",
    x = "Idade",
    y = "Frequência"
  ) +
  
  theme_minimal()

Crianças apresentaram maior proporção de sobrevivência.


4.4 Sobrevivência por Faixa Etária

ggplot(
  df_filtrado,
  aes(x = FaixaEtaria, fill = Survived)
) +
  
  geom_bar(position = "fill") +
  
  scale_y_continuous(labels = percent) +
  
  labs(
    title = "Sobrevivência por Faixa Etária",
    x = "Faixa Etária",
    y = "Proporção"
  ) +
  
  theme_minimal()


4.5 Boxplot da Tarifa por Classe

ggplot(
  df_filtrado,
  aes(
    x = Pclass,
    y = Fare,
    fill = Pclass
  )
) +
  
  geom_boxplot() +
  
  labs(
    title = "Distribuição da Tarifa por Classe",
    x = "Classe",
    y = "Tarifa"
  ) +
  
  theme_minimal()


4.6 Heatmap de Correlação

dados_cor <- df_filtrado %>%
  select(
    Age,
    Fare,
    SibSp,
    Parch,
    TamanhoFamilia
  )

matriz_cor <- cor(dados_cor)

corrplot(
  matriz_cor,
  method = "color",
  type = "upper"
)


4.7 Resumo Estatístico

resumo <- df_filtrado %>%
  
  group_by(
    FaixaEtaria,
    Survived
  ) %>%
  
  summarise(
    Quantidade = n(),
    IdadeMedia = round(mean(Age), 1),
    TarifaMedia = round(mean(Fare), 2),
    .groups = "drop"
  )

kable(
  resumo,
  caption = "Resumo Estatístico"
) |>
  
  kable_styling(
    bootstrap_options = c(
      "striped",
      "hover"
    ),
    full_width = FALSE
  )
Resumo Estatístico
FaixaEtaria Survived Quantidade IdadeMedia TarifaMedia
Criança Morreu 29 6.0 34.26
Criança Sobreviveu 39 3.7 30.03
Adolescente Morreu 23 15.9 17.75
Adolescente Sobreviveu 22 15.4 43.41
Adulto Morreu 353 31.7 21.44
Adulto Sobreviveu 222 32.8 56.51
Idoso Morreu 19 65.4 40.40
Idoso Sobreviveu 7 64.3 51.79

5 Divisão dos Dados

set.seed(123)

indices <- createDataPartition(
  df_filtrado$Survived,
  p = 0.7,
  list = FALSE
)

train_data <- df_filtrado[indices, ]
test_data  <- df_filtrado[-indices, ]

cat(
  "Treino:", nrow(train_data),
  "\nTeste:", nrow(test_data)
)
## Treino: 500 
## Teste: 214

Foi utilizada divisão estratificada 70/30 para preservar a proporção das classes.


6 Modelagem Preditiva

6.1 Modelo Baseline

tree_model_baseline <- rpart(
  
  Survived ~ Pclass + Sex + Age,
  
  data = train_data,
  
  method = "class",
  
  control = rpart.control(
    maxdepth = 4,
    minsplit = 20,
    cp = 0.01
  )
)

6.2 Modelo com Fare

tree_model_fare <- rpart(
  
  Survived ~ Pclass + Sex + Age + Fare,
  
  data = train_data,
  
  method = "class",
  
  control = rpart.control(
    maxdepth = 4,
    minsplit = 20,
    cp = 0.01
  )
)

A profundidade máxima da árvore foi limitada para reduzir o risco de overfitting.


7 Visualização da Árvore

rpart.plot(
  tree_model_fare,
  
  type = 4,
  
  extra = 104,
  
  fallen.leaves = TRUE,
  
  shadow.col = "gray",
  
  box.palette = "RdYlGn",
  
  branch.lty = 3,
  
  tweak = 1.2,
  
  main = "Árvore de Decisão - Modelo com Fare"
)

A variável Sex foi selecionada como nó raiz por apresentar maior capacidade de separação entre as classes.


8 Importância das Variáveis

importancia <- data.frame(
  
  Variavel = names(
    tree_model_fare$variable.importance
  ),
  
  Importancia = tree_model_fare$variable.importance
)

kable(
  importancia,
  caption = "Importância das Variáveis"
) |>
  
  kable_styling(
    bootstrap_options = c(
      "striped",
      "hover"
    ),
    full_width = FALSE
  )
Importância das Variáveis
Variavel Importancia
Sex Sex 65.72925
Pclass Pclass 28.89049
Fare Fare 24.18973
Age Age 23.14598

9 Avaliação dos Modelos

9.1 Previsões

pred_baseline <- predict(
  tree_model_baseline,
  test_data,
  type = "class"
)

pred_fare <- predict(
  tree_model_fare,
  test_data,
  type = "class"
)

9.2 Matrizes de Confusão

matriz_baseline <- confusionMatrix(
  pred_baseline,
  test_data$Survived,
  positive = "Sobreviveu"
)

matriz_fare <- confusionMatrix(
  pred_fare,
  test_data$Survived,
  positive = "Sobreviveu"
)

matriz_fare
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   Morreu Sobreviveu
##   Morreu        103         22
##   Sobreviveu     24         65
##                                           
##                Accuracy : 0.785           
##                  95% CI : (0.7239, 0.8381)
##     No Information Rate : 0.5935          
##     P-Value [Acc > NIR] : 0.000000002262  
##                                           
##                   Kappa : 0.5561          
##                                           
##  Mcnemar's Test P-Value : 0.8828          
##                                           
##             Sensitivity : 0.7471          
##             Specificity : 0.8110          
##          Pos Pred Value : 0.7303          
##          Neg Pred Value : 0.8240          
##              Prevalence : 0.4065          
##          Detection Rate : 0.3037          
##    Detection Prevalence : 0.4159          
##       Balanced Accuracy : 0.7791          
##                                           
##        'Positive' Class : Sobreviveu      
## 

9.3 Comparação das Métricas

metricas <- data.frame(
  
  Metrica = c(
    "Acurácia",
    "Recall",
    "Precisão",
    "F1-Score"
  ),
  
  Baseline = round(c(
    matriz_baseline$overall["Accuracy"],
    matriz_baseline$byClass["Sensitivity"],
    matriz_baseline$byClass["Precision"],
    matriz_baseline$byClass["F1"]
  ), 4),
  
  Com_Fare = round(c(
    matriz_fare$overall["Accuracy"],
    matriz_fare$byClass["Sensitivity"],
    matriz_fare$byClass["Precision"],
    matriz_fare$byClass["F1"]
  ), 4)
)

kable(
  metricas,
  caption = "Comparação entre os Modelos"
) |>
  
  kable_styling(
    bootstrap_options = c(
      "striped",
      "hover"
    ),
    full_width = FALSE
  )
Comparação entre os Modelos
Metrica Baseline Com_Fare
Accuracy Acurácia 0.7757 0.7850
Sensitivity Recall 0.5977 0.7471
Precision Precisão 0.8000 0.7303
F1 F1-Score 0.6842 0.7386

O modelo com a variável Fare apresentou desempenho superior ao modelo baseline.


10 Curva ROC

probabilidades <- predict(
  tree_model_fare,
  test_data,
  type = "prob"
)[,2]

roc_obj <- roc(
  test_data$Survived,
  probabilidades,
  levels = c(
    "Morreu",
    "Sobreviveu"
  )
)

plot(
  roc_obj,
  main = "Curva ROC"
)

auc(roc_obj)
## Area under the curve: 0.8385

A Curva ROC avalia a capacidade discriminativa do modelo.


11 Tabela Interativa

tabela <- df_filtrado %>%
  
  select(
    Nome = Name,
    Sexo = Sex,
    Idade = Age,
    Classe = Pclass,
    Tarifa = Fare,
    Sobreviveu = Survived
  )

datatable(
  
  tabela,
  
  extensions = c("Buttons"),
  
  options = list(
    
    dom = "Bfrtip",
    
    buttons = c(
      "copy",
      "csv",
      "excel",
      "pdf"
    ),
    
    pageLength = 10,
    
    scrollX = TRUE,
    
    language = list(
      search = "Buscar:",
      lengthMenu = "Mostrar _MENU_ registros",
      info = "Exibindo _START_ a _END_ de _TOTAL_ registros"
    )
  ),
  
  filter = "top",
  
  rownames = FALSE,
  
  class = "table table-striped table-hover"
)

12 Equações Matemáticas

12.1 Entropia de Shannon

A Entropia de Shannon mede o nível de desordem presente em um conjunto de dados.

\[ H(S) = -\sum_{i=1}^{c} p_i \log_2(p_i) \]


12.2 Ganho de Informação

O Ganho de Informação mede a redução da entropia após uma divisão.

\[ IG(S,A)=H(S)-\sum_{v\in valores(A)} \frac{|S_v|}{|S|}H(S_v) \]


12.3 Índice Gini

O Índice Gini é utilizado pelo algoritmo CART para selecionar as melhores divisões.

\[ Gini(S)=1-\sum_{i=1}^{c}p_i^2 \]


12.4 F1-Score

O F1-Score representa a média harmônica entre Precisão e Recall.

\[ F_1 = 2 \cdot \frac{Precisao \times Recall} {Precisao + Recall} \]


13 Discussão dos Resultados

Os resultados demonstraram que o sexo foi a variável mais relevante para prever a sobrevivência dos passageiros.

Além disso, passageiros das classes superiores apresentaram maiores taxas de sobrevivência, indicando forte influência socioeconômica.

A inclusão da variável Fare melhorou levemente o desempenho do modelo, sugerindo correlação entre valor da passagem e chance de sobrevivência.

As Árvores de Decisão apresentaram elevada interpretabilidade, permitindo compreender claramente os critérios utilizados pelo modelo.


14 Conclusão

O presente trabalho demonstrou a aplicação de Árvores de Decisão na previsão da sobrevivência dos passageiros do Titanic.

Os resultados mostraram que variáveis como sexo, classe social, idade e tarifa paga tiveram influência significativa na sobrevivência.

O modelo apresentou desempenho satisfatório e elevada interpretabilidade.

Como trabalhos futuros, recomenda-se:

  • Utilizar Random Forest;
  • Aplicar validação cruzada;
  • Testar algoritmos mais complexos;
  • Investigar técnicas de balanceamento de classes.

15 Referências

  • BREIMAN, L. et al. Classification and Regression Trees. CRC Press, 1984.

  • KUHN, M.; JOHNSON, K. Applied Predictive Modeling. Springer, 2013.

  • WICKHAM, H. ggplot2: Elegant Graphics for Data Analysis. Springer, 2016.

  • XIE, Y. R Markdown: The Definitive Guide. CRC Press, 2018.