Regressió polinòmica
Autor: Joan Puigcerver Ibáñez
Correu electrònic: j.puigcerveribanez@edu.gva.es
Llicència: CC BY-NC-SA 4.0
(Reconeixement - NoComercial - CompartirIgual) 🅭
Regressió polinòmica
La regressió polinòmica és un model de regressió que intenta ajustar les dades
que no segueixen una relació lineal mitjançant un polinomi .
Un pàmetre important en la regressió polinòmica és el grau del polinomi ,
que determina el nombre de coeficients per cada variable independent
que tindrà el model.
La fórmula general d'un polinomi de grau \(n\) per a una variable independent \(X_1\) és:
\[
Y = w_0 + w_1 X_1 + w_2 X_1^2 + \ldots + w_n X_1^n
\]
on:
\(Y\) és la variable dependent (objectiu o target ),
\(X_1\) és la variable independent (característica o feature ),
\(w_0, w_1, w_2, \ldots, w_n\) són els coeficients o pesos del model.
Exemple de formula de grau 2
La fórmula d'un polinomi de grau 2 és amb una variable independent \(X_1\) és:
\[
Y = w_0 + w_1 X_1 + w_2 X_1^2
\]
En cas de tindre dues variables independents \(X_1\) i \(X_2\) , la fórmula general d'un polinomi de grau \(n\) és:
\[
Y = w_0 + w_1 X_1 + w_2 X_2 + w_3 X_1^2 + w_4 X_1X_2 + w_5 X_2^2 + \ldots + w_n X_1^n + w_{n+1} X_1^{n-1}X_2 + \ldots + w_{2n} X_2^n
\]
Exemple de formula de grau 2 amb dues variables
La fórmula d'un polinomi de grau 2 amb dues variables independents \(X_1\) i \(X_2\) és:
\[
Y = w_0 + w_1 X_1 + w_2 X_2 + w_3 X_1^2 + w_4 X_1X_2 + w_5 X_2^2
\]
L'objectiu de la regressió polinòmica és trobar els valors dels coeficients que
millor s'ajusten a les dades.
Preparació de les dades
A partir del polinomi:
\[
Y = -100 - 5X + 5X^2 + 0.1X^3
\]
Anem a generar un conjunt de dades que s'ajusten a aquest polinomi
amb una lleugera desviació.
import numpy as np
from sklearn.model_selection import train_test_split
def f ( x ):
return - 100 - 5 * x + 5 * np . power ( x , 2 ) + 0.1 * np . power ( x , 3 )
np . random . seed ( 42 )
n_samples = 100
X = np . random . uniform ( - 50 , 50 , n_samples )
Y = f ( X ) + np . random . randn ( n_samples ) * 1000
X = X . reshape ( - 1 , 1 ) # Convertim X en una matriu de 1 columna
X_train , X_test , Y_train , Y_test = train_test_split ( X , Y , test_size = 0.2 , random_state = 42 )
X_test , Y_test = zip ( * sorted ( zip ( X_test , Y_test ))) # Ordenem les dades de test per visualitzar-les correctament
Figura 1. Dades generades a partir del polinomi
Regressió lineal
Si intentem ajustar les dades amb un model de regressió lineal,
obtenim un model incapaç de generalitzar les dades de manera correcta.
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score
model = LinearRegression ()
model . fit ( X_train , Y_train )
pred_Y = model . predict ( X_test )
rmse = mean_squared_error ( Y_test , pred_Y )
r2 = r2_score ( Y_test , pred_Y )
print ( f 'RMSE linear: { rmse : .2f } ' )
print ( f 'R^2 linear: { r2 : .2f } ' )
RMSE linear: 12671123.84
R^2 linear: 0.50
Figura 2. Regressió lineal
Model de regressió polinòmica
Els models de regressió polinòmica són capaços
de trobar la relació no lineal entre les variables
mitjançant un polinomi.
Utilitzant la llibreria scikit-learn
podem crear un model
de regressió polinòmica de manera senzilla.
Creació del model
Per crear un model de regressió polinòmica amb scikit-learn
podem
utilitzarem les següents classes i mètodes:
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
degree = 3
polynomial_features = PolynomialFeatures ( degree = degree , include_bias = False )
model = make_pipeline ( polynomial_features , LinearRegression ())
Entrenament del model
Per entrenar el model amb les dades, utilitzem el mètode fit
de la classe LinearRegression
.
model . fit ( X_train , Y_train )
Coeficients del model
Una vegada s'ha entrenat el model, podem obtenir els coeficients del polinomi
obtingut.
coef_
: coeficients de les variables independents.
intercept_
: terme independent de la recta.
print ( f 'Coeficients: { model . named_steps [ "linearregression" ] . coef_ } ' )
print ( f 'Intercept: { model . named_steps [ "linearregression" ] . intercept_ } ' )
Coeficients: [-1.63821771 5.24145621 0.09552926]
Intercept: -362.88402429981306
Predicció i avaluació amb el model
Una vegada entrenat, podem fer prediccions amb el model i avaluar-lo.
pred_Y = model . predict ( X_test )
rmse = mean_squared_error ( Y_test , pred_Y )
r2 = r2_score ( Y_test , pred_Y )
print ( f 'RMSE polinòmica: { rmse : .2f } ' )
print ( f 'R^2 polinòmica: { r2 : .2f } ' )
RMSE polinòmica: 642049.3
R2 polinòmica: 0.97
Visualització del model
Podem visualitzar el model de regressió lineal amb una gràfica.
plt . scatter ( X_train , Y_train , color = 'blue' )
plt . scatter ( X_test , Y_test , color = 'orange' )
plt . plot ( X_test , pred_Y , color = 'red' )
plt . show ()
Figura 3. Model de regressió polinòmica
Codi font
regressio_polinomica.py #!/usr/bin/env python
# --8<-- [start:dades]
import numpy as np
from sklearn.model_selection import train_test_split
def f ( x ):
return - 100 - 5 * x + 5 * np . power ( x , 2 ) + 0.1 * np . power ( x , 3 )
np . random . seed ( 42 )
n_samples = 100
X = np . random . uniform ( - 50 , 50 , n_samples )
Y = f ( X ) + np . random . randn ( n_samples ) * 1000
X = X . reshape ( - 1 , 1 ) # Convertim X en una matriu de 1 columna
X_train , X_test , Y_train , Y_test = train_test_split ( X , Y , test_size = 0.2 , random_state = 42 )
X_test , Y_test = zip ( * sorted ( zip ( X_test , Y_test ))) # Ordenem les dades de test per visualitzar-les correctament
# --8<-- [end:dades]
# --8<-- [start:plot_lineal]
import matplotlib.pyplot as plt
plt . scatter ( X_train , Y_train , color = 'blue' )
plt . scatter ( X_test , Y_test , color = 'orange' )
plt . show ()
# --8<-- [end:plot_lineal]
# --8<-- [start:regressio_lineal]
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score
model = LinearRegression ()
model . fit ( X_train , Y_train )
pred_Y = model . predict ( X_test )
rmse = mean_squared_error ( Y_test , pred_Y )
r2 = r2_score ( Y_test , pred_Y )
print ( f 'RMSE linear: { rmse : .2f } ' )
print ( f 'R^2 linear: { r2 : .2f } ' )
# --8<-- [end:regressio_lineal]
# --8<-- [start:plot_lineal]
plt . scatter ( X_train , Y_train , color = 'blue' )
plt . scatter ( X_test , Y_test , color = 'orange' )
plt . plot ( X_test , pred_Y , color = 'red' )
plt . show ()
# --8<-- [end:plot_lineal]
# --8<-- [start:model]
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
degree = 3
polynomial_features = PolynomialFeatures ( degree = degree , include_bias = False )
model = make_pipeline ( polynomial_features , LinearRegression ())
# --8<-- [end:model]
# --8<-- [start:fit]
model . fit ( X_train , Y_train )
# --8<-- [end:fit]
# --8<-- [start:params]
print ( f 'Coeficients: { model . named_steps [ "linearregression" ] . coef_ } ' )
print ( f 'Intercept: { model . named_steps [ "linearregression" ] . intercept_ } ' )
# --8<-- [end:params]
# --8<-- [start:predict]
pred_Y = model . predict ( X_test )
rmse = mean_squared_error ( Y_test , pred_Y )
r2 = r2_score ( Y_test , pred_Y )
print ( f 'RMSE polinòmica: { rmse : .2f } ' )
print ( f 'R^2 polinòmica: { r2 : .2f } ' )
# --8<-- [end:predict]
# --8<-- [start:plot_polinomica], pred_Y)
plt . scatter ( X_train , Y_train , color = 'blue' )
plt . scatter ( X_test , Y_test , color = 'orange' )
plt . plot ( X_test , pred_Y , color = 'red' )
plt . show ()
# --8<-- [end:plot_polinomica]