Regresión polinomial en Python

Si sus puntos de datos claramente no se ajustan a una regresión lineal (una línea recta a través de todos los puntos de datos), podría ser ideal para la regresión polinomial.

La regresión polinomial, como la regresión lineal, utiliza la relación entre las variables x e y para encontrar la mejor forma de dibujar una línea a través de los puntos de datos.

¿Como funciona?

Python tiene métodos para encontrar una relación entre puntos de datos y dibujar una línea de regresión polinomial. Le mostraremos cómo usar estos métodos en lugar de pasar por la fórmula matemática.

En el siguiente ejemplo, hemos registrado 18 automóviles cuando pasaban por una cabina de peaje determinada.

Hemos registrado la velocidad del automóvil y la hora del día (hora) en que ocurrió el rebasamiento.

El eje x representa las horas del día y el eje y representa la velocidad:


import matplotlib.pyplot as plt

X =[1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
Y =[100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]

plt.scatter(x, y)
plt.show()

import numpy
import matplotlib.pyplot as plt

X =[1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
Y =[100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]

mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))

myline = numpy.linspace(1, 22, 100)

plt.scatter(x, y)
plt.plot(myline, mymodel(myline))
plt.show()

Ejemplo explicado

Importa los módulos que necesites.

import numpy
import matplotlib.pyplot as plt

Cree las matrices que representan los valores de los ejes x e y:

X =[1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
Y =[100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]

NumPy has a method that lets us make a polynomial model:

mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))

Then specify how the line will display, we start at position 1, and end at position 22:

myline = numpy.linspace(1, 22, 100)

Dibujar el diagrama de dispersión original:

plt.scatter(x, y)

Dibujar la línea de regresión polinomial:

plt.plot(myline, mymodel(myline))

Muestre el diagrama:

plt.show()

R-cuadrado

It is important to know how well the relationship between the values of the x- and y-axis is, if there are no relationship the polynomial regression can not be used to predict anything.

The relationship is measured with a value called the r-squared.

The r-squared value ranges from 0 to 1, where 0 means no relationship, and 1 means 100% related.

Python and the Sklearn module will compute this value for you, all you have to do is feed it with the x and y arrays:

import numpy
from sklearn.metrics import r2_score
X =[1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
Y =[100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]
mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))
print(r2_score(y, mymodel(x)))

Nota: El resultado 0.94 muestra que hay una muy buena relación y podemos usar la regresión polinomial en futuras predicciones.

Predecir valores futuros

Ahora podemos usar la información que hemos recopilado para predecir valores futuros.

Ejemplo: Intentemos predecir la velocidad de un automóvil que pasa por la cabina de peaje alrededor de las 17:00:

Para hacerlo, necesitamos la misma matriz mymodel del ejemplo anterior:

mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))

Ejemplo

Prediga la velocidad de un automóvil que pasa a las 17:00:

import numpy
from sklearn.metrics import r2_score
X =[1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
Y =[100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]
mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))
speed = mymodel(17)
print(speed)

El ejemplo predijo una velocidad de 88,87, que también pudimos leer en el diagrama:

¿Mal ajuste?

Vamos a crear un ejemplo donde la regresión polinomial no sería el mejor método para predecir valores futuros.

import numpy
import matplotlib.pyplot as plt

X =[89,43,36,36,95,10,66,34,38,20,26,29,48,64,6,5,36,66,72,40]
Y =[21,46,3,35,67,95,53,72,58,10,26,34,90,33,38,20,56,2,47,15]

mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))

myline = numpy.linspace(2, 95, 100)

plt.scatter(x, y)
plt.plot(myline, mymodel(myline))
plt.show()

¿Y el valor de r-cuadrado?

import numpy
from sklearn.metrics import r2_score
X =[89,43,36,36,95,10,66,34,38,20,26,29,48,64,6,5,36,66,72,40]
Y =[21,46,3,35,67,95,53,72,58,10,26,34,90,33,38,20,56,2,47,15]
mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))
print(r2_score(y, mymodel(x)))

El resultado: 0,00995 indica una relación muy mala y nos dice que este conjunto de datos no es adecuado para la regresión polinomial.