Dans notre précédent article Créer Un Modèle De Régression Linéaire Avec Python, nous avons présenté de façon générale la régression linéaire. Nous aborderons dans cet article le cas de la régression polynomiale.
Pour rappel : La régression linéaire est un modèle (analyse) qui a pour but d’établir une relation linéaire entre une variable (appelée variable expliquée) par une ou plusieurs autres variables (appelées variables explicatives). Par exemple, il peut exister une relation linéaire entre le salaire d’une personne et le nombre d’années passées à l’université.
Alors la question est de savoir si notre modèle de régression linéaire sera autant performant s’il n’existe pas de relation linéaire entre la variable expliquée et le ou les variable(s) expliquée(s) ?
Plan de l’article
Dans cet article nous allons aborder les points suivants
- Le problème de la régression linéaire
- La Régression polynomiale
- l’Over-fitting et l’Under-fitting
- La régression polynomiale avec python
Le problème de la régression linéaire
L’une des grandes hypothèses de la régression linéaire est bien évidement l’existence d’une relation de linéaire entre les variables expliquées (y) et explicatives (x). Le problème est que rien n’est vraiment linéaire (une pensée pour Gallilé…) . Illustrons nos dires au travers d’un exemple.
Dans l’exemple suivant nous allons générer un jeu de données où la relation entre les variables explicatives et expliquées n’est pas linéaire.
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns sns.set(color_codes=True) plt.rcParams["figure.figsize"] = [12,12] #plt.figure(figsize=(12,12)) np.random.seed(0) #jeu de données sous la forme y = f(x) avec f(x) = x^4 + bx^3 + c x = np.random.normal(10, 2, 500) y = x ** 4 + np.random.uniform(-1, 1,500)*(x ** 3) + np.random.uniform(0, 1,500) plt.scatter(x,y) plt.show()
Ensuite, appliquons à notre jeu de données un modèle de régression linéaire afin de tracer la droite de régression.
x = x[:, np.newaxis] y = y[:, np.newaxis] from sklearn.linear_model import LinearRegression model = LinearRegression() model.fit(x,y) y_predict = model.predict(x) plt.scatter(x, y) plt.plot(x, y_predict, color='g') plt.show()
Aussi, on voit que notre modèle de régression nous donnera de mauvaises prédictions car nous avons un mauvais ajustement de notre de régression. Dans ce cas, on aura une erreur de prédiction assez élevée.
C’était évident mais l’idée était de montrer que la régression linéaire n’est pas forcément adaptée à tous les problèmes de régression.
Afin d’améliorer notre modèle de régression, penser aux polynômes est une très bonne idée ! Pourquoi ? Je vous mets de la lecture sur la théorie de l’approximation polynomiale.🙃
Bref d’où l’idée de la régression polynomiale.
La Régression polynomiale
La régression polynomiale est une forme d’analyse de régression dans laquelle la relation entre la variable explicative et la variable expliquée est modélisée comme un polynôme.
Petit rappel : La régression linéaire est une régression polynomiale de degré 1.
Alors pourquoi se limiter à un polynôme de degré 1 ?🙈
Si on prend l’exemple de la régression linéaire simple où la relation entre la variable expliquée et la variable explicative peut s’écire comme suit :
l’idée de la régression polynomiale sera d’écrire cette relation comme suit:
(ou n est le dégré du polynôme)
Si on reprend notre précédent exemple en utilisant cette fois-ci une relation polynomiale on s’aperçoit que l’erreur de prédiction est moins élevée et que notre droite de régression s’ajuste mieux à nos données.
from sklearn.preprocessing import PolynomialFeatures polynomial_features= PolynomialFeatures(degree=4) x_poly = polynomial_features.fit_transform(x) model = LinearRegression() model.fit(x_poly, y) y_poly_pred = model.predict(x_poly) rmse = np.sqrt(mean_squared_error(y,y_poly_pred)) #r2 = r2_score(y,y_poly_pred) print(rmse) #print(r2) import operator plt.scatter(x, y, s=10) # sort the values of x before line plot sort_axis = operator.itemgetter(0) sorted_zip = sorted(zip(x,y_poly_pred), key=sort_axis) x_p, y_poly_pred_P = zip(*sorted_zip) plt.plot(x_p, y_poly_pred_P, color='g') plt.show()
Comprendre l’Over-fitting et l’Under-fitting
Une question qu’on peut se poser est : comment se fait le choix du degré du polynôme dans la régression polynomiale ? Nous allons profiter de cette question pour aborder deux notions très très très très importantes que sont l’under-fitting et l’over-fitting.
Nous allons tracer la courbe de l’erreur quadratique en fonction du degré du polynôme.
def degreeChoice (x,y,degree): polynomial_features= PolynomialFeatures(degree=degree) x_poly = polynomial_features.fit_transform(x) model = LinearRegression() model.fit(x_poly, y) y_poly_pred = model.predict(x_poly) rmse = np.sqrt(mean_squared_error(y,y_poly_pred)) sort_axis = operator.itemgetter(0) sorted_zip = sorted(zip(x,y_poly_pred), key=sort_axis) x_p, y_poly_pred_P = zip(*sorted_zip) return rmse, x_p, y_poly_pred_P rmselist = np.zeros(100) x_p_list = [None]*100 y_poly_pred_P_list=[None]*100 for i in np.arange(1, 101): rmselist[i-1] ,x_p_list[i-1],y_poly_pred_P_list[i-1]= degreeChoice (x,y,i) plt.plot(np.arange(1, 101), rmselist, color='r') plt.show()

fig, axs = plt.subplots(3, 2,figsize=(20,20)) axs[0, 0].scatter(x, y) axs[0, 0].plot(x_p_list[0],y_poly_pred_P_list[0],color='g') axs[0, 0].set_title('Regression linéaire simple') #degre 2 axs[0, 1].scatter(x, y) axs[0, 1].plot(x_p_list[1],y_poly_pred_P_list[1],color='g') axs[0, 1].set_title('Regression polynomiale deg 2') #degre 4 axs[1, 0].scatter(x, y) axs[1, 0].plot(x_p_list[3],y_poly_pred_P_list[3],color='g') axs[1, 0].set_title('Regression polynomiale deg 4') #degre 16 axs[1, 1].scatter(x, y) axs[1, 1].plot(x_p_list[15],y_poly_pred_P_list[15],color='g') axs[1, 1].set_title('Regression polynomiale deg 16') #degre 32 axs[2, 0].scatter(x, y) axs[2, 0].plot(x_p_list[31],y_poly_pred_P_list[31],color='g') axs[2, 0].set_title('Regression polynomiale deg 32') #degre 64 axs[2, 1].scatter(x, y) axs[2, 1].plot(x_p_list[63],y_poly_pred_P_list[63],color='g') axs[2, 1].set_title('Regression polynomiale deg 64') for ax in axs.flat: ax.set(xlabel='x', ylabel='y') for ax in axs.flat: ax.label_outer()

La régression polynomiale avec python
Afin d’illustrer la régression polynomiale sur un vrai dataset, nous allons améliorer le modèle de prédiction des prix de maison créé dans l’article sur la régression linéaire.
Petit rappel:
Le jeu de données utilisé était le Boston Housing Dataset qui contient un bon nombre de données sur l’immobilier à Boston (prix, superficie, …).
L’objectif sera de prédire le prix des maisons (variable expliquée) grâce aux différentes informations présentes dans le jeu de données (variables explicatives). L’analyse des données ayant déjà été faite dans cet article, nous passons directement à création du modèle.
#on importe les libs et les données import numpy as np from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error from sklearn.metrics import r2_score from sklearn.preprocessing import PolynomialFeatures from sklearn.datasets import load_boston donnees_boston = load_boston() #Transformation de notre jeu de données en Data Frame grace à pandas donnees_boston_df = pd.DataFrame(donnees_boston.data, columns=donnees_boston.feature_names) #on utilise seulement 4 variables explicatives X=pd.DataFrame(np.c_[donnees_boston_df['LSTAT'],donnees_boston_df['RM'],donnees_boston_df['TAX'],donnees_boston_df['PTRATIO']], columns = ['LSTAT','RM','TAX','PTRATIO']) Y = donnees_boston_df['PRIX'] #base d'apprentissage et base de test from sklearn.model_selection import train_test_split X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.2, random_state=5) print(X_train.shape) print(X_test.shape) print(Y_train.shape) print(Y_test.shape) #on defintit la fonction pour entrainer et choisir notre modèle en fonction du degré du polynome def evalPolynonmialRegression(degree): #entrainement du modèle polynomial_features= PolynomialFeatures(degree=degree) X_train_poly = polynomial_features.fit_transform(X_train) X_test_poly = polynomial_features.fit_transform(X_test) model = LinearRegression() model.fit(X_train_poly, Y_train) # Evaluation du training set y_train_predict = model.predict(X_train_poly) rmse = (np.sqrt(mean_squared_error(Y_train, y_train_predict))) r2 = r2_score(Y_train, y_train_predict) print('La performance du modèle sur la base dapprentissage') print('--------------------------------------') print('Lerreur quadratique moyenne est {}'.format(rmse)) print('le score R2 est {}'.format(r2)) print('\n') # Evaluation du testing set y_test_predict = model.predict(X_test_poly) rmse = (np.sqrt(mean_squared_error(Y_test, y_test_predict))) r2 = r2_score(Y_test, y_test_predict) print('La performance du modèle sur la base de test') print('--------------------------------------') print('Lerreur quadratique moyenne est {}'.format(rmse)) print('le score R2 est {}'.format(r2)) return model,r2 ,rmse
Alors, on execute la fonction avec un degré=4.
evalPolynonmialRegression(4)
Nous obtientenons bien évidemment un meilleur modèle.
La performance du modèle sur la base dapprentissage -------------------------------------- Lerreur quadratique moyenne est 2.90954689132934 le score R2 est 0.9014517366633048 La performance du modèle sur la base de test -------------------------------------- Lerreur quadratique moyenne est 3.457159901752652 le score R2 est 0.8473449481539901
Ressources complémentaires
Le Notebook de l’article
La doc de sklearn sur les différentes méthodes de regression
L’underfitting
L’Overfitting
Petit Récap
En somme, nous avons présenté dans cet article la regression polynomiale. En effet la différence entre la regression polynomiale et a regression linéaire est l’utilisation d’un polynome pour décrire la relation entre les variables. Nous avons pu aborder dans la foulée les notions de d’overfitting et de underfitting. N’hesitez pas à laisser des commentaires pour les questions et suggestions.
Article interessant