Você treinou seu primeiro modelo de aprendizado de máquina. Ele tem um desempenho brilhante em seus dados de treinamento – 98% de precisão! Você testa em novos dados e ele desmorona: 61% de precisão. O que deu errado?
Quase certamente, seu modelo possui overfit. Este é um dos dois modos de falha mais comuns no aprendizado de máquina, e entendê-lo — junto com seu oposto, underfitting — é essencial para construir modelos que realmente funcionem no mundo real.
Antes de mergulhar nos exemplos, é útil compreender a estrutura teórica por trás desses conceitos: a compensação entre viés e variância.
Todo modelo comete erros de previsão. Esses erros podem ser decompostos em três partes:
Total Error = Bias² + Variance + Irreducible Noise
Viés é o erro de suposições erradas no modelo. Um modelo de alto viés é muito simples – ele falha sistematicamente no verdadeiro padrão dos dados.
Variância é o erro da sensibilidade a pequenas flutuações nos dados de treinamento. Um modelo de alta variância é muito complexo – ele memoriza os dados de treinamento, incluindo seu ruído, em vez de aprender o padrão subjacente.
Ruído irredutível é a aleatoriedade natural nos dados que nenhum modelo pode eliminar.
A desvantagem: reduzir o viés tende a aumentar a variância e vice-versa. Seu trabalho como profissional de aprendizado de máquina é encontrar o ponto ideal.
O underfitting ocorre quando seu modelo é muito simples para capturar o verdadeiro padrão nos dados. Ele tem um desempenho ruim em ambos dados de treinamento e novos dados.
Imagine que você tem dados que mostram os preços das casas com base no tamanho. A verdadeira relação é aproximadamente uma curva suave – os preços aumentam com o tamanho, mas com alguma estagnação no topo.
Se você ajustar uma linha reta horizontal a esses dados:
# Underfitting: overly simple model
from sklearn.linear_model import LinearRegression
import numpy as np
# True relationship is quadratic, but we're fitting a simple mean
model = DummyRegressor(strategy='mean')
model.fit(X_train, y_train)
# Training accuracy: 55%
# Test accuracy: 54%
# Both are bad — classic underfitting
O modelo ignora a relação real entre o tamanho da casa e o preço. Não importa se você mostra dados de treinamento ou novos dados - está errado de qualquer maneira.
Entrar participar da discussão
Overfitting ocorre quando seu modelo aprende os dados de treinamento muito bem — incluindo seu ruído e variação aleatória — e não consegue generalizar para novos exemplos.
Usando um polinômio de 15 graus para ajustar os mesmos dados de preços de casas:
# Overfitting: overly complex model
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
# Degree-15 polynomial — wildly complex for this problem
model = make_pipeline(PolynomialFeatures(15), LinearRegression())
model.fit(X_train, y_train)
train_score = model.score(X_train, y_train) # 0.99 — looks amazing!
test_score = model.score(X_test, y_test) # 0.43 — terrible on new data
O polinômio se torceu em nós para passar por todos os pontos de treinamento – incluindo os valores discrepantes barulhentos. Ele memorizou o conjunto de treinamento em vez de aprender o padrão subjacente. Em dados invisíveis, é inútil.
Uma ferramenta fundamental para detectar overfitting é dividir seus dados em três conjuntos:
from sklearn.model_selection import train_test_split
# First split: hold out 20% as the final test set
X_train_val, X_test, y_train_val, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Second split: hold out 20% of remaining as validation set
X_train, X_val, y_train, y_val = train_test_split(
X_train_val, y_train_val, test_size=0.25, random_state=42
)
# Result: 60% train / 20% validation / 20% test
O conjunto de validação é o seu sistema de alerta precoce. Se a precisão do treinamento continuar melhorando, mas a precisão da validação estagnar ou cair, você está se ajustando demais.
A regularização adiciona uma penalidade à função de perda que desencoraja o modelo de aprender padrões excessivamente complexos.
Regularização L2 (Ridge) penaliza pesos grandes:
from sklearn.linear_model import Ridge
model = Ridge(alpha=1.0) # alpha controls regularisation strength
model.fit(X_train, y_train)
Regularização L1 (Lasso) pode levar alguns pesos até zero, realizando a seleção de recursos:
from sklearn.linear_model import Lasso
model = Lasso(alpha=0.1)
model.fit(X_train, y_train)
Durante o treinamento, "descarte" aleatoriamente (definido como zero) uma proporção de neurônios:
import torch.nn as nn
model = nn.Sequential(
nn.Linear(128, 64),
nn.ReLU(),
nn.Dropout(p=0.5), # 50% of neurons randomly deactivated during training
nn.Linear(64, 1)
)
Isso evita que os neurônios se adaptem e força a rede a aprender representações distribuídas mais robustas.
Monitore a perda de validação durante o treinamento e pare quando ela começar a aumentar:
from tensorflow.keras.callbacks import EarlyStopping
early_stop = EarlyStopping(
monitor='val_loss',
patience=5, # stop after 5 epochs without improvement
restore_best_weights=True
)
model.fit(X_train, y_train,
validation_data=(X_val, y_val),
callbacks=[early_stop],
epochs=1000)
Mais dados tornam mais difícil para o modelo memorizar o ruído – simplesmente há muito para caber com exatidão. Quando a coleta de dados é cara, o aumento de dados (criação de cópias modificadas de exemplos existentes) pode ajudar.
Às vezes, a solução certa é simplesmente escolher um modelo menos complexo para o problema.
Com conjuntos de dados pequenos, uma única divisão train/val pode ser enganosa devido à aleatoriedade. A validação cruzada K-fold fornece uma estimativa mais confiável:
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=100)
# 5-fold cross-validation
scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
print(f"Mean accuracy: {scores.mean():.3f} ± {scores.std():.3f}")
# Mean accuracy: 0.847 ± 0.023
Os dados são divididos em 5 partes; o modelo treina em 4 e valida em 1, girando a cada vez. A pontuação final é a média de todos os 5 – muito mais confiável do que uma única divisão.
Um modelo atinge 99% de precisão nos dados de treinamento, mas apenas 62% nos dados de teste. O que isso indica?