Introduction à la régression linéaire simple

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

Lorsque nous parlons de régression linéaire, nous parlons d’apprentissage supervisé X → Y. La régression linéaire est également connue sous le nom de "ligne du meilleur ajustement" (Line of best fit). Dans un problème de régression, la sortie (Y) est un nombre.

Regression
Ligne de meilleur ajustement [1]

Exemple du monde réel

Un exemple est la prédiction de la note d’un élève dans une classe compte tenu du nombre d’heures d’études qu’il a effectuées.

X = nombre d'heures d'étude → Y = note

Corrélation et causalité

Il est important de noter que nous devons faire attention à déterminer le sens de la causalité. Si nous prenons l'exemple ci-dessus, il est très évident que si vous étudiez plus, vous obtiendrez une meilleure note. La seule chose que nous pouvons conclure lorsque nous trouvons une droite de meilleur ajustement, et que cela ajuste assez bien les données, est que les deux variables sont corrélées l'une avec l'autre. Mais cela ne signifie pas que l'un cause l'autre. Par exemple, les deux variables "heures d'étude" et "note" peuvent être corrélées l'une avec l'autre, mais il peut y avoir une troisième cause, comme si vos parents vous obligent à étudier plus, ce qui vous oblige à passer plus d'heures à étudier, ce qui entraîne votre note à augmenter.

Corrélation ne signifie pas causalité.

Formulation du problème

On nous donne un ensemble de points {(x1, y1),(x2, y2), (x3, y3), ...,(x_n, y_n)}.

Nous les traçons dans un graphe en 2D.

Nous trouvons la ligne de meilleur ajustement.

Comment faire?

La ligne de meilleur ajustement est définie comme suit: $$ \hat{y_i}=ax_i+b \; \; \; \text{ / } \hat{y_i} \text{ est notre prédiction.} $$

Nous voulons nous assurer que cela ajuste bien les données. Ce que nous souhaitons, c’est que tous les points cibles (y_i), qui proviennent des données recueillies dans notre expérience, sont proches de nos prédictions à partir de x_i: $$y_i \text{ proche de } \hat{y_i} \: ,i=1..N$$

Fonction de perte (Loss function)

Afin de quantifier la qualité de l'ajustement, nous définissons une fonction de perte. Pour toute valeur cible différente de la valeur prédite, nous voulons une contribution positive à l'erreur. La méthode standard est de carré la différence et en utilisant ce que l'on appelle « Somme des erreurs au carré ». $$E=\sum_{i=1}^{N}(y_i-\hat{y_i})^2$$

Maintenant, nous avons cette expression d'erreur, nous aimerions la minimiser. Le calcul (calculus) est l'outil dont nous avons besoin lorsque nous voulons minimiser les choses. Par exemple, considérons l'erreur E comme ci-dessous: $$E=0.5t^2-t$$ L’objectif est de savoir quel est le t qui nous donne le minimum E. Pour ce faire, nous pouvons calculer la dérivée de E par rapport à t et la mettre à zéro, puis résoudre le t. Nous obtiendrons l'erreur minimale pour t égal à 1. $$\frac{dE}{dt}=t-1$$ $$t-1=0 \rightarrow t=1$$

Dans notre problème, il y a plus de variables impliquées. Nous voulons minimiser E: $$E=\sum_{i=1}^{N}(y_i-\hat{y_i})^2$$ Cette expression peut aussi être écrite comme: $$E=\sum_{i=1}^{N}(y_i-(ax_i+b))^2$$ y_i et x_i sont donnés, ce sont les points de données collectés lors de notre expérimentation. Ce que nous voulons trouver, c'est a et b, car cela nous indique la pente de la ligne et l'interception.

Minimiser la fonction de perte

Pour minimiser la fonction d'erreur, nous voulons minimiser E par rapport à a et b. E est une fonction de 2 variables, nous devons donc utiliser des dérivées partielles. $$E=\sum_{i=1}^{N}(y_i-(ax_i+b))^2$$ Dérivé de E par rapport à a: $$\frac{\partial E}{\partial a}=\sum_{i=1}^{N}2(y_i-(ax_i+b))(-x_i)$$ la mettre à zéro: $$\sum_{i=1}^{N}2(y_i-(ax_i+b))(-x_i)=0$$ $$-\sum_{i=1}^{N}y_ix_i + a\sum_{i=1}^{N}x_i^2 + b\sum_{i=1}^{N}x_i = 0 $$ $$a\sum_{i=1}^{N}x_i^2 + b\sum_{i=1}^{N}x_i = \sum_{i=1}^{N}y_ix_i $$

Le résultat est une équation à 2 inconnues. Nous avons encore besoin de prendre la dérivée de E par rapport à b. $$\frac{\partial E}{\partial b}=\sum_{i=1}^{N}2(y_i-(ax_i+b))(-1)$$ la mettre à zéro: $$-\sum_{i=1}^{N}y_i + a\sum_{i=1}^{N}x_i + b\sum_{i=1}^{N}1 = 0 $$ $$a\sum_{i=1}^{N}x_i + bN = \sum_{i=1}^{N}y_i $$

Maintenant nous avons deux équations à deux inconnues: $$ \begin{cases} a\sum_{i=1}^{N}x_i^2 + b\sum_{i=1}^{N}x_i = \sum_{i=1}^{N}y_ix_i \\ a\sum_{i=1}^{N}x_i + bN = \sum_{i=1}^{N}y_i \end{cases} $$

Maintenant, nous voulons résoudre a et b. Pour faciliter la lecture, nous pouvons remplacer les sommations par des lettres. $$ C=\sum_{i=1}^{N}x_i^2 \text{ ,} \; \; D=\sum_{i=1}^{N}x_i \text{ ,} \; \; E=\sum_{i=1}^{N}y_ix_i \text{ ,} \; \; F=\sum_{i=1}^{N}y_i \; \; $$ $$ \begin{cases} aC + bD = E \\ aD + bN = F \end{cases} $$

La résolution de ces équations nous donnera ces résultats: $$a=\frac{EN-FD}{NC-D^2} \text{ ,} \; \; b=\frac{ED-FC}{D^2-NC} \; \;$$ $$a=\frac{N\sum_{i=1}^{N}y_ix_i-\sum_{i=1}^{N}x_i\sum_{i=1}^{N}y_i}{N\sum_{i=1}^{N}x_i^2 -(\sum_{i=1}^{N}x_i)^2} \text{ ,} \; \; b=\frac{\sum_{i=1}^{N}x_i\sum_{i=1}^{N}y_ix_i-\sum_{i=1}^{N}y_i\sum_{i=1}^{N}x_i^2}{(\sum_{i=1}^{N}x_i)^2-N\sum_{i=1}^{N}x_i^2} \; \;$$ Rendre le dénominateur identique: $$a=\frac{N\sum_{i=1}^{N}y_ix_i-\sum_{i=1}^{N}x_i\sum_{i=1}^{N}y_i}{N\sum_{i=1}^{N}x_i^2 -(\sum_{i=1}^{N}x_i)^2} \text{ ,} \; \; b=\frac{\sum_{i=1}^{N}y_i\sum_{i=1}^{N}x_i^2-\sum_{i=1}^{N}x_i\sum_{i=1}^{N}y_ix_i}{N\sum_{i=1}^{N}x_i^2-(\sum_{i=1}^{N}x_i)^2} \; \;$$ Simplification: $$ \bar{x}=\frac{1}{N}\sum_{i=1}^{N}x_i \text{ ,} \; \; \bar{y}=\frac{1}{N}\sum_{i=1}^{N}y_i \text{ ,} \; \; \bar{x^2}=\frac{1}{N}\sum_{i=1}^{N}x_i^2 \text{ ,} \; \; \bar{xy}=\frac{1}{N}\sum_{i=1}^{N}x_iy_i \; \; $$ $$ a=\frac{N \times N\bar{xy} - N \times N\bar{x}\bar{y}}{N \times N\bar{x^2}-N \times N\bar{x}^2}=\frac{\bar{xy} - \bar{x}\bar{y}}{\bar{x^2}-\bar{x}^2} $$ Même chose pour b: $$ b=\frac{\bar{y}\bar{x^2} - \bar{x}\bar{xy}}{\bar{x^2}-\bar{x}^2} $$

Codage de la solution 1-D en python

Dans ce qui suit, je vais vous montrer comment coder une régression linéaire simple en Python. Nous allons commencer par importer les bibliothèques numpy et pyplot.

            
                import numpy as np
                import matplotlib.pyplot as plt

                #31/5/2019
                #Version python  → 3.7.3
                #version numpy   → 1.16.2
                #version matplotlib  → 3.0.3
            
        

Ensuite, nous allons générer 200 points de données aléatoires entre 0 et 50.

            
                X=np.linspace(0,50,200)
                Y=np.linspace(0,50,200) + 4*np.random.randn(200)
            
        

Tracer les données:

            
                plt.scatter(X,Y)
                plt.show()
            
        

Maintenant, nous voulons trouver la ligne de meilleur ajustement. Pour ce faire, nous devons calculer a et b. $$ a=\frac{\bar{xy} - \bar{x}\bar{y}}{\bar{x^2}-\bar{x}^2} \\ b=\frac{\bar{y}\bar{x^2} - \bar{x}\bar{xy}}{\bar{x^2}-\bar{x}^2} $$ Nous pouvons simplifier davantage a et b en divisant le numérateur et le dénominateur par 1/N. $$ a=\frac{\sum_{i=1}^{N}y_ix_i - \bar{y}\sum_{i=1}^{N}x_i}{\sum_{i=1}^{N}x_i^2-\bar{x}\sum_{i=1}^{N}x_i} \\ b=\frac{\bar{y}\sum_{i=1}^{N}x_i^2 - \bar{x}\sum_{i=1}^{N}y_ix_i}{\sum_{i=1}^{N}x_i^2-\bar{x}\sum_{i=1}^{N}x_i} $$ Cette simplification nous aidera à utiliser les fonctions dot, mean et sum en python.

            
                # Calculer a et b
                denominateur = X.dot(X) - X.mean() * X.sum()
                a=(X.dot(Y)-Y.mean()*X.sum())/denominateur
                b=(Y.mean()* X.dot(X)-X.mean()*X.dot(Y))/denominateur

                # Calculer le Y prédit
                Yhat=a*X+b

                #Plot
                plt.scatter(X,Y)
                plt.plot(X,Yhat,'r')
                plt.show()
            
        

Déterminer la qualité du modèle

Nous verrons ci-après comment déterminer l'efficacité de notre modèle. Pour ce faire, nous allons utiliser ce que l'on appelle R-carré. Le R-carré peut être défini comme 1 moins la somme des résidus au carré par rapport à la somme du total au carré. $$ R^2=1-\frac{SC_{res}}{SC_{tot}} $$ la somme des résidus au carré est la somme de notre erreur de prédiction au carré. $$ SC_{res}=\sum_{i=1}^{N}(y_i-\hat{y_i})^2 $$ La somme du total au carré est définie comme la somme de tout y moins la moyenne, au carré. $$ SC_{tot}=\sum_{i=1}^{N}(y_i-\bar{y})^2 $$ Maintenant, comment cette métrique va nous aider? si le R-carré est proche ou égal à 1, cela signifie que l'erreur est trop petite et que nous avons un modèle parfait. Si le R-carré est égal à zéro, cela signifie que notre modèle ne prédit que la moyenne de y. Par conséquent, notre modèle n'est pas très bon. Cela peut se produire s'il n'y a pas de tendance dans les données. Si R-carré est négatif, cela signifie que notre modèle est pire que la simple prédiction de la moyenne.

Coder le R-carré en Python

Nous allons maintenant déterminer la qualité de notre modèle ci-dessus.

            
                #Calculer r-carre
                d1=Y-Yhat
                d2=Y-Y.mean()
                r2=1-(d1.dot(d1)/d2.dot(d2))

                print ("le r-carre est:",r2)
                # → 0.93
            
        

Le R-carré de notre modèle est proche de 1, ce qui signifie que c'est un très bon modèle.

Notez que si un modèle est bon pour certaines données, cela ne veut pas dire qu'il convient à tous les cas d'utilisation. L'exemple de ce post est un exemple très simple.
Récapituler:
En régression linéaire simple, nous prédisons la valeur d'une variable Y en fonction d'une autre variable X. X est appelée variable indépendante et Y est appelée variable dépendante.
Pourquoi appelons-nous cela simple? Nous appelons cela simple parce qu'il examine la relation entre deux variables uniquement.
Pourquoi l'appelons-nous linéaire? nous l'appelons linéaire car lorsque la variable indépendante augmente ou diminue, la variable dépendante augmente ou diminue de manière linéaire.
L'idée est de tracer une ligne droite qui représente le mieux les points de données.

Références

  • [1] Aurélien Géron - Hands-On Machine Learning with Scikit-Learn and TensorFlow.
  • Lazy programmer - https://deeplearningcourses.com