Introduction simple à la régression polynomiale

Publié: 15-12-2019
Le code de ce post est écrit avec Python version 3.7.3 à l'aide du logiciel Spyder.

Dans cet article, je vais discuter la régression polynomiale. Je veux commencer par un rappel sur les régressions linéaires simples et multiples:

Régression linéaire simple: $$ y=b_0 + b_1 \times x_1 $$

Régression linéaire multiple: $$ y=b_0 + b_1 \times x_1 + b_2 \times x_2 + ... + b_n \times x_n $$

La régression polynomiale peut être représentée avec l'équation ci-dessous: $$ y=b_0 + b_1 \times x_1 + b_2 \times x_1^2 + ... + b_n \times x_1^n $$

Rappel de ce qu'est un ensemble de données dans un projet d'apprentissage automatique:

Considérez la fonction polynomiale suivante: $$ P(x)= x^3 + 2\times x^2 + 3 \times x $$

                
                    import numpy as np
                    import matplotlib.pyplot as plt

                    #nous définirons la fonction P(x) en python
                    def p(x):
                        return x**3 + 2*x**2 + 3*x

                    #générez des données qui peuvent être ajustées avec une régression linéaire
                    x=np.linspace(1,50,100) + 2*np.random.randn(100)
                    plt.scatter(np.linspace(1,50,100),x)
                
            
                
                    #Appliquer la fonction polynomiale aux données générées
                    x=p(x)
                    plt.scatter(np.linspace(1,50,100),x)
                
            

Après avoir appliqué la fonction polynomiale, les données ne peuvent pas être parfaitement ajustées avec un régresseur linéaire. Par conséquent, dans de tels cas, nous devons utiliser la régression polynomiale linéaire.

Maintenant, pour continuer avec ce problème, nous allons utiliser un régresseur polynomial de degré 2: $$ \hat{y} = b + w_1x_1 + w_2x_1^2 \\ \hat{y} = w_0x_0 + w_1x_1 + w_2x_1^2 $$

Vous pouvez remarquer que cela ressemble à un problème de régression linéaire multiple discuté dans le post précédent <Introduction simple à la régression linéaire multiple>. Étant donné que nous travaillons avec des matrices et que nous avons de nombreux échantillons, le vecteur de prédiction peut être écrit comme suit: $$ \vec{Y}_{N \times 1} = X_{N \times D}w_{D \times 1} $$ Dans cet exemple, la dimension D sera égale à 3 puisque nous utilisons un régresseur polynomial de degré 2 et nous y ajoutons x_0 qui est égal à 1 et sera multiplié par le terme de biais w_0.

La fonction de coût E est la suivante: $$ E=\sum_{i=1}^{N}\big(y_i - \hat{y}_i \big)^2 = \big( Y_{N \times 1} - \hat{Y}_{N \times 1} \big)^T\big( Y_{N \times 1} - \hat{Y}_{N \times 1} \big) $$ Après avoir fait les mêmes dérivées partielles discutées dans le post précédent, nous obtenons thêta qui est la valeur du vecteur de paramètres (W) qui minimise la fonction de coût: $$\hat{\theta}=\big(X^TX \big)^{-1}X^Ty$$

                
                    #le code suivant est une continuation de ce qui précède
                    #*******************************************************
                    x=np.linspace(1,50,100) + 2*np.random.randn(100)
                    #créer l'entrée X et la sortie Y
                    X=[]
                    Y=[]
                    for i in range(len(x)):
                      #rappelez-vous que nous utilisons un
                      #régresseur polynomial de degré 2
                      X.append([1,x[i],x[i]*x[i]])

                    X=np.array(X)
                    Y=np.array(p(np.linspace(1,50,100)))

                    #calculer les poids W
                    w=np.linalg.solve(np.dot(X.T,X),np.dot(X.T,Y))
                    #calculer les prédictions
                    Yhat=np.dot(X,w)

                    #tracer tous ensemble
                    plt.scatter(X[:,1],Y)
                    plt.plot(X[:,1],Yhat,'r')
                
            

Maintenant, testons le modèle sur un ensemble de test:

                
                    #le code suivant est une continuation de ce qui précède
                    #*******************************************************

                    #générer des données avec une plage différente
                    #de celles utilisées pour l'apprentissage
                    x=np.linspace(50,100,100) + 2*np.random.randn(100)
                    X_test=[]
                    Y_test=[]
                    for i in range(len(x)):
                        X_test.append([1,x[i],x[i]*x[i]])

                    X_test=np.array(X_test)
                    Y_test=np.array(p(np.linspace(50,100,100)))

                    #calculer les prédictions
                    #en utilisant les poids calculés
                    Yhat=np.dot(X_test,w)


                    plt.scatter(X_test[:,1],Y_test)
                    plt.plot(X_test[:,1],Yhat,'r')
                
            

On peut voir que le modèle n'a pas bien ajusté les données. Essayons d'utiliser un régresseur avec un degré polynomial de 3.

                
                    x=np.linspace(1,50,100) + 2*np.random.randn(100)
                    X=[]
                    Y=[]
                    for i in range(len(x)):
                      #degré=3
                      X.append([1,x[i],x[i]*x[i],x[i]*x[i]*x[i]])

                    X=np.array(X)
                    Y=np.array(p(np.linspace(1,50,100)))

                    #calculer les poids
                    w=np.linalg.solve(np.dot(X.T,X),np.dot(X.T,Y))
                    Yhat=np.dot(X,w)


                    #testons le modèle sur un ensemble de test
                    x=np.linspace(50,100,100) + 2*np.random.randn(100)
                    X_test=[]
                    Y_test=[]
                    for i in range(len(x)):
                      #degré=3
                      X_test.append([1,x[i],x[i]*x[i],x[i]*x[i]*x[i]])

                    X_test=np.array(X_test)
                    Y_test=np.array(p(np.linspace(50,100,100)))

                    Yhat=np.dot(X_test,w)
                    plt.scatter(X_test[:,1],Y_test)
                    plt.plot(X_test[:,1],Yhat,'r')
                
            

Nous avons obtenu une meilleure ligne avec un degré de 3 qu'avec un degré de 2. Cependant, vous devez choisir le degré avec soin car parfois l'utilisation d'un degré polynomial plus élevé peut conduire à un sur-ajustement (overfitting).

Même si nous prédisons une fonction polynomiale, la méthode est toujours appelée régression linéaire. Le terme linéaire fait ici référence aux coefficients (poids) et non à l'entrée X. Ainsi, même si les données d'entrée X ne sont pas linéaires, la relation entre les coefficients est toujours linéaire. Voici un exemple de relation non linéaire entre les coefficients: $$ \hat{y} = w_0x_0 + \frac{w_1x_1}{w_2x_1^2} $$