Árvores: RF, XGBoost, LightGBM
- ⬜🔧 Feature engineering sério(Machine Learning Clássico)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
Árvores: o inductive bias certo para tabular
Decision trees particionam o espaço de features com splits axis-aligned, otimizando redução de impureza (Gini, entropy) ou MSE. Uma árvore sozinha overfitta. Ensembles de árvores resolvem isso de duas formas canônicas: bagging (RF) e boosting (XGBoost/LightGBM/CatBoost).
Árvores são invariantes a transformações monotônicas (log, sqrt, StandardScaler são irrelevantes) e lidam com missing values nativamente. Isso economiza 50% do pipeline comparado a modelos lineares.
Random Forest
| Aspecto | Ensacamento (florestas) | Impulsionamento (gradiente) |
|---|---|---|
| Como combina | Muitas árvores independentes, média no fim | Árvores em sequência, cada uma corrige o resto da anterior |
| Paralelizável | Sim, naturalmente | Não entre árvores — só dentro de cada uma |
| Sensível a hiperparâmetro | Pouco: mais árvores raramente piora | Muito: taxa de aprendizado e profundidade decidem tudo |
| Sobreajuste | Difícil, por construção | Fácil sem parada antecipada |
| Desempenho típico em tabular | Bom, e quase de graça | Melhor, com ajuste |
| Quando preferir | Linha de base rápida e robusta | Quando o último ponto percentual importa |
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
rf = RandomForestClassifier(
n_estimators=500, # mais árvores = melhor até platô; custo linear
max_depth=None, # deixar crescer, controlar via min_samples_leaf
min_samples_leaf=20, # folha precisa min 20 exemplos -> regulariza
max_features='sqrt', # em cada split, considera sqrt(n_features)
class_weight='balanced_subsample',
n_jobs=-1, # paraleliza árvores
random_state=42,
)
scores = cross_val_score(rf, X, y, cv=5, scoring='roc_auc', n_jobs=-1)
print(f'RF AUC: {scores.mean():.4f}')XGBoost com early stopping
import xgboost as xgb
from sklearn.model_selection import train_test_split
X_tr, X_val, y_tr, y_val = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
model = xgb.XGBClassifier(
n_estimators=5000, # teto alto; early stopping decide
learning_rate=0.05, # menor = mais árvores, geralmente melhor
max_depth=6, # 4-8 típico para tabular
subsample=0.8, # bagging de linhas
colsample_bytree=0.8, # bagging de colunas
reg_alpha=0.1, reg_lambda=1.0,
eval_metric='auc',
early_stopping_rounds=50,
tree_method='hist', # histogram mode -> rápido
device='cuda', # ou 'cpu'
random_state=42,
)
model.fit(X_tr, y_tr, eval_set=[(X_val, y_val)], verbose=100)
print(f'best_iteration: {model.best_iteration}')Nunca confunda eval_set com test set. O eval_set guia early stopping e, portanto, é tecnicamente parte do treino. Mantenha um test set holdout intocado para reportar a métrica final.
Árvores são invariantes a transformações monotônicas e lidam com valores ausentes nativamente. Que consequência prática isso tem?
LightGBM, CatBoost e quando escolher cada
import lightgbm as lgb
lgbm = lgb.LGBMClassifier(
n_estimators=5000,
learning_rate=0.05,
num_leaves=31, # leaf-wise: controlar num_leaves < 2^max_depth
min_data_in_leaf=50,
feature_fraction=0.8,
bagging_fraction=0.8, bagging_freq=5,
reg_alpha=0.1, reg_lambda=1.0,
objective='binary', metric='auc',
n_jobs=-1, random_state=42,
)
lgbm.fit(X_tr, y_tr, eval_set=[(X_val, y_val)], callbacks=[lgb.early_stopping(50)])
# CatBoost: use quando tem muitas categóricas de alta cardinalidade
from catboost import CatBoostClassifier
cat = CatBoostClassifier(
iterations=5000, learning_rate=0.05, depth=6,
cat_features=['city', 'product_category'],
eval_metric='AUC', early_stopping_rounds=50, verbose=100,
)Regra de bolso: LightGBM para speed em dataset médio-grande; XGBoost para maturidade e integração (Spark, GPU); CatBoost quando features categóricas dominam.
Feature importance e interpretabilidade
import shap
explainer = shap.TreeExplainer(model)
shap_values = explainer(X_val)
shap.plots.beeswarm(shap_values, max_display=15)
shap.plots.waterfall(shap_values[0]) # explicação local de uma prediçãoSHAP values são o padrão moderno para explicar boosting. Gain-based importance do XGBoost enviesa para features de alta cardinalidade. SHAP é aditivo, teoricamente fundado (Shapley values) e roda em tempo aceitável via TreeExplainer.
Perguntas frequentes
❓ Floresta aleatória ou impulsionamento por gradiente?
❓ Por que árvores dominam dado tabular?
❓ Como evitar que o modelo impulsionado decore?
Fixando
Por que o conjunto usado para parada antecipada não pode ser o mesmo conjunto de teste?
A importância baseada em ganho enviesa para variáveis de alta cardinalidade. Qual é a alternativa recomendada e por quê?
Terminou de ler?
Marcar como concluído registra o XP, mantém sua sequência e coloca 3 cartas deste módulo na fila de revisão espaçada.
Próximos passos sugeridos
Temas deste módulo
Discussão
Carregando comentários…