Skip to content

Commit

Permalink
secção mínimos quadrados teoria
Browse files Browse the repository at this point in the history
  • Loading branch information
viniciusdutra314 committed Jan 24, 2025
1 parent 9e92ae0 commit ddfafe1
Show file tree
Hide file tree
Showing 18 changed files with 139 additions and 167 deletions.
39 changes: 0 additions & 39 deletions docs/Arrays/curva_min_max.md

This file was deleted.

4 changes: 0 additions & 4 deletions docs/Arrays/get_incertezas_nominais.md

This file was deleted.

Empty file removed docs/Arrays/linspace.md
Empty file.
Binary file removed docs/Arrays/queda_livre.png
Binary file not shown.
Binary file removed docs/Arrays/queda_livre_sigmas.png
Binary file not shown.
Binary file removed docs/Constantes/autocomplete.png
Binary file not shown.
Empty file removed docs/Constantes/codigo_exemplo.py
Empty file.
16 changes: 0 additions & 16 deletions docs/Regressões (fitting)/exponencial.md

This file was deleted.

20 changes: 0 additions & 20 deletions docs/Regressões (fitting)/lei de potência.md

This file was deleted.

45 changes: 0 additions & 45 deletions docs/Regressões (fitting)/linear.md

This file was deleted.

40 changes: 0 additions & 40 deletions docs/Regressões (fitting)/polinomial.md

This file was deleted.

Binary file removed docs/Regressões (fitting)/regressao_linear.jpg
Binary file not shown.
Binary file removed docs/Regressões (fitting)/regressao_polinomial.jpg
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Muitas constantes da natureza são usadas para cálculos físicos, Alguns exemplos são \(\pi\), \(c\) e \(G\). A biblioteca possui um submódulo chamado **constantes** que armazena esses valores segundo a [CODATA2022](https://arxiv.org/abs/2409.03787). É altamente recomendado que você utilize um editor de texto com **autocompletar** para rapidamente encontrar a constante desejada.

<img src=autocomplete.png alt='Exemplo com autocomplete' width=500>
<img src=images/autocomplete.png alt='Exemplo com autocomplete' width=500>

## Exatas
Como os nomes das constantes são geralmente verbosos, é interessante salvar a constante com uma variável de nome reduzido no seu código. O código abaixo calcula o tempo que um fóton leva para sair do Sol e chegar até a Terra, usando a velocidade da luz e o semi-eixo maior médio da órbita da Terra:
Expand Down
10 changes: 10 additions & 0 deletions docs/regressoes_menu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Eu particularmente sempre achei que o método dos mínimos quadrados era dado de maneira muito rápida na graduação,
não mostrando como que o método é uma aplicação direta de cálculo I e algebra linear, eu espero nessa secção mostrar
um pouco disso aos leitores.

Para não misturar o uso da biblioteca com a teoria por trás, estou aqui dividindo explicitamente essa
secção em duas

#[Teoria dos mínimos quadrados](regressoes_teoria.md)
#[Uso na biblioteca](#lei-de-potência)

91 changes: 91 additions & 0 deletions docs/regressoes_teoria.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Regressão Linear

Quando temos uma equação física que prevê a relação entre duas ou mais variáveis, geralmente tentamos encontrar a curva teórica prevista pela equação que mais se encaixe com os dados experimentais. Um exemplo é a lei de Hooke:

$$\vec{F}=-k\vec{x}$$

Para certos regimes de deslocamento, a força aplicada a uma mola é linear com a sua distensão. Vamos imaginar que um experimento foi realizado e chegamos a este conjunto de forças e deslocamentos.

```py
--8<-- "tests/test_doc_lei_de_hook.py:3:6"
```

Qual é a constante elástica \(k\) da mola?

Na prática, a relação não é totalmente linear entre os dados, então precisamos criar algum tipo de critério para determinar qual reta é "melhor" do que outra. Um critério muito utilizado é a minimização dos quadrados dos desvios[^1], chamemos de \(S\):

$$S=\sum (y_{real}-y_{teórico})^2 = \sum (y_{real}-ax-b)^2$$

Para encontrar esse mínimo, podemos pensar no desvio como sendo uma função da nossa curva teórica \(S(a,b)\). Existe um conjunto de coeficientes angular e linear que minimiza essa função. Nesse ponto, temos[^2]:

$$\frac{\partial S}{\partial a} = \frac{\partial S}{\partial b} = 0$$

Comecemos com a equação do coeficiente linear:

$$\frac{\partial}{\partial b} \left(\sum (y_{real}-ax-b)^2\right) = -2\sum (y_{real}-ax-b) = 0 \rightarrow a\overline{x} + b = \sum y_{real}$$

Podemos fazer um raciocínio análogo para o coeficiente angular:

$$\frac{\partial}{\partial a} \left(\sum (y_{real}-ax-b)^2\right) = -2\sum (y_{real}-ax-b)x = 0$$

Que pode ser rearranjado como:

$$a\sum x^2 + b\sum x = \sum xy_{real}$$

Perceba que temos um **sistema linear em \(a\) e \(b\)**:

$$a\sum x^2 + b\sum x = \sum xy_{real}$$
$$a\overline{x} + b = \sum y_{real}$$

Como \(x\) e \(y\) são conhecidos, podemos inverter a matriz desse sistema linear e achar \(a\) e \(b\). Esta é uma demonstração das fórmulas do livro.

# Regressão Polinomial

O método descrito acima de tomar derivadas da função e chegar a um sistema de \(N\) variáveis se estende para polinômios de grau arbitrário. **Mas como um sistema linear pode achar coeficientes de uma parábola?**

O desvio seria \(S=\sum (y-ax^2-bx-c)^2\), faríamos então:

$$\frac{\partial S}{\partial a} = \frac{\partial S}{\partial b} = \frac{\partial S}{\partial c}= 0$$


A grande sacada é perceber que as equações são lineares nos coeficientes e não em \(x\). Claramente, uma regressão de uma parábola terá termos quadráticos em \(x\), mas as equações da minimização são lineares em \(a\), \(b\) e \(c\).



No fim, você chegará a uma equação matricial que te dá os coeficientes do polinômio para qualquer grau \(N\)[^3]:

$$\text{coeficientes} = (A^T A)^{-1} A^T y$$

É interessante pensar que você, em teoria, pode fazer o método dos mínimos quadrados para um polinômio arbitrário com uma linha de Python.

Caso queiram ver mais sobre, recomendo este [artigo](https://www.researchgate.net/publication/337103890_Linear_Least_Squares_Versatile_Curve_and_Surface_Fitting_CDT-17) do Luciano da Fontoura Costa. Ele é um pesquisador do IFSC que, além dos seus artigos de pesquisa, também publica vários materiais interessantes a nível de graduação chamados de CDT (Costa’s Didactic Texts).

# Regressão Exponencial

Também podemos usar o mesmo método para o caso exponencial, aplicando um truque simples:

$$y = Ae^{kx}$$
$$\text{Tomando log dos dois lados}$$
$$\ln(y) = kx + \ln(A)$$

Que é uma equação linear se plotarmos \(x \times \ln(y)\). Talvez seja difícil ver que isso é realmente uma reta. Minha sugestão é esquecer totalmente a variável \(y\) original e pensar que existe uma nova variável chamada \(Y\) que se conecta com \(y\). Assim, \(Y = \ln(y)\). Como \(\ln(A)\) é uma constante, vamos dar um novo nome, por que não \(B = \ln(A)\)? Reescrevendo a equação:

$$Y = kx + B$$

Agora creio que seja fácil ver que é de fato linear, a menos de uma transformação de variável.

## Regressão Lei de Potência

Uma lei de potência segue o mesmo truque:

$$y = Ax^n$$
$$\text{Tomando log dos dois lados}$$
$$\ln(y) = n\ln(x) + \ln(A)$$

Se fizermos um gráfico \(\ln(y) \times \ln(x)\), teremos uma reta.

[^1]: Sim, existem outros critérios. A minimização do módulo dos desvios também é válida (e em alguns casos até melhor do que o método dos mínimos quadrados), mas os mínimos quadrados têm a vantagem de ter uma solução analítica fechada usando apenas o ferramental básico de Cálculo I e Álgebra Linear, então certamente tem um apelo maior para a graduação.

[^2]: Mas você só provou que um extremo da função ocorre em \(a\) e \(b\), não que seja um mínimo! Bem, existe um passo geralmente omitido que seria a análise de que a função \(S\) é quadrática em \(a\) e \(b\), ela é **convexa**! Um dos teoremas mais fortes e úteis de otimização de funções convexas é que o extremo local é o extremo global. Pela convexidade, se provamos que é um extremo, então ou é um mínimo ou é um máximo. Claramente não é um máximo. Informalmente, podemos pensar que é sempre possível achar uma reta pior.

[^3]: Essa fórmula jogada não significa muita coisa, mas o interessante é que os mínimos quadrados possuem uma interpretação geométrica bem legal. Se o polinômio passasse por todos os pontos, teríamos um sistema linear \(A\vec{x} = \vec{b}\), mas não temos isso. Na verdade, temos \(A\vec{x} \approx \vec{b}\). Os mínimos quadrados são equivalentes a minimizar \(||A\vec{x} - \vec{b}||^2\). Estamos minimizando a norma da distância entre os vetores, fazendo a projeção ortogonal de um no outro. Esse vetor pode ser encontrado aplicando a pseudo-inversa de Penrose (sim, o mesmo Penrose do Nobel de 2020). Ela não é exatamente uma inversa porque não estamos resolvendo o sistema exatamente, mas sim, estamos atrás do vetor que está mais "próximo" da solução.
4 changes: 2 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ site_name: LabIFSC2
nav:
- Sobre: index.md
- Introdução: introducao.md
- Constantes: Constantes/constantes da natureza.md
- Constantes: constantes da natureza.md
- Funções Matemáticas: funcoes_matematicas.md
- Arrays: arrays.md
- Regressões (Fitting): Regressões (fitting)/linear.md
- Mínimos quadrados: regressoes_menu.md
- Gráficos: graficos.md
- Formataçõs/LaTeX: formatacoes_latex.md
- Como erros são propagados?: propagacao_de_erros.md
Expand Down
35 changes: 35 additions & 0 deletions tests/test_doc_lei_de_hook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import matplotlib.pyplot as plt

from LabIFSC2 import *

forças=linspaceM(0,10,10,'N',0.1) #variando a força
deslocamentos=arrayM([0,0.5,1.1,1.6,2,2.3,2.8,3.2,3.7,4],'cm',0.01) #medindo deslocamentos

linha=regressao_linear(deslocamentos,forças)
print(linha)
#MPolinomio(coefs=[(2,51 ± 0,06) N/cm, (-3 ± 2)x10⁻¹ N],grau=1)
print(f"Constante da mola {linha.a:si}")
#Constante da mola (2,51 ± 0,06)x10² kg/s²

unidade_x='cm'
unidade_y='N'

plt.style.use('ggplot')

plt.scatter(nominais(deslocamentos,unidade_x),
nominais(forças,unidade_y),
label='Dados',
color='red')

x=linspaceM(0,4,100,unidade_x,0)

plt.plot(nominais(x,unidade_x),
linha.amostrar(x,unidade_y),
label='Regressão linear',
color='blue')

plt.xlabel(f'Deslocamento ({unidade_x})')
plt.ylabel(f'Força ({unidade_y})')

plt.legend()
plt.savefig('teste.jpg',dpi=300)

0 comments on commit ddfafe1

Please sign in to comment.