Python para Ajuste da Curva

Neste capítulo, o Python será usado para organizar dados experimentais, montar somatórios, construir sistemas normais e avaliar modelos de regressão. Como a parte inicial de Python já apresentou listas, laços, funções e NumPy, aqui o foco será representar dados, gerar potências, montar matrizes e medir a qualidade do ajuste.

Dados como vetores numéricos

Os dados de regressão costumam ser fornecidos em pares \((x,y)\). Para calcular somatórios e produtos com menos código, podemos armazenar esses valores como vetores de NumPy:

import numpy as np

x = np.array([1, 2, 3, 4], dtype=float)
y = np.array([2.1, 3.9, 6.2, 8.1], dtype=float)

Com vetores, expressões como x**2 e x*y são aplicadas elemento a elemento, aproximando o código da notação matemática usada nos somatórios.

Somatórios

Na regressão linear, aparecem somas como \(\sum x_i\), \(\sum y_i\), \(\sum x_i^2\) e \(\sum x_i y_i\). Com NumPy, esses somatórios podem ser calculados diretamente:

soma_x = np.sum(x)
soma_y = np.sum(y)
soma_x2 = np.sum(x**2)
soma_xy = np.sum(x*y)
Expressão Python
\(\sum x_i\) np.sum(x)
\(\sum y_i\) np.sum(y)
\(\sum x_i^2\) np.sum(x**2)
\(\sum x_i y_i\) np.sum(x*y)

Potências para regressão polinomial

Na regressão polinomial, precisamos calcular potências de \(x\). Com vetores de NumPy, cada potência é calculada para todos os pontos:

quadrados = x**2
cubos = x**3

print(quadrados)
print(cubos)

Montando tabelas de somas

Para um polinômio de grau maior, podemos calcular as somas necessárias para o sistema normal usando uma lista de somatórios:

grau = 3
somas_x = []

for potencia in range(2*grau + 1):
    somas_x.append(np.sum(x**potencia))

print(somas_x)

Para regressão de grau \(m\), são necessárias somas de potências até \(2m\). A lista somas_x permite preencher a matriz do sistema normal sem recalcular os mesmos valores várias vezes.

Matrizes com NumPy

Depois de calcular os somatórios, podemos montar o sistema linear da regressão usando numpy. Para o ajuste linear \(y=a_0+a_1x\), o sistema normal fica:

quantidade = len(x)

A = np.array([
    [quantidade, soma_x],
    [soma_x, soma_x2]
], dtype=float)

b = np.array([soma_y, soma_xy], dtype=float)

Os coeficientes podem ser obtidos resolvendo o sistema:

coeficientes = np.linalg.solve(A, b)
a0, a1 = coeficientes

print(a0, a1)

Avaliando o modelo ajustado

Depois de encontrar os coeficientes, é importante calcular os valores previstos e os resíduos. O resíduo mede a diferença entre o valor observado e o valor calculado pelo modelo:

y_estimado = a0 + a1*x
residuos = y - y_estimado
erro_quadratico = np.sum(residuos**2)

print(y_estimado)
print(erro_quadratico)

Atividade

Dados os vetores x = np.array([1, 2, 3], dtype=float) e y = np.array([2, 4, 5], dtype=float), calcule os somatórios da regressão linear, monte o sistema normal e obtenha os coeficientes com np.linalg.solve.