Code
install.packages("tidymodels")
library(tidymodels)O tidymodels é um meta-pacote (coleção de pacotes) que fornece uma interface unificada para modelagem estatística e machine learning em R, seguindo os princípios do tidyverse.
Carrega automaticamente:
rsample - divisão de dadosrecipes - pré-processamentoparsnip - especificação de modelosworkflows - combinação de receitas e modelosyardstick - métricas de avaliaçãotune - ajuste de hiperparâmetrosdials - parâmetros de ajustebroom - organização de resultadosinitial_split()Pacote: rsample
Função: Divide os dados em conjuntos de treino e teste
Parâmetros:
data: dataset a ser divididoprop: proporção para treino (padrão: 0.75 = 75%)strata: variável para estratificação (mantém distribuição)Retorna: objeto rsplit com informações sobre a divisão
Exemplo estratificado:
training() e testing()Função: Extrai os conjuntos de treino e teste
Retorna: tibble/data.frame com os dados correspondentes
Notas importantes:
initial_split() usa amostragem aleatória simples ou estratificadarsplit armazena apenas índices, não duplica os dadosset.seed() antes para reprodutibilidadePacote: rsample
Função: Cria folds para validação cruzada k-fold
Parâmetros:
data: dados de treinov: número de folds (padrão: 10)strata: variável para estratificaçãorepeats: número de repetiçõesComo funciona:
v partes aproximadamente iguaisv-1 folds servem como treinoInterpretação:
Outras funções de reamostragem:
Pacote: recipes
Função: Cria uma “receita” de pré-processamento
Parâmetros:
formula: fórmula modelo (resposta ~ preditoras)data: dados de referência (apenas estrutura). para incluir todas as variáveis: Sale_Price ~ .Importante: A recipe apenas DEFINE os passos, não os executa
Fluxo de trabalho com recipes:
recipe() - define a receitastep_*() - adiciona passos de transformaçãoprep() - prepara a receita (calcula parâmetros nos dados de treino)bake() - aplica a receita preparada a novos dadosQuando usado dentro de um workflow, prep() e bake() são chamados automaticamente.
step_normalize()Função: Padroniza variáveis (z-score: média=0, desvio=1)
Fórmula: (x - média) / desvio_padrão
Quando usar:
Seletores disponíveis:
all_numeric_predictors(): todas numéricas preditorasall_nominal_predictors(): todas categóricasall_predictors(): todas as preditorasall_outcomes(): variável respostastep_normalize(Gr_Liv_Area, Lot_Area)Alternativa - step_range():
step_dummy()Função: Cria variáveis dummy para categóricas
Como funciona:
Parâmetros:
one_hot: TRUE para criar k variáveis (ao invés de k-1)naming: função para nomear as novas variáveisImportante: Sempre aplique após transformações numéricas e antes de interações
step_log()Função: Aplica transformação logarítmica
Quando usar:
Cuidado:
offset para lidar com zeros: step_log(var, offset = 1)Alternativas:
step_impute_mean() / step_impute_median()Função: Imputa valores faltantes (NA)
Tipos de imputação:
step_impute_mean(): média (sensível a outliers)step_impute_median(): mediana (robusta a outliers)step_impute_mode(): moda (para categóricas)step_impute_knn(): k vizinhos mais próximos (preserva relações)step_impute_linear(): regressão linearstep_impute_bag(): bagged treesExemplo KNN:
Considerações:
step_indicate_na() cria variável binária indicando se havia NAstep_pca()Função: Análise de Componentes Principais
Quando usar:
Parâmetros:
num_comp: número de componentes a manterthreshold: variância explicada mínima acumuladaoptions: lista com opções adicionaisImportante:
Tratamento de outliers:
Interações:
Polinômios:
Binning:
Pacote: parsnip
Função: Especifica modelo de regressão linear
Componentes:
set_engine()Define o pacote/função R que executará o modelo
Engines disponíveis para linear_reg():
"lm": regressão linear padrão (stats::lm)"glmnet": Ridge, Lasso, Elastic Net"stan": abordagem Bayesiana"keras": redes neurais"spark": para processamento distribuídoArgumentos específicos do engine:
set_mode()Define o tipo de problema
"regression": para variável resposta contínua"classification": para variável resposta categóricaNota: Para linear_reg(), o modo é sempre “regression”
Parâmetros de regularização:
Parâmetros:
penalty: força da regularização (lambda)
mixture: tipo de penalização
Interpretação:
Comparação Ridge vs Lasso:
| Aspecto | Ridge | Lasso |
|---|---|---|
| Penalização | L2 (soma dos quadrados) | L1 (soma dos valores absolutos) |
| Seleção de variáveis | Não | Sim |
| Coeficientes | Reduz, nunca zera | Pode zerar |
| Multicolinearidade | Lida bem | Seleciona uma variável do grupo |
| Interpretabilidade | Menos | Mais (modelo esparso) |
Pacote: parsnip
Função: Especifica modelo Random Forest
Parâmetros principais:
trees: número de árvores (padrão: 500)
mtry: variáveis consideradas em cada divisão
min_n: observações mínimas por nó terminal
Engines disponíveis:
"ranger": rápido e eficiente (recomendado)"randomForest": implementação clássica"spark": para big dataExemplo com todos os parâmetros:
Como funciona:
Vantagens:
Desvantagens:
Configurações específicas do ranger:
Quando usar: Geralmente superior em competições, excelente performance
Quando usar: Interpretabilidade máxima, baseline simples
Quando usar: Dados não-lineares, dimensionalidade média
Quando usar: Padrões complexos, muitos dados disponíveis
Pacote: workflows
Função: Combina recipe e modelo em pipeline único
Vantagens:
Fluxo de trabalho:
Componentes:
add_recipe()Adiciona recipe de pré-processamento
add_model()Adiciona especificação do modelo
add_formula()Alternativa a recipe para casos simples (sem pré-processamento complexo)
Quando usar formula vs recipe:
add_variables()Alternativa mais flexível
Inspecionando workflows:
Função: Treina o workflow nos dados
O que acontece:
Retorna: workflow treinado (fitted workflow)
Importante:
fit() sempre usa os dados fornecidos para preparar a recipefit() nos dados de testeVerificando o ajuste:
Função: Treina o workflow com validação cruzada
Parâmetros:
resamples: objeto vfold_cv ou outro tipo de reamostragemmetrics: métricas a calcular (padrão: rmse e rsq)control: controles adicionaisControles úteis:
Retorna: objeto com resultados de todos os folds
Para coletar resultados:
Interpretação dos resultados:
mean: performance média nos 10 foldsn: número de foldsstd_err: erro padrão (variabilidade entre folds)Vantagens do fit_resamples():
Função: Faz predições com modelo treinado
Retorna: tibble com coluna .pred
Tipos de predição:
Exemplo completo com teste:
# Predições
test_pred <- predict(ames_fit, ames_test)
# Adicionar aos dados originais
test_results <- ames_test %>%
select(Sale_Price) %>%
bind_cols(test_pred)
# Com intervalos
test_pred_int <- predict(ames_fit, ames_test, type = "conf_int")
test_results_full <- ames_test %>%
select(Sale_Price) %>%
bind_cols(test_pred) %>%
bind_cols(test_pred_int)Predições em novos dados:
Importante:
extract_fit_parsnip()Extrai o modelo parsnip do workflow
Uso: Acessar modelo para inspeção, importância de variáveis, etc.
extract_fit_engine()Extrai o modelo do engine original (ex: objeto lm)
extract_recipe()Extrai a recipe preparada
extract_preprocessor()Extrai o pré-processador (recipe ou formula)
tidy()Pacote: broom
Função: Organiza coeficientes em tibble
Retorna: tibble com:
term: nome da variávelestimate: coeficiente estimadostd.error: erro padrãostatistic: estatística tp.value: p-valorTambém funciona com recipes:
glance()Sumário do modelo em uma linha
Retorna: R², AIC, BIC, sigma, etc. (dependendo do modelo)
augment()Adiciona predições e resíduos aos dados
Retorna: dados originais com .fitted, .resid, etc.
Pacote: yardstick
Função: Calcula métricas de performance
Parâmetros:
truth: valores reais (observados)estimate: valores preditosRetorna (regressão):
rmse: Root Mean Squared Errorrsq: R-squaredmae: Mean Absolute ErrorExemplo completo:
Fórmula: √(Σ(real - predito)² / n)
Interpretação:
Quando menor, melhor
Propriedades:
Fórmula: 1 - (SS_res / SS_tot)
Onde:
Interpretação:
Valores típicos:
< 0.3: fraco
0.3-0.5: moderado
0.5-0.7: bom
0.7-0.9: muito bom
0.9: excelente (cuidado com overfitting)
Limitações:
Fórmula: Σ|real - predito| / n
Interpretação:
Quando usar:
Comparação RMSE vs MAE:
Fórmula: (100/n) × Σ|real - predito| / |real|
Interpretação:
Limitações:
metric_set() - Conjunto customizadoVantagem: Calcular todas de uma vez, consistente em todo o código
Outras métricas úteis para regressão:
# MASE - Mean Absolute Scaled Error
ames_results %>%
mase(truth = Sale_Price, estimate = .pred)
# CCC - Concordance Correlation Coefficient
ames_results %>%
ccc(truth = Sale_Price, estimate = .pred)
# SMAPE - Symmetric MAPE
ames_results %>%
smape(truth = Sale_Price, estimate = .pred)
# Huber Loss (robusto a outliers)
ames_results %>%
huber_loss(truth = Sale_Price, estimate = .pred)Criando métricas customizadas:
Colunas retornadas:
.metric: nome da métricamean: média entre foldsn: número de foldsstd_err: erro padrão da média.config: configuração do modeloInterpretação:
mean: performance esperada em novos dadosstd_err: variabilidade entre folds
Exemplo de output:
# A tibble: 2 × 6
.metric .estimator mean n std_err .config
<chr> <chr> <dbl> <int> <dbl> <chr>
1 rmse standard 30456 10 1234 Preprocessor1_Model1
2 rsq standard 0.81 10 0.02 Preprocessor1_Model1
Leitura:
# Métricas por fold individual
cv_results %>%
collect_metrics(summarize = FALSE)
# Predições por fold
cv_results %>%
collect_predictions()
# Visualizar variabilidade
cv_results %>%
collect_metrics(summarize = FALSE) %>%
ggplot(aes(x = id, y = .estimate)) +
geom_point() +
facet_wrap(~ .metric, scales = "free_y") +
labs(x = "Fold", y = "Valor da Métrica")Vantagem: Estimativa ainda mais estável, reduz viés da divisão específica
Quando usar:
Quando usar: Alternativa ao k-fold quando divisões aleatórias são preferíveis
Quando usar: Dados de séries temporais, respeita ordem temporal
Benefícios:
Quando usar estratificação:
vip() - Variable Importance PlotPacote: vip
Função: Visualiza importância das variáveis
Como funciona por tipo de modelo:
Tipos de importância:
Interpretação:
Customização do plot:
Vantagem: Explica contribuição de cada variável para predição individual
tune() - Marcador para tuningParâmetros que podem ser otimizados:
tune_grid() - Grid searchlibrary(dials)
# Definir grid de busca
rf_grid <- grid_regular(
mtry(range = c(2, 10)),
min_n(range = c(5, 30)),
levels = 5 # 5 valores para cada parâmetro = 25 combinações
)
# Workflow com modelo a ser otimizado
rf_workflow <- workflow() %>%
add_recipe(ames_recipe) %>%
add_model(rf_spec)
# Tuning
tune_results <- tune_grid(
rf_workflow,
resamples = ames_folds,
grid = rf_grid,
metrics = metric_set(rmse, rsq, mae),
control = control_grid(save_pred = TRUE, verbose = TRUE)
)Tipos de grid:
# Grid regular (espaçamento uniforme)
grid_regular(mtry(), min_n(), levels = 5)
# Grid aleatório (mais pontos, menos estruturado)
grid_random(mtry(), min_n(), size = 50)
# Grid específico (manual)
grid_manual <- tibble(
mtry = c(3, 5, 7),
min_n = c(10, 20, 30)
)
# Grid latino hipercubo (boa cobertura do espaço)
grid_latin_hypercube(mtry(), min_n(), size = 30)# Ver todas as combinações
collect_metrics(tune_results)
# Melhores resultados
show_best(tune_results, metric = "rmse", n = 10)
# Visualizar
autoplot(tune_results)
# Plot customizado
tune_results %>%
collect_metrics() %>%
filter(.metric == "rmse") %>%
ggplot(aes(x = mtry, y = mean, color = factor(min_n))) +
geom_line() +
geom_point() +
labs(title = "Performance por Hiperparâmetro")select_best() - Seleciona melhor combinaçãofinalize_workflow() - Atualiza workflow# Finalizar com melhores parâmetros
final_workflow <- finalize_workflow(rf_workflow, best_params)
# Treinar modelo final
final_fit <- final_workflow %>%
fit(ames_train)
# Avaliar no teste
final_results <- ames_test %>%
select(Sale_Price) %>%
bind_cols(predict(final_fit, ames_test))
final_results %>%
metrics(truth = Sale_Price, estimate = .pred)Vantagem: Explora espaço de hiperparâmetros de forma mais inteligente
Vantagem: Economiza tempo descartando configurações ruins cedo
Características do RDS:
library(bundle)
# Para modelos que não serializam bem
# (keras, xgboost, spark, etc.)
bundled_model <- bundle(ames_fit)
saveRDS(bundled_model, "models/model_bundled.rds")
# Carregar e desempacotar
loaded <- readRDS("models/model_bundled.rds")
unbundled_model <- unbundle(loaded)
# Usar
predict(unbundled_model, new_data)Quando usar bundle:
Vantagem: Framework completo para MLOps
library(stacks)
# Definir modelos candidatos
ctrl_grid <- control_stack_grid()
# Tuning de múltiplos modelos
rf_res <- tune_grid(rf_workflow, ames_folds, grid = 10, control = ctrl_grid)
xgb_res <- tune_grid(xgb_workflow, ames_folds, grid = 10, control = ctrl_grid)
lm_res <- fit_resamples(lm_workflow, ames_folds, control = ctrl_grid)
# Criar stack
model_stack <- stacks() %>%
add_candidates(rf_res) %>%
add_candidates(xgb_res) %>%
add_candidates(lm_res)
# Treinar meta-modelo
stack_fit <- model_stack %>%
blend_predictions() %>%
fit_members()
# Predições
predict(stack_fit, ames_test)Sequência correta:
Pipeline ideal:
# 1. Dividir
split <- initial_split(dados, prop = 0.75, strata = resposta)
treino <- training(split)
teste <- testing(split)
# 2. Explorar apenas treino
summary(treino)
ggplot(treino, aes(x = preditor, y = resposta)) + geom_point()
# 3. Recipe baseada no treino
recipe <- recipe(resposta ~ ., data = treino) %>%
step_normalize(all_numeric_predictors())
# 4. Validação cruzada no treino
folds <- vfold_cv(treino, v = 10)
cv_results <- workflow() %>%
add_recipe(recipe) %>%
add_model(modelo) %>%
fit_resamples(folds)
# 5. Avaliar CV
collect_metrics(cv_results)
# 6. Treinar modelo final
fit_final <- workflow() %>%
add_recipe(recipe) %>%
add_model(modelo) %>%
fit(treino)
# 7. Testar UMA VEZ
teste_results <- teste %>%
select(resposta) %>%
bind_cols(predict(fit_final, teste))Data leakage ocorre quando informação do teste “vaza” para o treino
Exemplos de leakage:
# ERRADO - Remove outliers antes de dividir
dados_sem_outliers <- dados %>%
filter(valor < quantile(valor, 0.95))
split <- initial_split(dados_sem_outliers)
# CORRETO - Remove dentro da recipe ou não remove
split <- initial_split(dados)
recipe <- recipe(resposta ~ ., training(split)) %>%
step_filter(valor < quantile(valor, 0.95))# ERRADO - Seleção de variáveis em todos os dados
modelo <- lm(resposta ~ var1 + var2, data = dados) # baseado em todos
split <- initial_split(dados %>% select(resposta, var1, var2))
# CORRETO - Seleção dentro do treino
split <- initial_split(dados)
# Análise exploratória apenas no treino para escolher variáveisPrevenção:
Benefícios da estratificação:
Número de estratos:
breaks se necessárioVerificações importantes:
library(ggplot2)
# 1. Normalidade dos resíduos
ggplot(resultados, aes(sample = residuos)) +
stat_qq() +
stat_qq_line() +
labs(title = "Q-Q Plot - Normalidade dos Resíduos")
# Teste de Shapiro-Wilk
shapiro.test(resultados$residuos)
# 2. Homocedasticidade (variância constante)
ggplot(resultados, aes(x = .pred, y = residuos)) +
geom_point(alpha = 0.5) +
geom_hline(yintercept = 0, color = "red", linetype = "dashed") +
geom_smooth(se = FALSE) +
labs(
x = "Valores Preditos",
y = "Resíduos",
title = "Resíduos vs Predições"
)
# 3. Distribuição dos resíduos
ggplot(resultados, aes(x = residuos)) +
geom_histogram(bins = 30, fill = "steelblue", alpha = 0.7) +
labs(title = "Distribuição dos Resíduos")
# 4. Resíduos vs variáveis preditoras
ggplot(resultados %>% bind_cols(teste %>% select(Gr_Liv_Area)),
aes(x = Gr_Liv_Area, y = residuos)) +
geom_point(alpha = 0.5) +
geom_hline(yintercept = 0, color = "red", linetype = "dashed") +
geom_smooth(se = FALSE)
# 5. Valores preditos vs reais
ggplot(resultados, aes(x = Sale_Price, y = .pred)) +
geom_point(alpha = 0.5) +
geom_abline(slope = 1, intercept = 0, color = "red", linetype = "dashed") +
labs(
x = "Valores Reais",
y = "Valores Preditos",
title = "Predito vs Real"
)Padrões problemáticos:
# Outliers (resíduos padronizados > 3)
outliers <- resultados %>%
filter(abs(residuos_padrao) > 3)
# Visualizar
ggplot(resultados, aes(x = seq_along(residuos), y = residuos_padrao)) +
geom_point() +
geom_hline(yintercept = c(-3, 3), color = "red", linetype = "dashed") +
labs(x = "Índice", y = "Resíduos Padronizados")
# Para regressão linear: Distância de Cook
modelo_lm <- extract_fit_engine(fit_final)
cooks_d <- cooks.distance(modelo_lm)
plot(cooks_d, type = "h")
abline(h = 4/length(cooks_d), col = "red", lty = 2)| Modelo | Uso Principal | Vantagens | Desvantagens |
|---|---|---|---|
| Linear | Baseline, interpretabilidade | Simples, rápido, interpretável | Assume linearidade |
| Ridge | Multicolinearidade | Estabiliza coeficientes | Mantém todas variáveis |
| Lasso | Seleção variáveis | Remove variáveis irrelevantes | Pode ser instável |
| Elastic Net | Combinação | Equilibra Ridge e Lasso | Mais hiperparâmetros |
| Random Forest | Relações complexas | Não-linear, robusto | Menos interpretável, lento |
# 1. PREPARAÇÃO DOS DADOS
library(tidymodels)
library(modeldata)
data("ames")
set.seed(123)
# Divisão estratificada
ames_split <- initial_split(ames, prop = 0.75, strata = Sale_Price)
ames_train <- training(ames_split)
ames_test <- testing(ames_split)
# 2. PRÉ-PROCESSAMENTO
ames_recipe <- recipe(Sale_Price ~ Gr_Liv_Area + Year_Built +
Garage_Area + Total_Bsmt_SF,
data = ames_train) %>%
step_normalize(all_numeric_predictors()) %>% # Padronização
step_impute_median(all_numeric_predictors()) # Imputa NAs
# 3. ESPECIFICAÇÃO DO MODELO
lm_spec <- linear_reg() %>%
set_engine("lm") %>%
set_mode("regression")
# 4. WORKFLOW
ames_wf <- workflow() %>%
add_recipe(ames_recipe) %>%
add_model(lm_spec)
# 5. VALIDAÇÃO CRUZADA
set.seed(456)
ames_folds <- vfold_cv(ames_train, v = 10, strata = Sale_Price)
cv_results <- ames_wf %>%
fit_resamples(
resamples = ames_folds,
control = control_resamples(save_pred = TRUE))
# 6. AVALIAÇÃO CV
collect_metrics(cv_results)
# 7. TREINO FINAL
final_fit <- ames_wf %>%
fit(ames_train)
# 8. TESTE
test_results <- ames_test %>%
select(Sale_Price) %>%
bind_cols(predict(final_fit, ames_test))
# 9. MÉTRICAS FINAIS
test_results %>%
metrics(truth = Sale_Price, estimate = .pred)
# 10. ANÁLISE DE RESÍDUOS
test_results <- test_results %>%
mutate(residuos = Sale_Price - .pred)
summary(test_results$residuos)
# 11. PREDIÇÃO NOVA
nova_casa <- tibble(
Gr_Liv_Area = 2000,
Year_Built = 2010,
Garage_Area = 500,
Total_Bsmt_SF = 1200)
predict(final_fit, nova_casa)Causa: Variável na fórmula não existe nos dados
Solução: Verificar nomes com names(dados)
Causa: Problema no pré-processamento ou dados
Solução: Verificar NAs, valores infinitos, variáveis constantes
Causa: Multicolinearidade perfeita
Solução: Remover variáveis redundantes ou usar regularização
Causa: Dados novos faltam variáveis usadas no treino
Solução: Garantir mesma estrutura nos novos dados
themis: balanceamento de classesembed: feature engineering avançadotextrecipes: processamento de textousemodels: gera código tidymodels automaticamenteArtifact: Visualização ou objeto criado no processo de análise
Bootstrap: Reamostragem com reposição
Cross-validation: Validação cruzada k-fold
Feature engineering: Criação/transformação de variáveis
Holdout: Conjunto de teste separado
Hyperparameter: Parâmetro definido antes do treino
Leakage: Vazamento de informação do teste para treino
Overfitting: Modelo muito ajustado aos dados de treino
Pipeline: Sequência automatizada de operações
Resampling: Técnicas de reamostragem (CV, bootstrap)
Stratification: Manter distribuição da resposta em divisões
Tuning: Otimização de hiperparâmetros
Que cada gole desperte uma nova ideia.
Que cada script abra uma nova conversa.
Que o Café com R, se torne um ponto de encontro nosso!