sábado, 12 de julho de 2008

Regressão linear

Em meu trabalho ora me envolvo em projetos de frontend – aplicações web –, ora me envolvo em projetos de backend. Ora trabalho em projetos de uma frente a outra.

No entanto sou fascinado por problemas conceituais e soluções matemáticas, portanto gosto muito mais de backend do que de frontend.

Em problemas conceituais, uma coisa magnífica é poder prever estados de um sistema por meio de regressão.

Há alguns tipos de regressão: regressão linear, regressão por potência, regressão logarítmica e regressão exponencial, mas todas podem ser reduzidas à regressão linear.

A função da regressão linear é simples:
ŷ=α + βx

Ou seja, a ordenada estimada é igual à intercepção (α) mais a inclinação (β) vezes a abscissa. O problema real é calcular α e β.

Há muitas e muitas formas de calcular esses, umas mais simples, outras mais interessantes. =)

Uma forma legal é usando o produto de uma matriz quadrada pelo vetor de coeficientes.
--

Assim sendo, o primeiro procedimento deve ser montar as matrizes. Hoje vamos trabalhar com Python.
from __future__ import division
__metaclass__ = type

class LinearRegression:
def __init__(self, pointset):
# pointset deve ser uma lista de pares x, y
self.__set = pointset

self.__createMatrices()
self.__calculateAlpha()
self.__calculateBeta()

def __createMatrices(self):
s = self.__set

m11 = len(s)
m21 = sum([e[0] for e in s])
m12 = m21
m22 = sum([e[0] ** 2 for e in s])

self.__m = [m11, m21, m12, m22]

self.__rvector = [
sum([e[1] for e in s]),
sum ([e[0] * e[1] for e in s])
]


Agora é preciso resolver o produto de matriz por vetor. Podemos traduzir isso por meio de determinantes:
--

Daí:
    def __calculateAlpha(self):
r = self.__rvector
m = self.__m

num = r[0] * m[3] - r[1] * m[2]
den = m[0] * m[3] - m[1] * m[2]

self.__alpha = num / den


Também é possível calcular β através de determinantes:
--

Daí:
    def __calculateBeta(self):
r = self.__rvector
m = self.__m

num = m[0] * r[1] - m[1] * r[0]
den = m[0] * m[3] - m[1] * m[2]

self.__beta = num / den


Falta somente agora o método para prever um estado estrapolado:
    def predict(self, x):
return self.__alpha + (self.__beta * x)


Esta mesma lógica pode ser implementada em outras linguagens. Há ainda outros algoritmos mais simples para calcular regressão linear, mas o apresentado é o mais didático.

[]'s
Cacilhas, La Batalema