Quando um modelo erra, ele erra por quê — e o que fazer em cada caso
Cada conjunto de treino ajusta um polinômio e prevê em \(x = 0{,}25\), onde a verdade vale 1. Viés \(= \overline{\hat f} - f(0{,}25)\); variância \(= \tfrac{1}{k}\sum_i (\hat f_i - \overline{\hat f})^2\). Preveja. Qual grau acerta em média, e qual se espalha mais?
Verdade: \(\sin(2\pi x)\). Cada curva é um polinômio ajustado num conjunto de treino diferente de 30 pontos.
Num \(x\) fixo: a verdade \(f(x)\); uma observação nova \(y = f(x) + \varepsilon\), ruído \(\varepsilon\) de média 0 e variância \(\sigma^2\); a previsão \(\hat f(x)\), aleatória porque depende do conjunto de treino; \(\mathbb{E}\): a média sobre conjuntos de treino e ruído.
\[ \mathbb{E}\big[(y - \hat f(x))^2\big] = \underbrace{\big(f(x) - \mathbb{E}[\hat f(x)]\big)^2}_{\text{viés}^2} + \underbrace{\mathbb{E}\big[(\hat f(x) - \mathbb{E}[\hat f(x)])^2\big]}_{\text{variância}} + \underbrace{\sigma^2}_{\text{ruído}} \]Viés: a melhor tentativa da família erra em média (uma reta não acompanha um seno). Variância: o preço de dar ouvidos à amostra. Ruído: a parte de \(y\) que não depende de \(x\); aqui \(\sigma^2 = 0{,}3^2 = 0{,}09\) e ninguém fica abaixo disso.
Preveja. 500 conjuntos de treino de 30 pontos por grau. Em que grau o erro quadrático médio (MSE, do inglês mean squared error) de teste é o menor? E o que acontece com a variância no grau 12?
| grau | viés² | variância | ruído | soma | MSE de teste medido |
|---|---|---|---|---|---|
| 0 | 0,495 | 0,020 | 0,09 | 0,605 | 0,603 |
| 1 | 0,204 | 0,022 | 0,09 | 0,316 | 0,314 |
| 3 | 0,005 | 0,018 | 0,09 | 0,113 | 0,112 |
| 5 | 0,000 | 0,045 | 0,09 | 0,135 | 0,135 |
| 7 | 0,001 | 0,635 | 0,09 | 0,726 | 0,723 |
| 12 | 0,001 | 38,897 | 0,09 | 38,987 | 38,985 |
Preveja. Deslize o grau de 0 (puro viés) a 12 (pura variância). Qual erro só cai e qual volta a subir?
Preveja. Cada vez mais pontos de treino: o erro do grau 1 continua caindo? E o do grau 9?
O que separa cada uma é o que se varia e o que fica fixo.
| o que se varia | o que fica fixo | precisa da verdade? | |
|---|---|---|---|
| decomposição viés–variância | o conjunto de treino (500 amostras) | o modelo | sim |
| curva de validação | a complexidade | os dados | não |
| curva de aprendizado | o número de linhas de treino | o modelo | não |
| busca em grade | combinações de hiperparâmetros | os dados e o cv | não |
Um botão é o hiperparâmetro que leva o modelo pelo eixo de complexidade do U: para a esquerda, mais viés (subajuste); para a direita, mais variância (sobreajuste). Viés alto pede girar para a direita; variância alta, para a esquerda. Preveja. Para deixar cada modelo mais complexo, para que lado você gira cada botão?
| família | botão | mais complexo (→ variância) | mais simples (→ viés) |
|---|---|---|---|
| polinômio | degree (grau) | maior | menor |
| Ridge, Lasso | alpha (força da penalidade) | menor | maior |
| regressão logística | C (inverso da penalidade) | maior | menor |
| k-NN | n_neighbors (\(k\), vizinhos que votam) | menor | maior |
| árvore | max_depth (profundidade) | maior | menor |
| árvore | min_samples_leaf (linhas mínimas por folha) | menor | maior |
alpha, n_neighbors e min_samples_leaf, maior é mais simples: mais penalidade, mais vizinhos na média, folhas maiores.GridSearchCV: a curva de validação que escolhe sozinha
from sklearn.model_selection import GridSearchCV, RepeatedKFold
# 1. o modelo, com o botão ainda solto
modelo = make_pipeline(PolynomialFeatures(), StandardScaler(),
LinearRegression())
# 2. os valores do botão a experimentar
# (nome do passo + __ + hiperparâmetro)
grade = {"polynomialfeatures__degree": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
# 3. como medir cada valor: 5 folds × 20 repetições (o cv do slide 10)
cv = RepeatedKFold(n_splits=5, n_repeats=20, random_state=0)
busca = GridSearchCV(modelo, grade, cv=cv,
scoring="neg_mean_squared_error")
# 4. mede os 10 graus, escolhe o menor erro
# e reajusta o vencedor nas 30 linhas
busca.fit(X, y)
busca.best_params_ # {'polynomialfeatures__degree': 3}
O que a busca mediu (busca.cv_results_):
| grau | MSE de validação |
|---|---|
| 1 | 0,319 |
| 2 | 0,386 |
| 3 | 0,114 |
| 4 | 0,311 |
| 5 | 0,198 |
| 6 | 0,255 |
| 7 | 0,579 |
| 8 | 0,424 |
| 9 | 1,748 |
| 10 | 1,222 |
busca.predict passa a usar o grau 3. O MSE entra negativo (neg_mean_squared_error) porque o scikit-learn sempre maximiza.Nas curvas de erro de treino e de validação (aqui, baixo é bom):
| o que você vê | diagnóstico | ação |
|---|---|---|
| treino ≈ validação, ambos altos, curvas planas | viés | ajustar o modelo (mais capacidade) |
| treino baixo, validação alta, distância fechando | variância | mais dados |
| treino baixo, validação alta, distância parada | variância | regularizar ou simplificar |
| treino alto e distância grande | os dois | primeiro capacidade, depois rever |
| ambos baixos, juntos | ok | pare (talvez seja o piso de ruído) |
"Alto" é relativo: sem conhecer o \(\sigma^2\) (a variância do ruído), compare com um baseline (prever a média, um modelo simples) ou com o erro aceitável para o negócio.
Ritmo: passos 1 a 3 e a primeira simulação em 15 min; passos 4 a 6 e a segunda em 25 min.