Mis à jour le 14/05/2018
  • 10 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

TP : Décomposez l'apprentissage d'une régression linéaire

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

La régression linéaire est un premier exemple simple de la manière dont un algorithme peut apprendre un modèle. Pour sauter le pas, je vous propose maintenant de l’étudier dans un contexte pratique, donc à vos claviers !

Définir sa problématique et ses données d'entraînement

Reprenons notre problématique des loyers abordée dans le premier chapitre de ce cours. La question qu'on essaie de résoudre est :

Étant donné les caractéristique de mon appartement, combien devrais-je normalement payer mon loyer?

Imaginons pour l'instant que la seule caractéristique dont nous disposons est la surface de l'appartement. Notre training set est un ensemble de N = 545 observations de surface et leur loyer associé :  $\((x, y) = (\text{surface}, \text{loyer})\)$ 

Vous pouvez télécharger ce training set ici

Commençons par charger et afficher les données d'entraînement, juste pour avoir une meilleure idée de ce à quoi on a affaire :

# On importe les librairies dont on aura besoin pour ce tp
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# On charge le dataset
house_data = pd.read_csv('house.csv')

# On affiche le nuage de points dont on dispose
plt.plot(house_data['surface'], house_data['loyer'], 'ro', markersize=4)
plt.show()

Clairement d'après la visualisation, on peut se dire que le montant du loyer dépend de manière linéaire de la surface du logement. On peut donc émettre une hypothèse de modélisation qui est que le phénomène possède la forme d'une droite. 

Reformuler le problème dans l'espace d’hypothèse : une droite

La régression linéaire s’appuie sur l’hypothèse que les données proviennent d’un phénomène qui à la forme d'une droite, c’est à dire qu’il existe une relation linéaire entre l’entrée (les observations) et la sortie (les prédictions).

Nous avons donc notre contrainte de modèle sous-jacent qui doit être sous la forme $\(\hat{y} = \theta^T x\)$  avec  $\(x = (1, x_1, x_2, x_3, ..., x_N), \hat{y} = (\hat{y_1}, \hat{y_2}, \hat{y_3}, ..., \hat{y_N})\)$ 

Dans notre cas, puisqu’on est en une dimension, on peut écrire pour un point $\(x_i\)$$\(\hat{y_i} = \theta_0 + \theta_1 \times x_i\)$  

Notre objectif est donc de trouver la droite paramétrée par $\(\theta = (\theta_0, \theta_1)\)$ qui fitte le mieux aux données d’entraînement.

Définir la fonction loss

Pour effectuer une régression linéaire, on doit ensuite choisir une fonction de perte dont on a parlé dans le chapitre précédent. On ne va pas prendre de risque, on va prendre la distance euclidienne. 😉

La distance euclidienne d'une observation $\(y\)$ vis à vis de notre modèle $\(\hat{y}\)$ est :

$\(\vert\vert \hat{y} - y \vert\vert_2 = \vert\vert \theta^T x - y \vert\vert_2\)$

Le risque empirique dont on parlait dans le chapitre précédent est donc : 

 $\(E = \sum_{i=1}^N \vert\vert \theta^T x_i - y_i \vert\vert\)$  

Et on va donc chercher à trouver le $\(\theta\)$ qui minimise cette fonction de perte (qu’on note E)

$\(\hat{\theta} = \text{argmin}_{\theta} E\)$

Apprentissage : trouver le $\(\theta\)$ optimal

Pour la régression linéaire, la solution de l'équation de minimisation (juste au dessus) est exacte :

  $\(\hat{\theta} = (X^TX)^{-1}X^Ty\)$  

Pourtant tu parlais dans le chapitre précédent d'algorithme itératif qui convergeait vers une solution non ? Là on a une solution exacte directement en fait ?

Alors en l’occurence on a de la chance. 😅 Il existe bien une solution exacte dans ce cas précis, qu’on vient de donner. Mais on peut aussi utiliser un algorithme appelé descente de gradient pour trouver une approximation de la solution. C'est en particulier utile lorsqu'on a beaucoup de données d'exemples, car c'est assez long pour un ordinateur de calculer la solution exacte ci-dessus (on calcule un inverse de matrice, ce qui n'est pas gratuit en temps de calcul !).

Bon en tout cas, on peut maintenant calculer les paramètres directement :

# On décompose le dataset et on le transforme en matrices pour pouvoir effectuer notre calcul
X = np.matrix([np.ones(house_data.shape[0]), house_data['surface'].as_matrix()]).T
y = np.matrix(house_data['loyer']).T

# On effectue le calcul exact du paramètre theta
theta = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)

print(theta)

On trouve donc la valeur numérique de $\(\theta\)$ pour nos données :

[[ 294.30011913]
 [ 30.04180999]]

Notre modèle final qui fitte les données sera donc dans notre cas (approximativement) :

$\(\text{loyer} = 30 \times \text{surface} + 294.3\)$

On peut représenter graphiquement la droite qu'on a trouvée pour vérifier qu'elle colle bien aux données :

plt.xlabel('Surface')
plt.ylabel('Loyer')

plt.plot(house_data['surface'], house_data['loyer'], 'ro', markersize=4)

# On affiche la droite entre 0 et 250
plt.plot([0,250], [theta.item(0),theta.item(0) + 250 * theta.item(1)], linestyle='--', c='#000000')

plt.show()

Utiliser le modèle pour effectuer des prédictions

Maintenant qu’on a notre paramètre $\(\theta\)$, c’est à dire qu’on a trouvé la droite qui fitte le mieux nos données d’entraînement, on peut effectuer des prédictions sur de nouvelles données, c’est à dire prédire le loyer en fonction de la surface qu’on nous donne en entrée, en appliquant directement la formule du modèle dessus :

Par exemple, si on l’applique pour une surface de 35m carré :

theta.item(0) + theta.item(1) * 35

On obtient une estimation du loyer

1345.7634688270678

Essayez avec n'importe quelle surface !

Aller plus loin : le “vrai” travail de modélisation

Maintenant qu’on a trouvé un premier modèle, il serait possible de tester plein d’hypothèses différentes pour aller plus loin et améliorer ses performances.

Que se passe-t-il si : 

  • on change l’hypothèse de linéarité (une droite) et qu’on en prend une autre (un polynôme du second degré par exemple) ?

  • on teste le modèle avec d’autres types d’erreurs que la distance euclidienne ?

  • on ajoute des features (dimensions) supplémentaires en entrée ?

  • au fur et à mesure que  la surface augmente, les données on l'air d'être de plus en plus "éparses", comment intégrer ce comportement dans ma modélisation ?

Toutes ces questions peuvent (et devraient !) être testées. Trouver la configuration la plus pertinente revient du coup à tester les différents modèles (régression linéaire ou non-linéaires, dimensions différentes, et tous les autres algorithmes que l'on verra par la suite) qui en découlent et trouver celui qui convient le mieux en terme de performances...

En résumé

  • À partir d'une problématique et d'un dataset, nous avons considéré une hypothèse de travail pour contraindre le modèle : ici nous nous sommes placés dans le cas d'une régression linéaire, qui correspond à contraindre la forme du modèle à une droite.

  • Nous avons décomposé l'entraînement de ce modèle sur les observations, afin de déterminer le paramètre (pente et ordonnée à l'origine) de la droite optimale pour ces données. C'est cette partie que l'on appelle apprentissage du modèle.

  • À l'aide du modèle ainsi trouvé, nous pouvons maintenant effectuer des prédictions de montant de loyer à partir de n'importe quelle surface donnée.

  • On peut toujours améliorer ce modèle (une fois qu'on saura évaluer ses performances) en testant par exemple d'autres hypothèses, en ajoutant de nouvelles caractéristiques sur les observations ou en testant d'autres types de loss qui seront peut-être plus appropriés pour ce cas... Le travail du data scientist ne s'arrête pas là !

Exemple de certificat de réussite
Exemple de certificat de réussite