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.
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) |
A função str() revela os tipos de cada variável,
enquanto summary() fornece estatísticas descritivas das
colunas numéricas mais relevantes.
## '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" ...
## 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.Fare) varia de £0 a
£512.33, refletindo grande disparidade socioeconômica
entre os passageiros.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
## Classes presentes: 1 2
## 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.
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.
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 ---
##
## Adolescente Adulto Criança Desconhecida Idoso
## 45 575 68 177 26
##
## --- Tamanho de Família ---
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.000 1.000 1.000 1.905 2.000 11.000
##
## --- Viajou 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.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")| 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:
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.
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.
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.
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)\[ 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, ...})\).
\[ \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.
\[ \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.
\[ 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.
\[ 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.
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 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.