← Voltar pra playlist

Só pra complementar: Funções de Perda (MSE, MAE, Huber)

Meme "olha o que eles precisam pra imitar uma fração do nosso poder": uma GPU e um gráfico 3D de uma superfície de custo cheia de vales, ao lado de um cérebro gigante, com a legenda debaixo

Esse post não vem de nenhum lab específico do curso, é um extra que a gente ganhou de tanto martelar em cima da função de custo nos posts 2 e 3. Lá atrás a gente elevou o erro ao quadrado sem questionar muito o porquê, só que "elevar ao quadrado" é uma escolha, não a única opção. Bora abrir esse leque.

Dando nome ao que você já construiu: MSE

A função de custo que você já usa desde o post 2 tem um nome oficial: (Mean Squared Error, erro quadrático médio).

MSE=1mi=0m1(fw,b(x(i))y(i))2\text{MSE} = \frac{1}{m}\sum_{i=0}^{m-1}\left(f_{w,b}(x^{(i)}) - y^{(i)}\right)^2

Repara que é basicamente a mesma fórmula do post 2, só sem o "2" extra no denominador (aquele 2 só existia pra facilitar a derivada do gradiente descendente, lembra?). O nome muda, a essência não.

A alternativa mais direta: MAE

E se, em vez de elevar ao quadrado, a gente só pegasse o valor absoluto do erro? Essa é a (Mean Absolute Error, erro absoluto médio):

MAE=1mi=0m1fw,b(x(i))y(i)\text{MAE} = \frac{1}{m}\sum_{i=0}^{m-1}\left|f_{w,b}(x^{(i)}) - y^{(i)}\right|

A diferença parece pequena no papel, mas muda tudo no comportamento. No MSE, errar o dobro custa quatro vezes mais (lembra do post 2?). No MAE, errar o dobro custa exatamente o dobro, nem mais, nem menos. É a diferença entre um juiz que enlouquece quando você erra feio e um juiz que só conta pontos de forma proporcional, sem drama extra.

As duas formas lado a lado

Nada de imaginar a forma, olha ela:

Repara: MSE é uma parábola (cresce cada vez mais rápido), MAE é um V (cresce sempre na mesma taxa). Segura essa imagem na cabeça, ela explica tudo que vem a seguir.

O melhor dos dois mundos: Huber

MSE é sensível demais a erro grande. MAE é durão demais, até com erro pequeno (repara no V: mesmo erros minúsculos custam proporcionalmente ao tamanho deles, sem o "desconto" que o quadrado dá perto de zero). A tenta pegar o melhor dos dois: parábola suave pertinho de zero, reta a partir de um limiar δ\delta (delta).

Lδ(e)={12e2se eδδ(e12δ)se e>δL_\delta(e) = \begin{cases} \frac{1}{2}e^2 & \text{se } |e| \le \delta \\ \delta\left(|e| - \frac{1}{2}\delta\right) & \text{se } |e| > \delta \end{cases}

Onde ee é o erro de um exemplo. Arrasta o slider do delta lá em cima de novo e observa a curva laranja: com delta pequeno, Huber vira quase um MAE, e com delta grande, vira quase um MSE. Delta é literalmente o controle de "a partir de que tamanho de erro eu paro de dar desconto".

O impacto de um outlier

Aqui é onde a escolha da função de perda deixa de ser teoria e vira decisão de verdade. Pega o dataset de 6 casas do post 2 e adiciona uma casa a mais, numa posição fixa. Você controla o preço dela com o slider, arrastando de um valor razoável até um valor bem fora da curva (um ), e observa três retas ajustadas ao vivo, uma pra cada função de perda:

  • MSE: w = 207.2, b = 45.5
  • MAE: w = 217.0, b = 33.0
  • Huber: w = 209.6, b = 21.2

Arrasta até o valor máximo e observa: a reta azul (MSE) sai correndo atrás do ponto vermelho, se contorcendo pra tentar "agradar" o outlier. A reta verde (MAE) mal se mexe. A laranja (Huber) fica no meio do caminho. Isso não é coincidência nem só desse exemplo, é a consequência direta do gráfico das duas formas que você viu ali em cima: quadrado pune erro grande sem limite, valor absoluto não.

Fechando

Função de perdaFórmulaReação a outlierQuando usar
MSEerro ao quadradosensível, se deixa puxardado limpo, sem outlier relevante
MAEvalor absoluto do errorobusta, quase imunedado com outlier que você quer ignorar
Huberhíbrida (quadrado perto de zero, reta longe)meio-termo ajustávelquando você quer um pouco de cada, controlando via delta

Três ideias pra levar:

  1. A função de perda não é um detalhe técnico escondido, é uma escolha de design que muda o comportamento do modelo inteiro, principalmente na presença de dado real e sujo.
  2. Elevar ao quadrado pune erro grande desproporcionalmente, é ótimo quando você confia no seu dataset, perigoso quando não confia.
  3. Huber existe justamente pra você não ter que escolher no escuro: o delta é um botão que desliza entre os dois extremos.

Aplicação prática

Mesmo dataset real de imóveis dos posts anteriores (Housing Prices Regression, Kaggle). Dessa vez, um cenário bem realista: um erro de digitação. Uma casa de 60 pés² (bem pequena) foi cadastrada por engano custando quase 2 milhões de dólares.

# 50 casas reais + 1 erro de digitação: 60 pés², $1.9 milhão
x_com_erro = [*x_sqft, 0.6]
y_com_erro = [*y_price, 1900]

ols  = fit_mse(x_com_erro, y_com_erro)             # ajuste comum (mínimos quadrados)
mae  = fit_irls(x_com_erro, y_com_erro, "mae")     # robusto a outlier
huber = fit_irls(x_com_erro, y_com_erro, "huber", delta=50)

casa_nova = 1.5   # 150 pés², na mesma escala dos posts anteriores

for nome, (w, b) in [("MSE", ols), ("MAE", mae), ("Huber", huber)]:
    print(f"{nome}: ${(w * casa_nova + b) * 1000:,.0f}")

Saída: MSE: $608,900 / MAE: $570,700 / Huber: $569,800

Sem o erro de digitação, os três dão praticamente o mesmo palpite pra essa casa (por volta de 567a567 a 573 mil). Com o erro de digitação, o MSE pula pra quase 609mil,umsustodemaisde609 mil, um susto de mais de 35 mil só por causa de uma linha errada na planilha, enquanto MAE e Huber mal se mexem (menos de $3 mil de diferença). Testa você mesmo, arrastando o outlier:

Carregando dados reais...

Numa base de dados de verdade, com milhares de linhas, erro de digitação acontece. A escolha da função de perda decide se um erro desses vira um problema seu ou não.