Pular para o conteúdo
</>RoByte

Buscar cursos e aulas

Aulas do curso

Vídeo em breve

Por enquanto, esta aula está disponível só em texto — o vídeo entra assim que ficar pronto.

Modelos clássicos

Regressão linear

Seu primeiro modelo de verdade: prever um número com scikit-learn, separando treino e teste do jeito certo. · 18 min

A regressão linear é o ponto de partida clássico: dado um conjunto de pontos, encontrar a reta que melhor passa por eles. Com uma feature, o modelo é a equação que você já conhece, y = a * x + b, em que a é a inclinação (coeficiente) e b é onde a reta cruza o eixo y (intercepto).

O algoritmo escolhe a e b de forma a minimizar o erro quadrático: a soma dos quadrados das distâncias entre cada ponto real e a reta.

Um problema: prever preço pela área

Para não depender de baixar arquivos, vamos gerar dados sintéticos de imóveis, em que o preço depende da área mais um pouco de ruído:

import numpy as np
from sklearn.linear_model import LinearRegression

rng = np.random.default_rng(42)
area = rng.uniform(30, 200, size=100)                        # em m²
preco = 3000 * area + 50000 + rng.normal(0, 20000, size=100)  # com ruído

X = area.reshape(-1, 1)   # features: matriz 2D (100 amostras, 1 feature)
y = preco                 # target: vetor 1D

Atenção

Repare no reshape(-1, 1). O scikit-learn exige que X seja 2D, mesmo com uma única feature. Sem isso você recebe o erro “Expected 2D array”.

Treinando e usando o modelo

Todo modelo do scikit-learn segue o mesmo trio de passos: criar, fit (treinar) e predict (prever).

modelo = LinearRegression()
modelo.fit(X, y)

print(modelo.coef_)        # perto de 3000
print(modelo.intercept_)   # perto de 50000
print(modelo.predict([[100]]))   # preço estimado para 100 m²

O modelo “descobriu” a relação escondida nos dados: os valores aprendidos ficam próximos dos 3000 e 50000 que usamos para gerar os dados. O ruído impede que sejam exatos, como acontece com dados reais.

Separando treino e teste

Já falamos que avaliar no mesmo dado do treino não é honesto. O correto:

from sklearn.model_selection import train_test_split

X_treino, X_teste, y_treino, y_teste = train_test_split(
    X, y, test_size=0.2, random_state=42
)

modelo = LinearRegression()
modelo.fit(X_treino, y_treino)

print(modelo.score(X_teste, y_teste))   # R² no conjunto de teste
  • test_size=0.2 guarda 20% dos dados só para o teste.
  • random_state=42 fixa o sorteio, para que o resultado seja o mesmo toda vez que você rodar. O número em si não importa.
  • score na regressão devolve o R²: quanto mais perto de 1, melhor o modelo explica os dados (1.0 é perfeito e 0 é tão ruim quanto sempre prever a média).

Visualizando a reta

import matplotlib.pyplot as plt

plt.scatter(X_teste, y_teste, label="Dados reais")
plt.plot(X_teste, modelo.predict(X_teste), color="red", label="Modelo")
plt.xlabel("Área (m²)")
plt.ylabel("Preço (R$)")
plt.legend()
plt.show()

Dica

Com mais de uma feature (área, quartos, idade do imóvel), o código é o mesmo: X passa a ter várias colunas e o modelo aprende um coeficiente por coluna. A “reta” vira um plano ou hiperplano, mas o fit e o predict não mudam.

Exercícios

Exercício

1. Aquecimento. Altere os números usados para gerar os dados (por exemplo, 3000 para 5000 e o intercepto para 10000) e confira se coef_ e intercept_ acompanham a mudança.

Exercício

2. Prevendo. Use o modelo treinado para prever o preço de imóveis de 50, 100 e 150 m² de uma vez só (predict aceita várias linhas). Os resultados fazem sentido em relação à equação original?

Exercício

3. Desafio. Adicione uma segunda feature, quartos, gerada com rng.integers(1, 5, size=100), e faça o preço depender também dela (por exemplo, somando 20000 * quartos). Monte X com as duas colunas usando np.column_stack, treine de novo e compare o R² com o do modelo de uma só feature.