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.