Introduction
La régression linéaire, bien qu’à première vue simple, est l’une des techniques de Machine Learning les plus importantes dans notre société. En effet, on l’utilise pour prédire n’importe quelles valeurs quantitatives continues, le but de cette dernière est de tracer une droite généralisant l’information de notre jeu de données, c’est-à-dire, qui minimise la distance entre les points du jeu de données et la droite de régression.
[Graphique à faire du même type que celui de Gyukkayle]
Les deux méthodes utilisées pour optimiser les algorithmes de régressions linéaires sont :
- Les équations normales, que nous avons vu dans cet article
- La méthode de descente de gradient.
Bien que ces deux méthodes soient liées par développement mathématique, chacune d’entre elles présentent ses avantages et ses inconvénients. En effet, bien que l’équation normale soit la méthode la plus implémentée dans les algorithmes de régressions linéaires (LinearRegression de sklearn par exemple, …), la principale faiblesse de cette dernière réside sur le nombre de features.
En effet, les équations normales sont efficaces si le nombre de variables n’est pas importante. L’alternative réside donc dans la méthode de descente de gradient.
Principe de la régression par descente de gradient
La descente de gradient est un algorithme d’optimisation cherchant à minimiser une fonction de coût de façon itérative. Elle requiert l’évaluation des dérivées de la fonction de coût en fonction des paramètres du modèle. C’est-à-dire que nous allons étudier la pente de la fonction en fonction des paramètres associés aux variables de notre jeu de données.
D’un point de vue illustratif, voici le fonctionnement :
Nous ne rentrerons pas dans les détails de la descente de gradient dans cet article, toutefois, si vous souhaitez approfondir vos connaissances sur la descente de gradient. Je vous invite à consulter l’article dédié au sujet.
Tout ce que nous avons besoin de savoir sont ces formules :
- Fonction de coût :
MSE=\frac{1}{2m}\sum_{i=1}^m(X\theta-y)^2 - Gradient de la fonction de coût :
\frac{\partial MSE}{\partial \theta}=\frac{1}{m}*X^T(X\theta-y) - Mise à jour des paramètres du modèle :
\theta=\theta-\nu * \frac{\partial MSE}{\partial \theta}
Où \nu [\katex] représente le taux d’apprentissage de la descente de gradient (Nous verrons l’utilité de ce paramètre sur l’article dédié à la descente de gradient)
Ces formules sont au cœur de l’algorithme de descente de gradient.
Implémentation en python
Commençons par le calcul de la fonction de coût :
[code lang="python"]
def Calcul_MSE(X, theta, y):
# Récupération du nombre de lignes
len_x = X.shape[0]
# Calcul du fonction de coût
cout = (1/(2*len_x)) * np.sum((X.dot(theta) - y) ** 2)
return cout
[/code]
Cette fonction prend en paramètres :
- La matrice de variables d’entrées (X)
- Le vecteur de paramètres du modèle (\theta)
- Le vecteur de la variable cible (y)
La fonction retournera l’erreur quadratique moyenne du modèle.
Nous passons à l’implémentation du calcul du gradient, dans le même style que le calcul de la MSE :
[code lang="python"]
def CalculGradients(X, theta, y):
len_x = X.shape[0]
# Calcul du vecteur de gradients
Gradients = (1/len_x) * X.T.dot((X.dot(theta)) - y)
return Gradients
[/code]
La seule différence ici est que la fonction ne sortira pas de nombre, mais un vecteur. Le vecteur des gradients des paramètres du modèle.
Et enfin, la mise à jour des paramètres :
[code lang="python"]
def MAJ_Parameters(theta, gradients, learning_rate):
# Mise à jour des paramètres du modèle
theta = theta - learning_rate * gradients
return theta
[/code]
Cette fonction prend en paramètres :
- Le vecteur de paramètres du modèle (theta)
- Le vecteur gradient de la fonction précédente.
- Le taux d’apprentissage de la descente de gradient.
Elle sortira un nouveau vecteur de paramètres, de même dimension que le theta d’entrée, il s’agira du vecteur de paramètres « amélioré ».
A présent, nous allons initialiser quelques paramètres importants pour le modèle, à savoir :
- Le taux d’apprentissage du modèle.
- Le nombre d’itérations maximale de notre descente de gradient.
- Le vecteur de paramètres de départ du modèle.
[code lang="python"]
# Taux d'apprentissage du modèle
learning_rate = 0.1
# Nombre d'itérations maximale de la descente de gradient
epochs = 1000
# Vecteur de paramètres de même dimension que le nombre de variables.
theta = np.repeat(0, X.shape[1])
# Indicateur d'itération dans le modèle
it = 0
[/code]
Enfin, nous allons itérer sur les epochs du modèle en calculant le gradient des paramètres et en mettant à jour ces derniers afin de minimiser l’erreur quadratique :
[code lang="python"]
for i in range(epochs):
# Calcul du coût avec les paramètres de départ
old_MSE = Calcul_MSE(X, theta, y)
# Calcul du gradient des paramètres theta
Gradients = CalculGradients(X, theta, y)
# Mise à jour des paramètres theta
theta = MAJ_Parameters(theta, Gradients, learning_rate)
# Calcul du coût avec les paramètres mise à jour par la descente de gradient
new_MSE = Calcul_MSE(X, theta, y)
# Affichage de l'évolution du modèle
print(f'Itération : {it}, MSE : {new_MSE}')
print(f'Paramètres : {theta} \n')
# Arrêt de la boucle for si convergence de l'erreur quadratique moyenne.
if np.abs(old_MSE - new_MSE) < 10e-10:
print(f"Convergence du modèle atteint à l'itération : {it}, MSE du modèle : {np.round(new_MSE, 3)}")
break
else:
it += 1
continue
[/code]
Ainsi, nous obtenons les résultats suivants :
[code lang="python"]
Itération : 0, MSE : 24.199724519627907
Paramètres : [0.18840183 0.49522567]
Itération : 1, MSE : 21.9794810485345
Paramètres : [0.3530282 0.94838514]
Itération : 2, MSE : 20.139059494361593
Paramètres : [0.49667587 1.36312911]
…
Itération : 132, MSE : 10.946195394349768
Paramètres : [1.29171984 5.94370138]
Convergence du modèle atteint à l'itération : 132, MSE du modèle : 10.946
[/code]
<--Insérer la vidéo-->
Un arrêt de la boucle a aussi été implémenté afin d’arrêter les itérations lorsqu’il y a convergence de l’erreur quadratique moyenne. Nous avons donc l’équation linéaire : 5.944x + 1.292
Toutefois, scikit-learn dispose déjà d’une implémentation d’optimisation de régression linéaire par descente de gradient. Cette fonction est « SGDRegressor » du module linear_model :
[code lang="python"]
from sklearn.linear_model import SGDRegressor
LR_GD = SGDRegressor(loss = 'squared_error', eta0 = 0.1, learning_rate = 'constant')
LR_GD.fit(X, y)
LR_GD.coef_
array([1.13601847, 5.12979387])
[/code]
Nous obtenons donc des paramètres similaire à l’algorithme que nous avons implémenté.
j’ai commencé et j’en suis devenus acros mercis infiniment.J’avais fais se cours mais sans bien le comprendre mais grace a vous je me suis encore mieux ameliorer
Merci beaucoup Stéphane. Je suis heureux d’apprendre que le contenu vous aide !
j’aimerai avoir votre livre si c’est encore posible
Le livre est maintenant disponible. Bonne lecture et merci beaucoup.
Bonjour Guillaume Saint-Cirgue
mercis infiniment grâce a vous je me suis aprende ML encore mieux améliorer
je vais développer un programme de ML.
1) comment déterminer les variables (x,y) dataset pour remplir d’une courbe physique (exemple photovoltaïque I-V ou
P-V)) et extraire le point maximal?
2)j’aimerai avoir un tutoriel comment utilise big data en python?
Bonjour et merci beaucoup.
1) je vous invite a rejoindre notre serveur Discord ou beaucoup de data Scientists pourront vous aider
2) votre demande est bien enregistrée merci ! 🙂
chère Guillaume tout ça passe bien sauf la dernière étape : je change le learning_rate=0.01 mais le modèle ne converge pas
Bonjour, je vous invite a rejoindre notre serveur discord pour que nous puissions vous aider a résoudre ce problème tous ensemble ! (le lien est sur ma chaine youtube)
un très bon cours de machine learning bravo
Merci beaucoup
comment puis je avoir le livre?
Il est disponible depuis la page d’accueil du site
j’aimerai bien avoir votre livre si c’est encore posible
Bonjour
est ce que le vecteur Y peut être une matrice de m lignes et n colonnes ?
si oui comment je peut faire une formulation correcte , parce le produit du matrice X avec le veceur des parametres = m
c’est a dire que Y est de m lignes et un 1colone
Y peut en effet avoir plus d’une colonne, je conseille d’utiliser une autre lettre que “n” pour les décrire.
merci beaucoup pour votre aide,j’ai un projet sur la prédiction de prix d’appartement mais je ne sais pas encore comment intégrer tout ces codes dans mon application pour prédire le prix a la fin
Je vais bientôt faire des projets sur l’immobilier, cela répondra a vos questions 🙂