Introdução

Neste trabalho, aplicamos algoritmos de classificação supervisionada à base de dados Census, com o objetivo de prever a variável alvo a partir de atributos demográficos e socioeconômicos. Foram utilizados dois modelos amplamente empregados em problemas de classificação: o Naive Bayes, conhecido por sua simplicidade e eficiência em conjuntos de dados com muitas variáveis, e a Árvore de Decisão, valorizada por sua capacidade interpretativa.

A base foi dividida em 80% para treinamento e 20% para teste, a fim de avaliar o desempenho de ambos os modelos. Com isso, buscamos não apenas aplicar os conceitos teóricos aprendidos, mas também desenvolver uma análise comparativa entre os dois algoritmos em termos de acurácia e capacidade preditiva.

1. Carregar os dados

# Carregar pacotes
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(caret)
## Carregando pacotes exigidos: lattice
## 
## Anexando pacote: 'caret'
## 
## O seguinte objeto é mascarado por 'package:purrr':
## 
##     lift
library(e1071)   # Naive Bayes
library(rpart)   # Árvore de Decisão
library(rpart.plot)
library(GGally)
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
# Carregar os dados
dados <- read.csv("C:/Users/Windows 11 PRO/Downloads/census.csv")

# Visualizar
glimpse(dados)
## Rows: 32,561
## Columns: 15
## $ age            <int> 39, 50, 38, 53, 28, 37, 49, 52, 31, 42, 37, 30, 23, 32,…
## $ workclass      <chr> " State-gov", " Self-emp-not-inc", " Private", " Privat…
## $ final.weight   <int> 77516, 83311, 215646, 234721, 338409, 284582, 160187, 2…
## $ education      <chr> " Bachelors", " Bachelors", " HS-grad", " 11th", " Bach…
## $ education.num  <int> 13, 13, 9, 7, 13, 14, 5, 9, 14, 13, 10, 13, 13, 12, 11,…
## $ marital.status <chr> " Never-married", " Married-civ-spouse", " Divorced", "…
## $ occupation     <chr> " Adm-clerical", " Exec-managerial", " Handlers-cleaner…
## $ relationship   <chr> " Not-in-family", " Husband", " Not-in-family", " Husba…
## $ race           <chr> " White", " White", " White", " Black", " Black", " Whi…
## $ sex            <chr> " Male", " Male", " Male", " Male", " Female", " Female…
## $ capital.gain   <int> 2174, 0, 0, 0, 0, 0, 0, 0, 14084, 5178, 0, 0, 0, 0, 0, …
## $ capital.loos   <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ hour.per.week  <int> 40, 13, 40, 40, 40, 40, 16, 45, 50, 40, 80, 40, 30, 50,…
## $ native.country <chr> " United-States", " United-States", " United-States", "…
## $ income         <chr> " <=50K", " <=50K", " <=50K", " <=50K", " <=50K", " <=5…

2. Pré-processamento

# Verificar e tratar NAs (se houver)
dados <- na.omit(dados)

# Transformar variável alvo em fator (supondo que a coluna alvo se chama 'income')
dados$income <- as.factor(dados$income)

3 Análise Exploratória dos Dados (EDA)

# Gráfico de distribuição da variável alvo
ggplot(dados, aes(income)) +
  geom_bar(fill = "steelblue") +
  theme_minimal() +
  labs(title = "Distribuição da variável alvo (income)")

# Idade por faixa de renda
ggplot(dados, aes(age, fill = income)) +
  geom_histogram(bins = 30, position = "dodge") +
  theme_minimal() +
  labs(title = "Distribuição da idade por faixa de renda")

# Correlação entre variáveis numéricas
dados_num <- dados %>% select(where(is.numeric))
ggcorr(dados_num, label = TRUE, label_round = 2, label_size = 3)

4. Dividir em treino (80%) e teste (20%)

set.seed(123)
indice <- createDataPartition(dados$income, p = 0.8, list = FALSE)
treino <- dados[indice, ]
teste <- dados[-indice, ]

5. Modelo Naive Bayes

modelo_nb <- naiveBayes(income ~ ., data = treino)
prev_nb <- predict(modelo_nb, newdata = teste)
conf_nb <- confusionMatrix(prev_nb, teste$income)
conf_nb
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  <=50K  >50K
##      <=50K   4590   801
##      >50K     354   767
##                                           
##                Accuracy : 0.8226          
##                  95% CI : (0.8131, 0.8318)
##     No Information Rate : 0.7592          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.4626          
##                                           
##  Mcnemar's Test P-Value : < 2.2e-16       
##                                           
##             Sensitivity : 0.9284          
##             Specificity : 0.4892          
##          Pos Pred Value : 0.8514          
##          Neg Pred Value : 0.6842          
##              Prevalence : 0.7592          
##          Detection Rate : 0.7049          
##    Detection Prevalence : 0.8279          
##       Balanced Accuracy : 0.7088          
##                                           
##        'Positive' Class :  <=50K          
## 
# Métricas adicionais - Naive Bayes
conf_nb$byClass[c("Precision", "Recall", "F1")]
## Precision    Recall        F1 
## 0.8514190 0.9283981 0.8882438

6. Modelo Árvore de Decisão

modelo_arvore <- rpart(income ~ ., data = treino, method = "class")
rpart.plot(modelo_arvore)

prev_arvore <- predict(modelo_arvore, newdata = teste, type = "class")

conf_arvore <- confusionMatrix(prev_arvore, teste$income)
conf_arvore
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  <=50K  >50K
##      <=50K   4675   767
##      >50K     269   801
##                                           
##                Accuracy : 0.8409          
##                  95% CI : (0.8318, 0.8497)
##     No Information Rate : 0.7592          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.5119          
##                                           
##  Mcnemar's Test P-Value : < 2.2e-16       
##                                           
##             Sensitivity : 0.9456          
##             Specificity : 0.5108          
##          Pos Pred Value : 0.8591          
##          Neg Pred Value : 0.7486          
##              Prevalence : 0.7592          
##          Detection Rate : 0.7179          
##    Detection Prevalence : 0.8357          
##       Balanced Accuracy : 0.7282          
##                                           
##        'Positive' Class :  <=50K          
## 
# Métricas adicionais - Árvore de Decisão
conf_arvore$byClass[c("Precision", "Recall", "F1")]
## Precision    Recall        F1 
## 0.8590592 0.9455906 0.9002503

7. Importância das Variáveis (Árvore)

modelo_arvore$variable.importance
##   relationship marital.status   capital.gain      education  education.num 
##     1953.26386     1922.60688      816.23568      756.60043      756.60043 
##            sex     occupation            age  hour.per.week native.country 
##      603.36249      540.46995      451.07188      255.69578       15.66416 
##   capital.loos 
##       13.94754

Conclusão

A partir da aplicação dos algoritmos de classificação Naive Bayes e Árvore de Decisão à base de dados Census, foi possível observar o comportamento de ambos os modelos em um contexto real de mineração de dados. O Naive Bayes demonstrou ser eficiente, especialmente pela sua simplicidade e velocidade de execução, enquanto a Árvore de Decisão se destacou pela interpretabilidade dos resultados, permitindo visualizar claramente os critérios de decisão.

Com a divisão dos dados em conjuntos de treinamento e teste, foi possível realizar uma avaliação justa do desempenho de cada modelo. A comparação por meio da matriz de confusão e das métricas de acurácia forneceu insights valiosos sobre a capacidade preditiva de cada abordagem.