LABORATÓRIO 07 · REGRESSÃO LINEAR MÚLTIPLA

De duas características a um valor previsto.

Vamos estimar o consumo de combustível de um carro usando duas entradas: potência do motor e peso do veículo.

duas entradas ŷ = b + w₁x₁ + w₂x₂ uma saída contínua

O PROBLEMA

O que entra e o que queremos descobrir?

x₁

Potência do motor

Medida em cavalos-vapor (cv). Motores mais potentes podem exigir mais combustível.

exemplo: 180 cv
x₂

Peso do veículo

Medido em quilogramas (kg). Um carro mais pesado exige mais energia para se movimentar.

exemplo: 1.500 kg
y

Consumo de combustível

É a resposta esperada, medida em litros consumidos a cada 100 quilômetros.

exemplo: 8,7 L/100 km

Por que não usamos apenas potência e consumo? Nesse caso teríamos uma entrada e uma saída. Para estudar uma rede com duas entradas, acrescentamos o peso do veículo como segunda característica e mantemos o consumo como única saída.

Σu = b + w₁x₁ + w₂x₂
g(u)g(u) = u
ŷsaída contínua

Onde está a função de ativação? A regressão usa a função linear, também chamada identidade. Ela não transforma o potencial: ŷ = g(u) = u. Por isso a saída pode assumir valores como 7,35 ou 9,82, em vez de apenas 0 ou 1.

ANTES DE TREINAR

Colocando cv e kg na mesma escala

Potência e peso usam unidades muito diferentes. Padronizamos cada entrada para que nenhuma domine o gradiente apenas porque seus números são maiores.

x₁′ = (x₁ − média da potência) ÷ desvio da potência x₂′ = (x₂ − média do peso) ÷ desvio do peso

EXPERIMENTO

Treine o plano de regressão

O modelo inicia com uma superfície horizontal e ajusta três parâmetros: w₁, w₂ e bias.

ÉPOCAS0
ERRO QUADRÁTICO MÉDIO
RAIZ DO ERRO · RMSE
COEFICIENTE R²

Duas entradas formam um plano

Os pontos são carros do dataset. As linhas verticais representam os resíduos entre consumo real e previsto.

Modelo novo
consumo realplano previstoresíduo

MODELO ATUAL

A equação que a regressão aprendeu

Durante o treinamento usamos as entradas padronizadas. Abaixo, a mesma equação é convertida novamente para cv e kg:

Erro × épocas

O eixo x mostra o treinamento; o eixo y mostra E = ½ × média(e²).

CONTAS DO TREINAMENTO

Uma época, passo a passo

O gradiente usa a soma dos erros de todos os carros. Depois divide pelo número de amostras e atualiza os três parâmetros ao mesmo tempo.

O que é a descida do gradiente? As derivadas dizem para qual lado o erro aumenta. Por isso, a atualização usa o sinal de menos: caminhamos na direção contrária para reduzir o erro.

USANDO O MODELO

Quanto consumiria um carro novo?

Aplicamos a equação atual a um veículo que não aparece no dataset: 200 cv e 1.500 kg.

DATASET E RESULTADOS

O erro de cada carro

e = y − ŷ mantém a direção do erro. Já ½e² elimina o sinal, penaliza erros grandes e participa da função de custo.

CÓDIGO DIDÁTICO

Regressão linear múltipla em JavaScript

O exemplo usa arrays, matrizes e laços simples. Cada função representa uma fase matemática do treinamento.

prever()calcularCusto()calcularGradientes()atualizarParametros()treinarEpoca()
regressao-linear.jsduas entradas e uma saída
// Cada linha contém [potência padronizada, peso padronizado, consumo real].
var dados = [
  [-1.54, -1.35, 5.9],
  [-1.23,  0.13, 7.0],
  [-0.92, -1.05, 6.6]
  // ...demais carros
];

var w1 = 0;
var w2 = 0;
var bias = 0;
var taxa = 0.08;

// Forward: combina as duas entradas e devolve um número contínuo.
function prever(x1, x2) {
  return bias + w1 * x1 + w2 * x2;
}

// Custo: calcula E = 1/(2N) × somatório dos erros ao quadrado.
function calcularCusto() {
  var soma = 0;

  for (var i = 0; i < dados.length; i++) {
    var previsao = prever(dados[i][0], dados[i][1]);
    var erro = previsao - dados[i][2];
    soma = soma + erro * erro;
  }

  return soma / (2 * dados.length);
}

// Calcula as três derivadas usando todas as amostras.
function calcularGradientes() {
  var somaW1 = 0;
  var somaW2 = 0;
  var somaBias = 0;

  for (var i = 0; i < dados.length; i++) {
    var x1 = dados[i][0];
    var x2 = dados[i][1];
    var y = dados[i][2];
    var erro = prever(x1, x2) - y;

    somaW1 = somaW1 + erro * x1;
    somaW2 = somaW2 + erro * x2;
    somaBias = somaBias + erro;
  }

  return [
    somaW1 / dados.length,
    somaW2 / dados.length,
    somaBias / dados.length
  ];
}

// Descida do gradiente: parâmetro novo = atual − taxa × derivada.
function atualizarParametros(gradientes) {
  w1 = w1 - taxa * gradientes[0];
  w2 = w2 - taxa * gradientes[1];
  bias = bias - taxa * gradientes[2];
}

// Uma época percorre o dataset uma vez e faz uma atualização em lote.
function treinarEpoca() {
  var gradientes = calcularGradientes();
  atualizarParametros(gradientes);
}

for (var epoca = 0; epoca < 100; epoca++) {
  treinarEpoca();
}

console.log('Custo final:', calcularCusto());