Implementando Regressão Linear com Python e PyTorch

Este artigo aborda a implementação de um modelo de regressão linear utilziando Python e a biblioteca PyTorch. Cobriremos desde os conceitos teóricos até a aplicação prática.

Fundamentos da Regressão Linear

A regressão linear é uma técnica estatística utilizada para modelar a relação entre uma variável dependente e uma ou mais variáveis independentes. O objetivo é encontrar a linha (ou hiperplano, em casos de múltiplas variáveis) que melhor se ajusta aos dados, permitindo fazer previsões.

Modelo Matemático

A forma mais simples de regressão linear é definida pela equação:

y = w * x + b

Onde:

  • y é a variável dependente (o que queremos prever).
  • x é a variável independente (a entrada).
  • w é o peso (ou coeficiente angular).
  • b é o viés (ou intercepto).

Em casos de múltiplas variáveis independentes (regresssão linear múltipla), a equação se generaliza para:

y = w1*x1 + w2*x2 + ... + wn*xn + b

Introdução ao PyTorch

PyTorch é uma poderosa biblioteca de aprendizado de máquina de código aberto, desenvolvida pela equipe de pesquisa em IA do Facebook. Ela se destaca pela sua flexibilidade, com grafos computacionais dinâmicos e a capacidade de executar operações em GPUs, acelerando significativamente o treinamento de modelos complexos.

Configuração do Ambiente

Para começar, certifique-se de ter o Python instalado. Em seguida, instale as bibliotecas necessárias:

pip install torch torchvision torchaudio numpy pandas matplotlib

A instalação específica do PyTorch pode variar dependendo se você pretende usar CPU ou GPU. Consulte o site oficial do PyTorch para obter instruções detalhadas de instalação para o seu sistema.

Preparação dos Dados

Vamos simular um conjunto de dados para prever o preço de casas com base na sua área. Primeiro, definimos e normalizamos os dados para melhorar a convergência do treinamento.

import numpy as np
import torch

# Dados simulados: área (m²) e preço (em milhares de R$)
areas_m2 = np.array([50, 60, 70, 80, 90, 100, 110, 120, 130, 140], dtype=np.float32)
precos_milhares = np.array([300, 360, 420, 480, 540, 600, 660, 720, 780, 840], dtype=np.float32)

# Normalização dos dados (Z-score)
mean_area = np.mean(areas_m2)
std_area = np.std(areas_m2)
areas_normalizadas = (areas_m2 - mean_area) / std_area

mean_preco = np.mean(precos_milhares)
std_preco = np.std(precos_milhares)
precos_normalizados = (precos_milhares - mean_preco) / std_preco

# Conversão para tensores PyTorch
entradas = torch.from_numpy(areas_normalizadas).view(-1, 1)
alvos = torch.from_numpy(precos_normalizados).view(-1, 1)

A normalização ajuda o algoritmo de otimização (como o gradiente descendente) a convergir mais rapidamente.

Implementação do Modelo com PyTorch

Definiremos um modelo de regressão linear simples usando a classe nn.Module do PyTorch.

Definição da Classe do Modelo

import torch.nn as nn

class ModeloRegressaoLinear(nn.Module):
   def __init__(self):
       super(ModeloRegressaoLinear, self).__init__()
       # Camada linear com 1 entrada e 1 saída
       self.camada_linear = nn.Linear(in_features=1, out_features=1)

   def forward(self, x):
       # A passagem forward simplesmente aplica a camada linear
       saida = self.camada_linear(x)
       return saida

Instanciação e Configuração

Criamos uma instância do modelo, definimos a função de perda (Mean Squared Error - MSE) e o otimizador (Stochastic Gradient Descent - SGD).

# Instancia o modelo
modelo = ModeloRegressaoLinear()

# Define a função de perda (Mean Squared Error)
funcao_perda = nn.MSELoss()

# Define o otimizador (SGD) com taxa de aprendizado (learning rate) de 0.01
taxa_aprendizado = 0.01
otimizador = torch.optim.SGD(modelo.parameters(), lr=taxa_aprendizado)

Treinamento do Modelo

O treinamento envolve iterar sobre os dados, calcular a perda, e ajustar os pesos do modelo para minimizá-la.

num_epocas = 100 # Número de iterações sobre o dataset

for epoca in range(num_epocas):
   # Passo 1: Forward pass (predição)
   previsoes = modelo(entradas)
   perda = funcao_perda(previsoes, alvos)

   # Passo 2: Backward pass e otimização
   otimizador.zero_grad() # Limpa os gradientes acumulados
   perda.backward()      # Calcula os gradientes da perda em relação aos parâmetros
   otimizador.step()     # Atualiza os parâmetros do modelo

   # Imprime a perda a cada 10 épocas
   if (epoca + 1) % 10 == 0:
       print(f'Época [{epoca+1}/{num_epocas}], Perda: {perda.item():.4f}')

Avaliação e Previsão

Após o treinamento, podemos avaliar o modelo e usá-lo para fazer novas previsões.

Avaliação

Colocamos o modelo em modo de avaliação e calculamos a perda final.

modelo.eval() # Modo de avaliação (desativa dropout, batch normalization, etc.)
with torch.no_grad(): # Desabilita o cálculo de gradientes
   previsoes_finais = modelo(entradas)
   perda_final = funcao_perda(previsoes_finais, alvos)
   print(f'\nPerda final no conjunto de treinamento: {perda_final.item():.4f}')

   # Exibe os pesos e bias aprendidos
   for nome, param in modelo.named_parameters():
       if param.requires_grad:
           print(f'{nome}: {param.data.numpy()}')

Previsão

Para prever o preço de uma nova área, é crucial aplicar a mesma normalização utilizada nos dados de treinamento.

# Prever o preço para uma casa de 100 m²
area_exemplo_m2 = torch.tensor([100.0])

# Aplica a mesma normalização usada no treinamento
area_normalizada_exemplo = (area_exemplo_m2 - mean_area) / std_area
area_tensor_exemplo = area_normalizada_exemplo.view(-1, 1)

# Realiza a previsão
modelo.eval()
with torch.no_grad():
   preco_previsto_normalizado = modelo(area_tensor_exemplo)
   # Desnormaliza o resultado para obter o preço no valor original
   preco_previsto_original = (preco_previsto_normalizado * std_preco) + mean_preco

print(f'Preço previsto para uma casa de 100 m²: {preco_previsto_original.item():.2f} mil R$')

Este exemplo demonstra um ciclo completo de implementação de um modelo de regressão linear, desde a preparação dos dados até a previsão com o modelo treinado.

Tags: Python Pytorch regressão linear machine learning deep learning

Publicado em 7-1 19:26