Regresión no Lineal en Python

La regresión no lineal es un ajuste estadístico hecho haciendo una optimización para distintas curvas tales como la función exponencial, la función logarítmica, la función polinomial, las funciones trigonométrica, etc. Algunas de estas regresiones tienen la particularidad de que pueden linealizarse tales como la regresión exponencial y la regresión logarítmica. Por consiguiente se puede usar la regresión lineal respectivamente. No obstante hay algunas regresiones que no pueden linealizarse tales como la regresión polinómica. En el siguiente articulo trataremos algunas regresiones no lineales.

Regresión no Lineal de un Conjunto de Puntos (X, Y)


Regresión Exponencial 


La regresión exponencial es una regresión no lineal no obstante esta regresión puede linealizarse. Comúnmente esta regresión es usada para los modelos de crecimiento y decrecimiento respectivamente.

$${\large \begin{align*} Y &= ae^{bX} \\ \ln{Y} &= \ln{ae^{bX}} \\ \ln{Y} &= \ln{a} + bX \\ \ln{Y} &= bX + \ln{a} \end{align*}}$$

Por consiguiente se puede hacer uso de los mínimos cuadrados para calcular los valores correspondientes a y b respectivamente.

$${\large \begin{align*} b &= \frac{\sum X \sum \ln{Y} - N\sum (X \cdot \ln{Y})}{(\sum X )^2 - N\sum X^2} \\ \\ \ln{a} &= \frac{\sum X \sum (X \cdot \ln{Y}) - \sum \ln{Y} \sum X^2}{(\sum X )^2 - N\sum X^2} \end{align*} }$$ 

Ahora trataremos la regresión exponencial por medio de la siguiente data que se muestra a continuación:

 N de Datos  Datos $X$  Datos $Y$  Datos $X^2$  Datos $X \cdot \ln{Y}$ 
Dato 104.7500
Dato 2112.612.53
Dato 3324.499.58
Dato 4454.01615.96
Dato 5678.853626.21
Dato 67103.54932.48
Dato 78163.16440.75
Dato 892238148.66
Dato 910322.510057.76
Dato 1011543.412169.28
$\sum$591530.1477303.21


Código Fuente de la Regresión Exponencial

import numpy as np
import matplotlib.pyplot as plt

fig=plt.figure(figsize=(12,6))

X = np.array([0, 1, 3, 4, 6, 7, 8, 9, 10, 11])
Y = np.array([4.75, 12.6, 24.4, 54.0,  78.85, 103.5, 163.1, 223, 322.5, 543.4])

N = len(X)
prom_X= np.mean(X)
prom_Y= np.mean(np.log(Y))
sum_X = np.sum(X)
pot_X = np.sum(X*X)
sum_Y = np.sum(np.log(Y))
prod_XY = np.sum(X*np.log(Y))
VarX = np.sqrt(np.sum( (X - prom_X)**2 ))
VarY = np.sqrt(np.sum( (np.log(Y) - prom_Y)**2 ))
Cov_X_Y = np.sum( (X-prom_X)*(np.log(Y)-prom_Y) )

b = (sum_X*sum_Y - N*prod_XY)/((sum_X)**2 - N*pot_X)
lg = (sum_X*prod_XY - pot_X*sum_Y)/((sum_X)**2 - N*pot_X)
a = np.exp(lg)

Z = a*np.exp(X*b)  

print("La magnitud es igual a {}".format(a))
print("La tasa de crecimiento es igual a {}".format(b))
plt.title("Regresión Exponencial", fontsize=20)
plt.xlabel("Eje X", fontsize=20)
plt.ylabel("Eje Y", fontsize=20)
plt.plot(X,Y, 'ro', markersize=10)
plt.plot(X,Z, color='k', lw=2, label="$Y = {:.3f} \cdot exp({:.3f} \cdot X) $".format(a,b))
plt.legend(loc='best', fontsize=15)

plt.show()

Regresión Exponencial para la Data



Regresión Logarítmica

La regresión logarítmica también es una regresión no lineal no obstante esta regresión puede linealizarse. Comúnmente esta regresión es usada para determinar la antigüedad de materiales como también la medición de sismos. 

$${\large \begin{align*} Y = a\ln{X} + b \end{align*} } $$

Aunque se trate de logaritmos el termino $\ln{X}$ se puede tratar como una X. Por consiguiente usando el método de los mínimos cuadrados podemos calcular los valores correspondientes a y b respectivamente.

$${\large \begin{align*} a &= \frac{\sum \ln{X} \sum Y - N\sum (\ln{X} \cdot Y)}{(\sum \ln{X} )^2 - N\sum \ln^2{X}} \\ \\ b &= \frac{\sum \ln{X} \sum (\ln{X} \cdot Y) - \sum Y \sum \ln^2{X}}{(\sum \ln{X} )^2 - N\sum \ln^2{X}} \end{align*} }$$

Ahora trataremos la regresión logarítmica por medio de la siguiente data que se muestra a continuación:

 N de Datos  Datos $X$  Datos $Y$  Datos $\ln^2{X}$  Datos $Y \cdot \ln{X}$ 
Dato 110.500
Dato 220.70.4770.483
Dato 330.81.210.88
Dato 440.91.931.251
Dato 560.953.201.701
Dato 681.24.332.50
Dato 791.254.842.75
Dato 8101.275.292.921
Dato 9121.306.153.224
Dato 10151.377.343.713
$\sum$7010.2434.76719.423


Código Fuente de la Regresión Logarítmica

import numpy as np
import matplotlib.pyplot as plt

fig=plt.figure(figsize=(12,6))

X = np.array([1, 2, 3, 4, 6, 8, 9, 10, 12, 15])
Y = np.array([0.5, 0.7, 0.8, 0.9, 0.95, 1.2, 1.25, 1.27, 1.30, 1.37])

N = len(X)
prom_X= np.mean(np.log(X))
prom_Y= np.mean(Y)
sum_X = np.sum(np.log(X))
pot_X = np.sum(np.log(X)*np.log(X))
sum_Y = np.sum(Y)
prod_XY = np.sum(np.log(X)*Y)
VarX = np.sqrt(np.sum( (np.log(X) - prom_X)**2 ))
VarY = np.sqrt(np.sum( (Y - prom_Y)**2 ))
Cov_X_Y = np.sum( (np.log(X)-prom_X)*(Y-prom_Y) )

a = (sum_X*sum_Y - N*prod_XY)/((sum_X)**2 - N*pot_X)
b = (sum_X*prod_XY - pot_X*sum_Y)/((sum_X)**2 - N*pot_X)

Z = a*np.log(X) + b  

print("La pendiente es igual a {}".format(a))
print("El intercepto es igual a {}".format(b))
plt.title("Regresión Logaritmica", fontsize=20)
plt.xlabel("Eje X", fontsize=20)
plt.ylabel("Eje Y", fontsize=20)
plt.plot(X,Y, 'ro', markersize=10)
plt.plot(X,Z, color='k', lw=2, label="$Y = {:.3f} \cdot \ln(X) + {:.3f} $".format(a,b))
plt.legend(loc='best', fontsize=15)

plt.show()

Regresión Logarítmica para la Data



Regresión Polinómica 

La regresión polinomial es un caso mucho más general que el de la regresión lineal.

$${\large \begin{align*} Y = \beta_{0} + X_{i}\beta_{1} + X^{2}_{i}\beta_{2} + \cdots + X^{m}_{i}\beta_{m}\hspace{1cm},\hspace{0.2cm} i =1,2,3,\cdots,n \end{align*}}$$

Esta regresión necesariamente se resuelve usando la matriz de Vandermonde.

$${\large \begin{align*} Y &= M \cdot C \\ \begin{bmatrix} Y_{1} \\ Y_{2} \\ Y_{3} \\ \vdots \\ Y_{n} \end{bmatrix} &= \begin{bmatrix}1 & X_{1} & X^{2}_{1} & \cdots & X^{m}_{1}  \\ 1 & X_{2} & X^{2}_{2} & \cdots & X^{m}_{2}  \\ 1 & X_{3} & X^{2}_{3} & \cdots & X^{m}_{3}  \\  \vdots & \vdots & \vdots & \ddots &\vdots  \\ 1 & X_{n} & X^{2}_{n} & \cdots &X^{m}_{n}  \end{bmatrix} \cdot  \begin{bmatrix} \beta_{0} \\ \beta_{1} \\ \beta_{2} \\ \vdots \\ \beta_{m} \end{bmatrix} \end{align*}}$$

Para obtener los parámetros de la regresión lineal se hace uso del algebra lineal.

$${\large \begin{align*} Y &= M \cdot C \\ M^{t} \cdot Y &= M^{t} \cdot M \cdot C \\ C &= (M^{t} \cdot M)^{-1} \cdot M^{t} \cdot Y \end{align*} }$$

Ahora trataremos la regresión logarítmica por medio de la siguiente data que se muestra a continuación:

 
N de Datos Datos X Datos Y
Dato 1 0 -1.05
Dato 2 1 5.0
Dato 3 2 9.5
Dato 4 -3 16
Dato 5 4 6.7
Dato 6 -1 3.5
Dato 7 7 56.1
Dato 8 5 30.0
Dato 9 -4 32.5
Dato 10 -9 120.0


Código Fuente de la Regresión Polinómica

import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import inv
import sympy as sp


fig=plt.figure(figsize=(12,6))

x = sp.Symbol('x')

X = np.array([0, 1, 2, -3, 4, -1, 7, 5, -4, -9])
Y = np.array([-1.05, 5, 9.5, 16, 6.7, 3.5, 56.1, 30, 32.5, 120])

n = 2      # Representa el Grado del Polinomio

M = np.vander(X, n+1, increasing=True)
Mt = np.transpose(M)
I = inv(np.dot(Mt, M))

t = np.linspace(min(X), max(X), 10**3)
C = np.dot(np.dot(I , Mt), Y)

h = 0
for i in range(0,n+1,1):
    print('beta_{} = {}'.format(i, C[i]))
    h += round(C[i], 3)*x**i
print(h)
    
Z = 0    
for i in range(0,n+1,1):
    Z += C[i]*(t**i)
plt.plot(t,Z, color='k', lw=2, label=" Y = {}".format(h))
    
    
plt.title("Regresión Lineal por el Método Matricial", fontsize=20)
plt.xlabel("Eje X", fontsize=20)
plt.ylabel("Eje Y", fontsize=20)
plt.plot(X,Y, 'ro', markersize=10)
plt.legend(loc='best', fontsize=15)

plt.show()

Regresión Parabólica para la Data 







Comentarios