diff --git a/rapport/rapport.md b/rapport/rapport.md index 9ac3934f3fc4809c445e9cf9bf3e9a93367d186f..c98b7e391fd9662ec6b2c0eb755ff3f4b53265ef 100644 --- a/rapport/rapport.md +++ b/rapport/rapport.md @@ -1,17 +1,26 @@ +<div align="right"> Debray Julien </div> +<div align="right"> Faroukou Samir </div> + # <div align="center"> Rapport travail pratique - Optimisation</div> ## I. Introduction +<div style="text-align: justify"> Dans le cadre du cours de Mathématiques en Technologies de l'Information, nous avons implémenté en C une méthode d'optimisation de régression linéaire. La régression linéaire consiste à minimiser un coût et donc à trouver la solution optimale pour un certain nombre d'objet. Pour ce faire, nous avions d'abord comme objectif de trouver une solution littérale, puis d'implémenter la descente de gradient. Enfin, pour tester notre code, nous avons comparé nos résultats analytiques et numériques puis avons utilisé une méthode de validation. Nous verrons donc la théorie nécessaire ainsi que l'implémentation en elle-même suivie de nos résultats. +</div> ## II. Partie théorique +<div style="text-align: justify"> Plusieurs formules et équations à résoudre étaient nécessaires pour la réalisation de ce travail. +</div> ### Solution analytique - Fonction de coût : $\sum_{i=1}^{N} (ax_i + b - y_i)^2$ - Minimisation du coût : $\vec{\nabla}E(a, b) = \vec{0}$ +<div style="text-align: justify"> En dérivant la fonction du coût selon $a$ puis $b$, nous avons obtenu la minimisation du coût en 2 équations : +</div> $\vec{\nabla}E(a, b) =$ $\begin{cases} a\sum{x_i} + Nb - \sum{y_i} = 0 \\ a\sum{x_i} + b\sum{x_i} - \sum{x_i y_i} = 0 \end{cases}$ @@ -24,42 +33,54 @@ $\Leftrightarrow \begin{cases} b = \frac{\sum{y_i} - a\sum{x_i}}{N}\\ a(N\sum{x_ $\Leftrightarrow \begin{cases} b = \frac{\sum{y_i} - a\sum{x_i}}{N}\\ a = \frac{N\sum{x_i y_i} - \sum{x_i}\sum{y_i}}{N\sum{x_i^2}-\sum{x_i}^2} \end{cases}$ ### Solution numérique +<div style="text-align: justify"> Nous nous sommes servis, pour l'implémentation, de la méthode la descente de gradient d'après la formule suivante : +</div> - $\binom{a_{i+1}}{b_{i+1}} = \binom{a_i}{b_i} - \lambda\vec{\nabla}E(a_i, b_i)$ avec $\lambda , a_0, b_0 \in [0;1]$ et $i >= 0$ +<div style="text-align: justify"> Nous avons travaillé avec des valeurs $\in [0;1]$ afin de ne pas avoir trop de différence d'ordre de grandeur après quelques itérations. +</div> ## II. Implémentation et résultats ### Solution analytique +<div style="text-align: justify"> Nous avons testé notre solution littérale avec les points $A(0, 1)$ et $B(2, 0)$. Nous avons bien trouvé $y = ax + b$ avec $a = -\frac{1}{2}$ et $b = 1$. - +</div> <img src="sol_analytique.png" align=center> ### Solution numérique +<div style="text-align: justify"> Nous prendrons $c = 0.66$ et $d = 0.24$ pour tous les tests suivants sauf si précisé.$\\$ Implémentation du nuage de points : - Afin que la phase de test soit plus simple, nous avons créé le nuage de points de sorte à ce qu'il suive une droite de référence prédéfinie par l'utilisateur. Cette droite est définie par $y = cx + d$. Afin d'avoir des points autour de cette droite, nous faisons apparaître les points d'après l'équation suivante : $\\$ $y_j = c * x_j + d + r_j$ avec $x_j\in [0;1]$ et $r_j < c * x_j + d$ $\\$ -Après l'implémentation, nous avons testé la création d'un nuage de 30 points, nous avons le résultat suivant pour $c = 0.66$ et $d = 0.24$ : <img src="nuage_1.png"> D'après le visuel, nous avons anticipé un problème : les points sont tous situés au dessus de la droite de référence, ce qui fait que la droite résultant de notre programme aura forcément une ordonnée à l'origine supérieure à celle de la droite de référence. Pour remédier à cela, nous avons défini que $r_j$ serait négatif pour la moitié des points. Cela donne le résultat suivant : <img src="nuage_2.png"> Cette fois-ci, les points sont bien répartis de part et d'autres de la droite. $\\$ +Après l'implémentation, nous avons testé la création d'un nuage de 30 points, nous avons le résultat suivant pour $c = 0.66$ et $d = 0.24$ : +<img src="nuage_1.png"> D'après le visuel, nous avons anticipé un problème : les points sont tous situés au dessus de la droite de référence, ce qui fait que la droite résultant de notre programme aura forcément une ordonnée à l'origine supérieure à celle de la droite de référence. Pour remédier à cela, nous avons défini que $r_j$ serait négatif pour la moitié des points. Cela donne le résultat suivant : +<img src="nuage_2.png"> Cette fois-ci, les points sont bien répartis de part et d'autres de la droite. $\\$ Implémentation du calcul de l'erreur : - Pour rappel, cette équation permet de savoir si la droite donnée par un couple $a$ et $b$ est optimale par rapport au nuage de points. Le but est alors d'obtenir un résultat qui tend vers 0 et donc d'avoir la droite correspondante. Afin de simplifier le travail, nous avons utilisé les 2 points $A$ et $B$ de la partie analytique pour tester notre code au cours du développement. En effet, le couple $a = -\frac{1}{2}$ et $b = 1$ correspond à la droite optimale étant donnée qu'elle passe par $A$ et $B$. La fonction retourne bien une erreur de 0 pour ces paramètres. Implémentation de la descente de gradient : -- Nous avons eu quelques difficultés lors de l'implémentation de cette fonction. L'algorithme à utiliser étant en soit assez simple, la difficulté se situait dans les valeurs de $\lambda$ et de $a_0$ et $b_0$. En effet, les valeurs calculées devenaient très vite très grandes jusqu'à ce que le programme retourne *inf* ou *nan*. C'est à ce moment-là que nous avons décidé de travailler dans un domaine restreint (valeurs comprises entre 0 et 1). Après la résolution de ce problème, nous avons testé notre solution pour un nuage de 30 points : <img src="desc_grad_1.png"> La droite résultante est assez proche de la droite de référence mais pas exactement ($a = 0.70$ et $b = 0.22$). Nous avons effectué le test 10 fois et avons obtenu en moyenne $a = 0.68$ et $b = 0.21$, ce qui n'est pas trop mal mais pas parfait. Nous avons alors émis deux hypothèses : +- Nous avons eu quelques difficultés lors de l'implémentation de cette fonction. L'algorithme à utiliser étant en soit assez simple, la difficulté se situait dans les valeurs de $\lambda$ et de $a_0$ et $b_0$. En effet, les valeurs calculées devenaient très vite très grandes jusqu'à ce que le programme retourne *inf* ou *nan*. C'est à ce moment-là que nous avons décidé de travailler dans un domaine restreint (valeurs comprises entre 0 et 1). Après la résolution de ce problème, nous avons testé notre solution pour un nuage de 30 points : +- <img src="desc_grad_1.png"> La droite résultante est assez proche de la droite de référence mais pas exactement ($a = 0.70$ et $b = 0.22$). Nous avons effectué le test 10 fois et avons obtenu en moyenne $a = 0.68$ et $b = 0.21$, ce qui n'est pas trop mal mais pas parfait. Nous avons alors émis deux hypothèses : - Il y a peu de points, ce qui diminuerait la précision du calcul. - $r_j$ calculé pour la génération des points est trop grand ce qui fait que les points sont trop éloignés de la droite de référence. - Nous avons donc effectué d'autres tests en modifiant le nombre de points :<img src="tableau_1.png"> + Nous avons donc effectué d'autres tests en modifiant le nombre de points : + <img src="tableau_1.png"> Notre première hypothèse s'avère donc juste : plus il y a de points, plus le résultat sera précis. -Nous avons ensuite essayé de diminuer la valeur de $r_j$ ($r_j$ est **Diminution** fois plus petit que $c * x_j + d$) :<img src="tableau_2.png"> +Nous avons ensuite essayé de diminuer la valeur de $r_j$ ($r_j$ est **Diminution** fois plus petit que $c * x_j + d$) : +<img src="tableau_2.png"> L'hypothèse est également validée, cependant nous avons décidé de laisser le code comme il était car $c * x_j$ tend vers 0, donc si $r_j$ tend aussi vers 0, on aurait $y_j = d$. -Voici donc un visuel du résultat pour un nuage de 300 points :<img src="desc_grad_2.png"> +Voici donc un visuel du résultat pour un nuage de 300 points : +<img src="desc_grad_2.png"> On voit bien ici que la droite suit la droite de référence avec une marge d'erreur quasiment nulle, mais pas totalement : cela nous amène à l'étape suivante. Vérification des résultats par la méthode de la validation croisée : @@ -69,9 +90,11 @@ Vérification des résultats par la méthode de la validation croisée : Nous avons exploré une troisième manière de vérifier notre implémentation : il s'agit de la validation croisée qui est un moyen automatique de vérifier nos résultats. La méthode consiste à vérifier la persistance de nos résultats en ajoutant de nouveaux points. Dans le cas de notre travail, nous avons simplfier la méthode en divisant nos points en 3 groupes distincts : deux groupes sont utilisés pour entraîner notre modèle (c'est à dire trouver le couple $a$ et $b$) puis le troisième est utilisé pour tester le couple trouvé. - Pour le test précédent, nous avons eu le résultat suivant :<img src="tableau_3.png"> + Pour le test précédent, nous avons eu le résultat suivant : + <img src="tableau_3.png"> On peut voir que $E(a, b)$ tend vers 0, ce qui signifie que l'erreur est très basse. Elle n'est pas nulle malgré tout, nous avons alors repensé aux précédentes hypothèses émises qui peuvent être factrices du manque de précision. Cela peut également venir de la précision des *float* en informatique. Enfin, nous sommes globalement satisfaits des résultats obtenus par nos tests. ## Conclusion - Pour ce travail, nous avons d'abord résolu des équations littérales avant ~~de s'arracher les cheveux~~ d'implémenter une solution en plusieurs étapes afin de répondre à la problématique de la régression linéaire. Nous avons trouvé ce TP très intéressant et assez amusant à réaliser. Nous n'étions pas très confiants au départ mais sommes finalement contents du travail réalisé et des résultats obtenus. De plus, c'est toujours enrichissant d'apprendre comme informatiser un processus mathématiques. \ No newline at end of file + Pour ce travail, nous avons d'abord résolu des équations littérales avant ~~de s'arracher les cheveux~~ d'implémenter une solution en plusieurs étapes afin de répondre à la problématique de la régression linéaire. Nous avons trouvé ce TP très intéressant et assez amusant à réaliser. Nous n'étions pas très confiants au départ mais sommes finalement contents du travail réalisé et des résultats obtenus. De plus, c'est toujours enrichissant d'apprendre comment informatiser un processus mathématiques. +</div> \ No newline at end of file diff --git a/rapport/rapport.pdf b/rapport/rapport.pdf index d3dc4a329fcd9d6acff1088878ac1115f439c060..c93b3084a9b5a89d7a5a33ee5dad5408b07dd5ce 100644 Binary files a/rapport/rapport.pdf and b/rapport/rapport.pdf differ