Lista 14 · Regressão linear¶
Acompanha o capítulo 14. A reta que erra menos, pelas equações normais; o \(R^2\); e o que os resíduos contam.
Como esta lista funciona
Abra o caderno no Colab, escreva a sua solução no lugar do # TODO e rode a
célula de teste logo abaixo. Ela mesma diz o que passou e o que falhou — você
não precisa esperar correção de ninguém.
O código de cada exercício também está aqui embaixo, caso você prefira colar num editor local. Os testes comparam números com tolerância.
Exercícios marcados com ✏️ são à mão, no papel, com 4 casas decimais — como na parte em papel das avaliações.
Exercício 01¶
✏️ À mão. Ajuste uma reta aos pontos \((1, 2)\), \((2, 3)\), \((3, 5)\), \((4, 6)\).
a) Calcule \(n\), \(\sum x_i\), \(\sum x_i^2\), \(\sum y_i\) e \(\sum x_i y_i\).
b) Monte e resolva as equações normais.
c) Calcule os resíduos e o \(R^2\).
Exercício 02¶
Escreva reta_minimos_quadrados(x, y), que monta as equações normais, resolve com
np.linalg.solve e devolve a tupla (a0, a1). Converta x e y com np.array
(eles podem chegar como listas).
import numpy as np
def reta_minimos_quadrados(x, y):
"""(a0, a1) da reta y = a0 + a1 x, pelas equações normais."""
x = np.array(x)
y = np.array(y)
# TODO: a matriz 2 x 2 das somas, o lado direito, np.linalg.solve
pass
# --- testes (não altere) ---
r = reta_minimos_quadrados([1, 2, 3, 4], [2, 3, 5, 6])
assert r is not None, "faltou o return?"
assert abs(r[0] - 0.5) < 1e-12 and abs(r[1] - 1.4) < 1e-12, f"veio {r}"
r = reta_minimos_quadrados([0, 1, 2], [5, 7, 9])
assert abs(r[0] - 5) < 1e-12 and abs(r[1] - 2) < 1e-12, "pontos em cima de uma reta: ela mesma"
print("Exercício 02: todos os testes passaram!")
Exercício 03¶
Escreva r_quadrado(x, y, a0, a1):
import numpy as np
def r_quadrado(x, y, a0, a1):
"""Coeficiente de determinação da reta a0 + a1 x nos dados."""
x = np.array(x)
y = np.array(y)
# TODO: os resíduos, as duas somas de quadrados (use np.mean) e a fórmula
pass
# --- testes (não altere) ---
assert abs(r_quadrado([1, 2, 3, 4], [2, 3, 5, 6], 0.5, 1.4) - 0.98) < 1e-12
assert abs(r_quadrado([0, 1, 2], [5, 7, 9], 5, 2) - 1) < 1e-12, "reta perfeita"
assert abs(r_quadrado([0, 1, 2], [1, 3, 2], 2, 0)) < 1e-12, "a reta da média explica zero"
print("Exercício 03: todos os testes passaram!")
Exercício 04¶
Instrumentação — calibrar um sensor. O conversor analógico-digital de um sensor de temperatura dá números de 0 a 4095. Para calibrá-lo, ele foi comparado com um termômetro de referência:
| leitura | 512 | 1024 | 1536 | 2048 | 2560 | 3072 |
|---|---|---|---|---|---|---|
| referência (°C) | 4,8 | 15,1 | 25,3 | 34,6 | 45,2 | 55,0 |
Escreva leitura_para_temperatura(leitura), que ajusta a reta de calibração com a
reta_minimos_quadrados (já escrita) e converte uma leitura em °C.
import numpy as np
def reta_minimos_quadrados(x, y):
"""JÁ ESCRITA."""
x = np.array(x)
y = np.array(y)
n = len(x)
A = np.array([[n, np.sum(x)], [np.sum(x), np.sum(x**2)]])
b = np.array([np.sum(y), np.sum(x * y)])
a = np.linalg.solve(A, b)
return (a[0], a[1])
def leitura_para_temperatura(leitura):
"""Temperatura (°C) de uma leitura do conversor, pela reta de calibração."""
leituras = [512, 1024, 1536, 2048, 2560, 3072]
referencia = [4.8, 15.1, 25.3, 34.6, 45.2, 55.0]
# TODO: ajuste a reta e aplique-a à leitura
pass
# --- testes (não altere) ---
assert abs(leitura_para_temperatura(1800) - 30.156517857142855) < 1e-9
assert abs(leitura_para_temperatura(0) - -5.059999999999984) < 1e-9, "o intercepto"
print("Exercício 04: todos os testes passaram!")
Exercício 05¶
Estatística — a correlação. O coeficiente de Pearson mede o quanto dois dados andam juntos em linha reta: \(+1\) (sobem juntos, exatamente), \(-1\) (um sobe, o outro desce) e \(0\) (nada a ver):
Escreva correlacao(x, y). Para uma reta de mínimos quadrados, \(r^2 = R^2\): confira
com os pontos do ex01.
import numpy as np
def correlacao(x, y):
"""Coeficiente de correlação de Pearson entre x e y (de -1 a 1)."""
x = np.array(x)
y = np.array(y)
# TODO: os desvios em relação à média e a fórmula
pass
# --- testes (não altere) ---
assert abs(correlacao([1, 2, 3, 4], [2, 3, 5, 6])**2 - 0.98) < 1e-12, "r² = R²"
assert abs(correlacao([1, 2, 3], [6, 4, 2]) - (-1)) < 1e-12, "uma desce quando a outra sobe"
assert abs(correlacao([1, 2, 3, 4], [1, -1, -1, 1])) < 1e-12, "sem relação linear"
print("Exercício 05: todos os testes passaram!")
Exercício 06¶
Educação — prever sem extrapolar. Numa turma, as horas de estudo semanais e as
notas foram: horas [2, 4, 5, 6, 8, 9, 10, 12]; notas [4.1, 5.0, 5.6, 6.3, 7.0, 7.9, 8.2, 9.1]. Escreva previsao_nota(horas), que ajusta a
reta (a reta_minimos_quadrados já está escrita) e devolve a nota prevista — mas
devolve None se horas estiver fora da faixa observada (de 2 a 12
horas).
import numpy as np
def reta_minimos_quadrados(x, y):
"""JÁ ESCRITA."""
x = np.array(x)
y = np.array(y)
n = len(x)
A = np.array([[n, np.sum(x)], [np.sum(x), np.sum(x**2)]])
b = np.array([np.sum(y), np.sum(x * y)])
a = np.linalg.solve(A, b)
return (a[0], a[1])
def previsao_nota(horas):
"""Nota prevista pela reta; None fora da faixa das horas observadas."""
horas_estudo = [2, 4, 5, 6, 8, 9, 10, 12]
notas = [4.1, 5.0, 5.6, 6.3, 7.0, 7.9, 8.2, 9.1]
# TODO: se horas estiver fora da faixa, return None; senão, a reta
pass
# --- testes (não altere) ---
assert abs(previsao_nota(7) - 6.65) < 1e-9
assert previsao_nota(40) is None, "fora da faixa: não extrapole"
assert previsao_nota(1) is None
print("Exercício 06: todos os testes passaram!")