📊 Análise de Dados

Apresentação do Dataset

O conjunto de dados Titanic é amplamente utilizado em Ciência de Dados e Aprendizado de Máquina (Baumer; Udwin, 2015). Ele contém informações sobre os passageiros a bordo do RMS Titanic, que naufragou em 15 de abril de 1912. O objetivo principal costuma ser prever a sobrevivência dos passageiros com base em variáveis como sexo, idade, classe socioeconômica e número de familiares a bordo.


1. Carregamento dos Dados

O dataset titanic_train é carregado diretamente do pacote titanic. A função head() exibe as primeiras linhas para uma inspeção inicial.

# Carregamento do dataset
dados <- titanic::titanic_train

# Inspecionar as primeiras linhas
head(dados, 8)

O dataset contém 891 observações e 12 variáveis. A tabela abaixo descreve cada coluna:

Variável Tipo Descrição
PassengerId Inteiro Identificador único do passageiro
Survived Binária Sobreviveu? (0 = Não, 1 = Sim)
Pclass Ordinal Classe da cabine (1ª, 2ª ou 3ª)
Name Texto Nome completo
Sex Categórica Sexo do passageiro
Age Numérica Idade em anos
SibSp Inteiro Nº de irmãos/cônjuges a bordo
Parch Inteiro Nº de pais/filhos a bordo
Fare Numérica Tarifa paga (libras esterlinas)
Embarked Categórica Porto de embarque (C = Cherbourg, Q = Queenstown, S = Southampton)

2. Estrutura e Resumo Estatístico

A função str() revela os tipos de cada variável, enquanto summary() fornece estatísticas descritivas das colunas numéricas mais relevantes.

str(dados)
## '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       : chr  "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ...
##  $ Sex        : chr  "male" "female" "female" "female" ...
##  $ 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" ...
summary(dados[, c("Survived", "Pclass", "Age", "SibSp", "Parch", "Fare")])
##     Survived          Pclass           Age            SibSp      
##  Min.   :0.0000   Min.   :1.000   Min.   : 0.42   Min.   :0.000  
##  1st Qu.:0.0000   1st Qu.:2.000   1st Qu.:20.12   1st Qu.:0.000  
##  Median :0.0000   Median :3.000   Median :28.00   Median :0.000  
##  Mean   :0.3838   Mean   :2.309   Mean   :29.70   Mean   :0.523  
##  3rd Qu.:1.0000   3rd Qu.:3.000   3rd Qu.:38.00   3rd Qu.:1.000  
##  Max.   :1.0000   Max.   :3.000   Max.   :80.00   Max.   :8.000  
##                                   NA's   :177                    
##      Parch             Fare       
##  Min.   :0.0000   Min.   :  0.00  
##  1st Qu.:0.0000   1st Qu.:  7.91  
##  Median :0.0000   Median : 14.45  
##  Mean   :0.3816   Mean   : 32.20  
##  3rd Qu.:0.0000   3rd Qu.: 31.00  
##  Max.   :6.0000   Max.   :512.33  
## 

Principais observações:

  • Age possui 177 valores ausentes (NA), equivalendo a 19.9% do total — o que exige atenção nas etapas seguintes.
  • A tarifa (Fare) varia de £0 a £512.33, refletindo grande disparidade socioeconômica entre os passageiros.
  • A taxa geral de sobrevivência é de 38.4%, ou seja, menos da metade dos passageiros sobreviveu.

3. Filtragem

A filtragem remove registros com idade desconhecida e restringe a análise às classes 1 e 2, garantindo dados completos para comparações demográficas.

# Manter apenas passageiros com idade conhecida das classes 1 e 2
dados_filtrados <- dados %>%
  filter(!is.na(Age), Pclass %in% c(1, 2))

cat("Registros após filtragem:", nrow(dados_filtrados), "\n")
## Registros após filtragem: 359
cat("Classes presentes:", sort(unique(dados_filtrados$Pclass)), "\n")
## Classes presentes: 1 2
cat("Valores ausentes em Age:", sum(is.na(dados_filtrados$Age)), "\n")
## Valores ausentes em Age: 0

Resultado: Restaram 359 passageiros após a filtragem. A condição !is.na(Age) elimina registros com idade desconhecida, e Pclass %in% c(1, 2) seleciona apenas as duas primeiras classes. Após a filtragem, não há mais valores ausentes em Age.


4. Ordenação

O dataset filtrado é reordenado pela tarifa paga (decrescente) e, em caso de empate, pela idade (crescente), permitindo identificar os passageiros de maior poder aquisitivo.

# Ordenar por tarifa decrescente e idade crescente
dados_ordenados <- dados_filtrados %>%
  arrange(desc(Fare), Age) %>%
  select(PassengerId, Name, Sex, Age, Pclass, Fare, Survived)

head(dados_ordenados, 10)

Resultado: Os passageiros com as tarifas mais altas pertencem majoritariamente à 1ª classe. A ordenação dupla (desc(Fare) + Age) resolve empates de tarifa priorizando os passageiros mais jovens. Tarifas elevadas estão associadas a maior probabilidade de sobrevivência, refletindo o acesso prioritário aos botes salva-vidas.


5. Criação de Novas Variáveis

Novas colunas são criadas com mutate() para enriquecer o dataset com informações derivadas, tornando a análise mais interpretável.

dados_enriquecidos <- dados %>%
  mutate(
    # Categorização da idade em faixas etárias
    FaixaEtaria = case_when(
      is.na(Age)  ~ "Desconhecida",
      Age < 12    ~ "Criança",
      Age < 18    ~ "Adolescente",
      Age < 60    ~ "Adulto",
      TRUE        ~ "Idoso"
    ),
    # Tamanho total do grupo familiar (inclui o próprio passageiro)
    TamanhoFamilia  = SibSp + Parch + 1,
    # Flag: viajou sozinho?
    Sozinho         = ifelse(TamanhoFamilia == 1, "Sim", "Não"),
    # Rótulos legíveis para classe e sobrevivência
    ClasseTexto     = recode(as.character(Pclass),
                             "1" = "1ª Classe",
                             "2" = "2ª Classe",
                             "3" = "3ª Classe"),
    SobreviveuTexto = ifelse(Survived == 1, "Sobreviveu", "Não Sobreviveu")
  )

cat("--- Faixa Etária ---\n")
## --- Faixa Etária ---
print(table(dados_enriquecidos$FaixaEtaria))
## 
##  Adolescente       Adulto      Criança Desconhecida        Idoso 
##           45          575           68          177           26
cat("\n--- Tamanho de Família ---\n")
## 
## --- Tamanho de Família ---
print(summary(dados_enriquecidos$TamanhoFamilia))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   1.000   1.000   1.905   2.000  11.000
cat("\n--- Viajou Sozinho? ---\n")
## 
## --- Viajou Sozinho? ---
print(table(dados_enriquecidos$Sozinho))
## 
## Não Sim 
## 354 537

Resultado:

  • FaixaEtaria: criada com case_when(), que avalia condições em sequência e atribui o primeiro valor verdadeiro. A maioria dos passageiros são adultos (18–59 anos).
  • TamanhoFamilia: soma de SibSp + Parch + 1 (o próprio passageiro). Valor igual a 1 indica que o passageiro viajou sozinho.
  • Sozinho: 60.3% dos passageiros viajaram desacompanhados.

6. Agregação por Grupo

Com group_by() e summarise(), calculam-se estatísticas por subgrupo — neste caso, por classe e sexo — para comparar as taxas de sobrevivência.

tabela_sobrevivencia <- dados_enriquecidos %>%
  group_by(ClasseTexto, Sex) %>%
  summarise(
    Total         = n(),
    Sobreviventes = sum(Survived),
    Taxa_Sobrev   = round(mean(Survived) * 100, 1),
    Idade_Media   = round(mean(Age, na.rm = TRUE), 1),
    Tarifa_Media  = round(mean(Fare, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  arrange(ClasseTexto, desc(Taxa_Sobrev))

kable(tabela_sobrevivencia,
      col.names = c("Classe", "Sexo", "Total", "Sobreviventes",
                    "Taxa Sobrev. (%)", "Idade Média", "Tarifa Média (£)"),
      caption = "Tabela 1: Análise de Sobrevivência por Classe e Sexo") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE) %>%
  row_spec(0, bold = TRUE, background = "#2c3e50", color = "white")
Tabela 1: Análise de Sobrevivência por Classe e Sexo
Classe Sexo Total Sobreviventes Taxa Sobrev. (%) Idade Média Tarifa Média (£)
1ª Classe female 94 91 96.8 34.6 106.13
1ª Classe male 122 45 36.9 41.3 67.23
2ª Classe female 76 70 92.1 28.7 21.97
2ª Classe male 108 17 15.7 30.7 19.74
3ª Classe female 144 72 50.0 21.8 16.12
3ª Classe male 347 47 13.5 26.5 12.66

Resultado: Três padrões se destacam:

  1. Mulheres sobreviveram muito mais do que homens em todas as classes, reflexo da regra “mulheres e crianças primeiro”.
  2. Passageiros da 1ª classe tiveram as maiores taxas de sobrevivência, especialmente as mulheres (acima de 90%).
  3. Homens da 3ª classe apresentaram a menor taxa, evidenciando forte desigualdade no acesso às saídas de emergência.

7. Visualizações

ggplot(tabela_sobrevivencia,
       aes(x = ClasseTexto, y = Taxa_Sobrev, fill = Sex)) +
  geom_col(position = "dodge", alpha = 0.85, color = "white", linewidth = 0.3) +
  geom_text(aes(label = paste0(Taxa_Sobrev, "%")),
            position = position_dodge(width = 0.9),
            vjust = -0.4, size = 3.5, fontface = "bold") +
  scale_fill_manual(values = c("female" = "#e74c3c", "male" = "#3498db"),
                    labels = c("Feminino", "Masculino"), name = "Sexo") +
  labs(title    = "Taxa de Sobrevivência no Titanic",
       subtitle = "Estratificada por Classe da Cabine e Sexo",
       x = "Classe da Cabine", y = "Taxa de Sobrevivência (%)",
       caption = "Fonte: Dataset Titanic — pacote titanic (CRAN)") +
  theme_minimal(base_size = 13) +
  theme(plot.title    = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5, color = "gray40"),
        legend.position = "top") +
  ylim(0, 105)
Figura 1: Taxa de sobrevivência por classe e sexo.

Figura 1: Taxa de sobrevivência por classe e sexo.

Resultado: Mulheres de 1ª classe ultrapassam 96% de sobrevivência, enquanto homens de 3ª classe ficam abaixo de 15% — a maior disparidade registrada no dataset.

dados_enriquecidos %>%
  filter(!is.na(Age), FaixaEtaria != "Desconhecida") %>%
  mutate(FaixaEtaria = factor(FaixaEtaria,
                              levels = c("Criança", "Adolescente", "Adulto", "Idoso"))) %>%
  ggplot(aes(x = Age, fill = SobreviveuTexto)) +
  geom_histogram(bins = 25, alpha = 0.75, color = "white", linewidth = 0.2) +
  facet_wrap(~ FaixaEtaria, scales = "free_x") +
  scale_fill_manual(values = c("Sobreviveu" = "#27ae60", "Não Sobreviveu" = "#c0392b"),
                    name = "Status") +
  labs(title    = "Distribuição de Idade por Faixa Etária",
       subtitle = "Colorida pelo Status de Sobrevivência",
       x = "Idade (anos)", y = "Frequência",
       caption = "Fonte: Dataset Titanic — pacote titanic (CRAN)") +
  theme_minimal(base_size = 12) +
  theme(plot.title    = element_text(face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5, color = "gray40"),
        legend.position = "bottom",
        strip.text = element_text(face = "bold"))
Figura 2: Distribuição da idade por faixa etária e status de sobrevivência.

Figura 2: Distribuição da idade por faixa etária e status de sobrevivência.

Resultado: Crianças apresentaram maior taxa relativa de sobrevivência. Adultos formam o maior grupo em termos absolutos, tanto de sobreviventes quanto de vítimas.


📋 Tabela Interativa

Tabela Interativa com o Pacote DT

A tabela abaixo exibe os passageiros do Titanic com todas as variáveis originais e as derivadas criadas na seção anterior. O pacote DT (Xie; Allaire; Grolemund, 2018) permite busca em tempo real, ordenação por coluna, filtros individuais, paginação e exportação dos dados em diferentes formatos.

dados_dt <- dados_enriquecidos %>%
  select(PassengerId, Name, Sex, Age, Pclass,
         FaixaEtaria, TamanhoFamilia, Sozinho,
         Fare, Embarked, SobreviveuTexto) %>%
  rename(ID             = PassengerId,
         Nome           = Name,
         Sexo           = Sex,
         Idade          = Age,
         Classe         = Pclass,
         `Faixa Etária` = FaixaEtaria,
         `Tam. Família` = TamanhoFamilia,
         Sozinho        = Sozinho,
         Tarifa         = Fare,
         Embarque       = Embarked,
         Status         = SobreviveuTexto) %>%
  mutate(Sexo   = recode(Sexo, "male" = "Masculino", "female" = "Feminino"),
         Tarifa = round(Tarifa, 2))

datatable(
  dados_dt,
  rownames   = FALSE,
  filter     = "top",
  extensions = "Buttons",
  options    = list(
    dom        = "lBfrtip",
    buttons    = list("copy", "csv", "excel", "pdf", "print"),
    pageLength = 15,
    lengthMenu = list(c(10, 15, 25, 50, -1),
                      c("10", "15", "25", "50", "Todos")),
    scrollX    = TRUE,
    autoWidth  = TRUE,
    language   = list(
      search      = "Buscar:",
      lengthMenu  = "Mostrar _MENU_ registros",
      info        = "Mostrando _START_ a _END_ de _TOTAL_ registros",
      infoEmpty   = "Nenhum registro encontrado",
      zeroRecords = "Nenhum registro correspondente",
      paginate    = list(`first` = "Primeiro", `last` = "Último",
                         `next` = "Próximo", `previous` = "Anterior")
    )
  ),
  caption = htmltools::tags$caption(
    style = "caption-side:top; text-align:center; font-weight:bold; font-size:14px;",
    "Tabela 2 — Passageiros do Titanic com Variáveis Derivadas"
  )
) %>%
  formatStyle("Status",
              backgroundColor = styleEqual(
                c("Sobreviveu", "Não Sobreviveu"),
                c("#d5f5e3", "#fadbd8")),
              fontWeight = "bold") %>%
  formatStyle("Classe",
              backgroundColor = styleEqual(
                c(1, 2, 3),
                c("#d6eaf8", "#fef9e7", "#fdebd0"))) %>%
  formatCurrency("Tarifa", currency = "£", digits = 2)

📐 Equações LaTeX

Cinco Equações Fundamentais em Ciência de Dados


Equação 1 — Regressão Logística (Função Sigmoide)

\[ P(Y = 1 \mid \mathbf{x}) = \frac{1}{1 + e^{-(\mathbf{w}^\top \mathbf{x} + b)}} \]

Significado: Modela a probabilidade de um evento binário ocorrer dado um vetor de características \(\mathbf{x}\) (Baumer et al., 2014). A saída é sempre entre 0 e 1, sendo interpretada como probabilidade. O vetor \(\mathbf{w}\) representa os pesos de cada variável e \(b\) é o viés (bias). No contexto do Titanic, estima \(P(\text{Sobreviveu} = 1 \mid \text{sexo, classe, idade, ...})\).


Equação 2 — Entropia Cruzada Binária (Função de Perda)

\[ \mathcal{L}(\mathbf{w}) = -\frac{1}{n} \sum_{i=1}^{n} \left[ y_i \log\hat{p}_i + (1 - y_i) \log(1 - \hat{p}_i) \right] \]

Significado: Função de perda padrão para classificação binária (Xie; Dervieux; Riederer, 2020). Penaliza o modelo quando a probabilidade predita \(\hat{p}_i\) diverge do rótulo verdadeiro \(y_i \in \{0, 1\}\). Quanto menor \(\mathcal{L}\), maior o alinhamento entre predições e realidade. É minimizada via gradiente descendente durante o treinamento.


Equação 3 — Gradiente Descendente Estocástico

\[ \mathbf{w}_{t+1} = \mathbf{w}_t - \eta \cdot \nabla_{\mathbf{w}} \mathcal{L}\!\left(\mathbf{w}_t;\, x_i, y_i\right) \]

Significado: Algoritmo de otimização que atualiza os parâmetros \(\mathbf{w}\) iterativamente na direção oposta ao gradiente da perda (Baumer; Udwin, 2015). O hiperparâmetro \(\eta > 0\) (taxa de aprendizado) controla o tamanho do passo. A versão estocástica usa um único exemplo por iteração, tornando o treinamento eficiente em grandes volumes de dados.


Equação 4 — Teorema de Bayes

\[ P(\theta \mid \mathcal{D}) = \frac{P(\mathcal{D} \mid \theta)\; P(\theta)}{\displaystyle\int P(\mathcal{D} \mid \theta)\, P(\theta)\; d\theta} \]

Significado: Fundamento da estatística bayesiana (Xie; Allaire; Grolemund, 2018). \(P(\theta \mid \mathcal{D})\) é a distribuição a posteriori dos parâmetros após observar os dados \(\mathcal{D}\); \(P(\mathcal{D} \mid \theta)\) é a verossimilhança e \(P(\theta)\) é a priori. No algoritmo Naive Bayes, esta equação calcula a probabilidade de pertencimento a uma classe dada a presença de certas variáveis preditoras.


Equação 5 — Critério de Impureza de Gini

\[ G(p) = 1 - \sum_{k=1}^{K} p_k^2 \]

Significado: Mede a impureza de um nó em uma árvore de decisão (Xie, 2016). \(p_k\) é a proporção de amostras da classe \(k\) no nó e \(K\) é o número total de classes. \(G = 0\) indica pureza perfeita (todas as amostras pertencem à mesma classe). O algoritmo CART minimiza \(G\) ao escolher os melhores atributos e pontos de corte para dividir os nós da árvore.


🖼️ Figuras

Figuras Relacionadas à Ciência de Dados


Figura 3 — Ciclo de Vida de um Projeto de Ciência de Dados (CRISP-DM)

Figura 3: Diagrama do ciclo CRISP-DM (Cross Industry Standard Process for Data Mining). Fonte: Wikimedia Commons.

Figura 3: Diagrama do ciclo CRISP-DM (Cross Industry Standard Process for Data Mining). Fonte: Wikimedia Commons.

O CRISP-DM (Cross Industry Standard Process for Data Mining) é a metodologia de referência para projetos de Ciência de Dados (Baumer; Udwin, 2015). O diagrama ilustra seis etapas cíclicas: entendimento do negócio, entendimento dos dados, preparação dos dados, modelagem, avaliação e implantação. As setas bidirecionais indicam que o processo é iterativo — é comum retornar a etapas anteriores conforme novos aprendizados surgem ao longo do projeto.


Figura 4 — Árvore de Decisão Treinada no Dataset Titanic

Figura 4: Árvore de decisão CART para sobrevivência no Titanic. Fonte: Wikimedia Commons.

Figura 4: Árvore de decisão CART para sobrevivência no Titanic. Fonte: Wikimedia Commons.

A figura exibe uma árvore de decisão treinada diretamente no dataset Titanic (Xie; Dervieux; Riederer, 2020). Cada nó interno representa uma regra de divisão baseada em uma variável preditora (sex, age, sibsp), e cada folha indica a classe predita com a respectiva proporção do grupo. A variável sex é a mais discriminante: passageiros do sexo masculino têm probabilidade de sobrevivência muito menor, resultado consistente com a análise exploratória da Aba 1.


📚 Referências

BAUMER, Ben et al. R Markdown: Integrating a reproducible analysis tool into introductory statistics. arXiv preprint arXiv:1402.1894, 2014.
BAUMER, Benjamin; UDWIN, Dana. R markdown. Wiley Interdisciplinary Reviews: Computational Statistics, v. 7, n. 3, p. 167–177, 2015.
XIE, Yihui. Bookdown: Authoring books and technical documents with R markdown. [S.l.]: Chapman; Hall/CRC, 2016.
XIE, Yihui; ALLAIRE, Joseph J.; GROLEMUND, Garrett. R markdown: The definitive guide. [S.l.]: Chapman; Hall/CRC, 2018.
XIE, Yihui; DERVIEUX, Christophe; RIEDERER, Emily. R markdown cookbook. [S.l.]: Chapman; Hall/CRC, 2020.