From d6ed4772f334d1d8919e9c3c3054139ebdf1183e Mon Sep 17 00:00:00 2001 From: "alexandr.benzonan" <alexandre.benzonana@etu.hesge.ch> Date: Sun, 12 Dec 2021 21:15:09 +0100 Subject: [PATCH] modification readme --- README.md | 197 ++++++++++++++++++++++++++++++++++++++++- TP01 - Optimisation.md | 196 ---------------------------------------- 2 files changed, 195 insertions(+), 198 deletions(-) delete mode 100644 TP01 - Optimisation.md diff --git a/README.md b/README.md index efe6f87..7915cea 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,196 @@ -# TP Optimisation +# TP01 - Optimisation -TP de Math \ No newline at end of file +Alexandre Benzonana & Kelly Nguyen + +--- +# Table des matières +- [Introduction](#introduction) +- [Explication mathématique](#Explication_mathématique) + - [Solution Analytique](#Solution_Analytique) + - [Solution Numérique](#Solution_Numérique) + - [Partie Test](#Partie_Test) + - [Cross Validation](#Cross_Validation) + - [Calculs d'erreurs](#Calculs_d'erreurs) +- [Résultats](#Résultats) +- [Conclusion](#Conclusion) +--- + +# Introduction + +Nous avons réalisé un programme permettant de faire une régression linéaire grâce aux théorèmes que nous avons vu durant le cours de math. Les calculs ont été réalisés en C et l'affichage en python à l'aide de la librairie matplotlib et numpy. + +Pour la structure de notre rapport, nous avons divisé les explications mathématique en plusieurs sous chapitres pour pouvoir expliquer en détails notre raisonnement. + +Pour la partie analytique, nous expliquons comment nous avons trouvé les équations permettant de faire la descente de gradient. Pour la solution numérique, nous expliquons comment sont utilisés les équations trouvées dans la partie précédente. + +La partie test explique comment nous avons testé nos différents résultats pour terrifier leur cohérence. + +La partie cross validation explique comment nous avons vérifié que notre code nous rendait bien le résultat attendu. + +Pour finir, nous montrons les différents résultats que nous avons pu obtenir en faisant des régressions linéaires. + +# Explication mathématique + +## Solution Analytique + +Pour faire la régression linéaire, nous avons d'abord dérivé l'équation puis isolé a et b a partir de la dérivée: + +$$E(a, b) = \sum^N_{j=1} (a \cdot x_j + b - y_j)^2 \tag{1}$$ + +$$a=\frac{-b \cdot \displaystyle\sum^N_{j=1} x_j + \sum^N_{j=1} x_j \cdot y_j}{\displaystyle\sum^N_{j=1} x^2_j} \tag{2}$$ + +$$b = -\frac{a\cdot \displaystyle\sum^N_{j=1} x_j - \sum^N_{j=1} y_j}{N} \tag{3}$$ + +Puis, nous avons remplacé a et b dans les équations pour les isoler. + +$$a = \frac +{\displaystyle\sum^N_{j=1} x_j \cdot y_j} +{\displaystyle\sum^N_{j=1} x^2_j} \tag{4}$$ + +$$b = \frac{ +\left(\displaystyle\sum^N_{j=1} x_j - \sum^N_{j=1} y_j +\right) +\cdot +\left(\displaystyle\sum^N_{j=1}x_j \cdot \sum^N_{j=1}y_j + N \cdot \sum^N_{j=1}x_j \cdot y_j +\right)} +{N \cdot \displaystyle\sum^N_{j=1}x^2_j + \left +(\sum^N_{j=1}x_j\right)^2} + +\tag{5}$$ + +## Solution Numérique + +À partir des formules trouvées (formule 2 et 3), nous avons implémenté la descente de gradient. Nous choisissons un a et b de départ aléatoirement puis utilisons cette formule pour nous rapprocher le plus possible du vrai a et b : + +$$\begin{pmatrix} +a_i + 1 \\ +b_i + 1 +\end{pmatrix} = +\begin{pmatrix} +a_i \\ +b_i +\end{pmatrix} - \lambda \cdot \vec \nabla E(a_i, b_i) \tag{6}$$ + +$$i \ge 0 \text{ et } \lambda \in [0, 1]$$ + +Les itérations se finissent lorsque : + +$$\begin{Vmatrix} +\begin{pmatrix} +a_i + 1 \\ +b_i + 1 +\end{pmatrix} +- +\begin{pmatrix} +a_i\\ +b_i +\end{pmatrix} +\end{Vmatrix} +< \epsilon +$$ + +avec la précision d'un $\epsilon$ que l'on souhaite qui est inférieur à 0. +Nous avons choisis $\epsilon = 1*10^{-8}$ + +## Partie de Test + +Pour tester nos formules de la solution analytique, nous avons choisi des points alignés avec une pente de 1 et avons simplement calculé a et b en fonction de ces points avec nos formules. + +Pour pouvoir tester notre programme, nous avons commencé par entrer les même données que lors du test de la partie analytique pour les comparer puis nous avons créée un nuage de points ($x_j$, $y_j$) qui se trouve autour d'une droite dont la pente est de *c* et l'ordonnée à l'origine *d*. Les valeurs $x_j$ sont entre deux bornes que nous avons choisi. À partir du $x_j$ on calcule le $y_j$. + +$$y_j = c \cdot x_j + d + r_j \tag{7}$$ + +$$r_j \text{ est une valeur aléatoire petite.}\\ +\text{(nous avons pris entre 0 et 0.1)}$$ + +A cause d'un manque de précision, nous sommes contraints d'avoir : + +$x_j \in$ [0, 1] + +c, d $\in$ [0, 1] + +## Cross validation + +Une fois le code implémenté, il faut maintenant vérifier si les valeurs de a et b restent cohérents après avoir ajouté des points. Mais pour simplifier cette validation, nous avons fait 3 groupes de points qui sont de la même taille. Nous prenons ensuite 2 parties pour entrainer le modèle et un partie pour le vérifier et répétons cette opération avec les différentes combinaisons possibles : + +- trouver a et b avec les groupes G1 $\cup$ G2 et tester sur G3 +- trouver a et b avec les groupes G1 $\cup$ G3 et tester sur G2 +- trouver a et b avec les groupes G2 $\cup$ G3 et tester sur G1 + +### Calculs d'erreurs + +#### Test 1 (300 points, 100 par groupes) + +| / | G1 U G2 | G3 | Erreur | +| --- | --- | --- | --- | +| Pente | 0.497449 | 0.545689 | 0.04824 | +| Ordonnée à l'origine | 0.987339 | 0.984916 | 0.002423 | + +| / | G1 U G2 | G3 | Erreur | +| --- | --- | --- | --- | +| Pente | 0.816814 | 0.807846 | 0.008968 | +| Ordonnée à l'origine | 0.905392 | 0.908249 | 0.002857 | + +| / | G1 U G3 | G2 | Erreur | +| --- | --- | --- | --- | +| Pente | 0.551048 | 0.437933 | 0.113115 | +| Ordonnée à l'origine | 0.974797 | 0.993563 | 0.018766 | + +#### Test 2 (1500 points, 500 par groupes) + +| / | G1 U G3 | G2 | Erreur | +| --- | --- | --- | --- | +| Pente | 0.799613 | 0.82446 | 0.024847 | +| Ordonnée à l'origine | 0.911 | 0.903562 | 0.007438 | + +| / | G2 U G3 | G1 | Erreur | +| --- | --- | --- | --- | +| Pente | 0.493222 | 0.55014 | 0.056918 | +| Ordonnée à l'origine | 0.980026 | 0.967909 | 0.012117 | + +| / | G2 U G3 | G1 | Erreur | +| --- | --- | --- | --- | +| Pente | 0.831619 | 0.815212 | 0.016407 | +| Ordonnée à l'origine | 0.901718 | 0.906601 | 0.004883 | + +Sur un nombre de points faibles l'erreur est assez importante mais plus nous augmentons les points, plus l'erreur diminue. + +# Résultats + +Nous avons commencé par afficher les valeurs a et b dans la console pour les vérifier puis pour afficher nos graphiques nous avons décidé d'utiliser python par soucis de simplicité. Nos données étant calculés en C nous avons du trouver un moyen de les transmettre a python pour ensuite les afficher. Pour ce faire nous avons eu l'idée de les écrire dans un fichier puis lire ce fichier en python. + +Nous pouvons voir que la régression linéaire fonctionne car la ligne se trouve au centre des points. + + + +Résultats + +En choisissant un $r_j$ trop élevé nous nous retrouvons avec une droite presque plate visuellement. Elle ne nous permet donc pas de voir si la régression linéaire est correcte. + + + +Droite avec un $r_j$ trop élevé + +Nous pouvons donc voir que lorsque nous avons une droite dont la pente se rapproche de 0, les points se retrouvent visuellement plus éparpillé. Alors que quand nous avons une grande pente, nous nous retrouvons avec des points qui se trouvent directement sur la droite et non un nuage de points. + + + +Graphique dont la pente est grande et un $r_j$ faible. + + + +Graphique dont tous les valeurs sont normales mais avec peu de points. + + + +Graphique dont la pente est normal et $r_j$ très grand avec un nombre de points faible. + +# Conclusion + +Nous avons pu constater que la régression linéaire ne nous apporte pas une solution exacte mais une approximation qui selon la valeur $\epsilon$ peut-être plus ou moins précise. + +Le nombre de points a également une influence pour la validation des résultats, avec un nombre de points faible les résultats ne seront pas cohérents alors qu'avec un nombre de points important les résultats ont beaucoup plus de sens. + +Si notre droite est générée avec une pente faible, nous nous retrouvons avec un graphique remplis de points et la régression semble approximative tandis qu'avec une pente élevée, les points se retrouvent tous sur la droite. Ceci dépend également du nombre de points du nuage, une pente faible avec peu de points nous donnera les résultats les moins cohérents surtout lors de la validation croisée. + +Le code pourrait-être retravaillé pour le rendre plus propre avec moins de répétitions. diff --git a/TP01 - Optimisation.md b/TP01 - Optimisation.md deleted file mode 100644 index 7915cea..0000000 --- a/TP01 - Optimisation.md +++ /dev/null @@ -1,196 +0,0 @@ -# TP01 - Optimisation - -Alexandre Benzonana & Kelly Nguyen - ---- -# Table des matières -- [Introduction](#introduction) -- [Explication mathématique](#Explication_mathématique) - - [Solution Analytique](#Solution_Analytique) - - [Solution Numérique](#Solution_Numérique) - - [Partie Test](#Partie_Test) - - [Cross Validation](#Cross_Validation) - - [Calculs d'erreurs](#Calculs_d'erreurs) -- [Résultats](#Résultats) -- [Conclusion](#Conclusion) ---- - -# Introduction - -Nous avons réalisé un programme permettant de faire une régression linéaire grâce aux théorèmes que nous avons vu durant le cours de math. Les calculs ont été réalisés en C et l'affichage en python à l'aide de la librairie matplotlib et numpy. - -Pour la structure de notre rapport, nous avons divisé les explications mathématique en plusieurs sous chapitres pour pouvoir expliquer en détails notre raisonnement. - -Pour la partie analytique, nous expliquons comment nous avons trouvé les équations permettant de faire la descente de gradient. Pour la solution numérique, nous expliquons comment sont utilisés les équations trouvées dans la partie précédente. - -La partie test explique comment nous avons testé nos différents résultats pour terrifier leur cohérence. - -La partie cross validation explique comment nous avons vérifié que notre code nous rendait bien le résultat attendu. - -Pour finir, nous montrons les différents résultats que nous avons pu obtenir en faisant des régressions linéaires. - -# Explication mathématique - -## Solution Analytique - -Pour faire la régression linéaire, nous avons d'abord dérivé l'équation puis isolé a et b a partir de la dérivée: - -$$E(a, b) = \sum^N_{j=1} (a \cdot x_j + b - y_j)^2 \tag{1}$$ - -$$a=\frac{-b \cdot \displaystyle\sum^N_{j=1} x_j + \sum^N_{j=1} x_j \cdot y_j}{\displaystyle\sum^N_{j=1} x^2_j} \tag{2}$$ - -$$b = -\frac{a\cdot \displaystyle\sum^N_{j=1} x_j - \sum^N_{j=1} y_j}{N} \tag{3}$$ - -Puis, nous avons remplacé a et b dans les équations pour les isoler. - -$$a = \frac -{\displaystyle\sum^N_{j=1} x_j \cdot y_j} -{\displaystyle\sum^N_{j=1} x^2_j} \tag{4}$$ - -$$b = \frac{ -\left(\displaystyle\sum^N_{j=1} x_j - \sum^N_{j=1} y_j -\right) -\cdot -\left(\displaystyle\sum^N_{j=1}x_j \cdot \sum^N_{j=1}y_j + N \cdot \sum^N_{j=1}x_j \cdot y_j -\right)} -{N \cdot \displaystyle\sum^N_{j=1}x^2_j + \left -(\sum^N_{j=1}x_j\right)^2} - -\tag{5}$$ - -## Solution Numérique - -À partir des formules trouvées (formule 2 et 3), nous avons implémenté la descente de gradient. Nous choisissons un a et b de départ aléatoirement puis utilisons cette formule pour nous rapprocher le plus possible du vrai a et b : - -$$\begin{pmatrix} -a_i + 1 \\ -b_i + 1 -\end{pmatrix} = -\begin{pmatrix} -a_i \\ -b_i -\end{pmatrix} - \lambda \cdot \vec \nabla E(a_i, b_i) \tag{6}$$ - -$$i \ge 0 \text{ et } \lambda \in [0, 1]$$ - -Les itérations se finissent lorsque : - -$$\begin{Vmatrix} -\begin{pmatrix} -a_i + 1 \\ -b_i + 1 -\end{pmatrix} -- -\begin{pmatrix} -a_i\\ -b_i -\end{pmatrix} -\end{Vmatrix} -< \epsilon -$$ - -avec la précision d'un $\epsilon$ que l'on souhaite qui est inférieur à 0. -Nous avons choisis $\epsilon = 1*10^{-8}$ - -## Partie de Test - -Pour tester nos formules de la solution analytique, nous avons choisi des points alignés avec une pente de 1 et avons simplement calculé a et b en fonction de ces points avec nos formules. - -Pour pouvoir tester notre programme, nous avons commencé par entrer les même données que lors du test de la partie analytique pour les comparer puis nous avons créée un nuage de points ($x_j$, $y_j$) qui se trouve autour d'une droite dont la pente est de *c* et l'ordonnée à l'origine *d*. Les valeurs $x_j$ sont entre deux bornes que nous avons choisi. À partir du $x_j$ on calcule le $y_j$. - -$$y_j = c \cdot x_j + d + r_j \tag{7}$$ - -$$r_j \text{ est une valeur aléatoire petite.}\\ -\text{(nous avons pris entre 0 et 0.1)}$$ - -A cause d'un manque de précision, nous sommes contraints d'avoir : - -$x_j \in$ [0, 1] - -c, d $\in$ [0, 1] - -## Cross validation - -Une fois le code implémenté, il faut maintenant vérifier si les valeurs de a et b restent cohérents après avoir ajouté des points. Mais pour simplifier cette validation, nous avons fait 3 groupes de points qui sont de la même taille. Nous prenons ensuite 2 parties pour entrainer le modèle et un partie pour le vérifier et répétons cette opération avec les différentes combinaisons possibles : - -- trouver a et b avec les groupes G1 $\cup$ G2 et tester sur G3 -- trouver a et b avec les groupes G1 $\cup$ G3 et tester sur G2 -- trouver a et b avec les groupes G2 $\cup$ G3 et tester sur G1 - -### Calculs d'erreurs - -#### Test 1 (300 points, 100 par groupes) - -| / | G1 U G2 | G3 | Erreur | -| --- | --- | --- | --- | -| Pente | 0.497449 | 0.545689 | 0.04824 | -| Ordonnée à l'origine | 0.987339 | 0.984916 | 0.002423 | - -| / | G1 U G2 | G3 | Erreur | -| --- | --- | --- | --- | -| Pente | 0.816814 | 0.807846 | 0.008968 | -| Ordonnée à l'origine | 0.905392 | 0.908249 | 0.002857 | - -| / | G1 U G3 | G2 | Erreur | -| --- | --- | --- | --- | -| Pente | 0.551048 | 0.437933 | 0.113115 | -| Ordonnée à l'origine | 0.974797 | 0.993563 | 0.018766 | - -#### Test 2 (1500 points, 500 par groupes) - -| / | G1 U G3 | G2 | Erreur | -| --- | --- | --- | --- | -| Pente | 0.799613 | 0.82446 | 0.024847 | -| Ordonnée à l'origine | 0.911 | 0.903562 | 0.007438 | - -| / | G2 U G3 | G1 | Erreur | -| --- | --- | --- | --- | -| Pente | 0.493222 | 0.55014 | 0.056918 | -| Ordonnée à l'origine | 0.980026 | 0.967909 | 0.012117 | - -| / | G2 U G3 | G1 | Erreur | -| --- | --- | --- | --- | -| Pente | 0.831619 | 0.815212 | 0.016407 | -| Ordonnée à l'origine | 0.901718 | 0.906601 | 0.004883 | - -Sur un nombre de points faibles l'erreur est assez importante mais plus nous augmentons les points, plus l'erreur diminue. - -# Résultats - -Nous avons commencé par afficher les valeurs a et b dans la console pour les vérifier puis pour afficher nos graphiques nous avons décidé d'utiliser python par soucis de simplicité. Nos données étant calculés en C nous avons du trouver un moyen de les transmettre a python pour ensuite les afficher. Pour ce faire nous avons eu l'idée de les écrire dans un fichier puis lire ce fichier en python. - -Nous pouvons voir que la régression linéaire fonctionne car la ligne se trouve au centre des points. - - - -Résultats - -En choisissant un $r_j$ trop élevé nous nous retrouvons avec une droite presque plate visuellement. Elle ne nous permet donc pas de voir si la régression linéaire est correcte. - - - -Droite avec un $r_j$ trop élevé - -Nous pouvons donc voir que lorsque nous avons une droite dont la pente se rapproche de 0, les points se retrouvent visuellement plus éparpillé. Alors que quand nous avons une grande pente, nous nous retrouvons avec des points qui se trouvent directement sur la droite et non un nuage de points. - - - -Graphique dont la pente est grande et un $r_j$ faible. - - - -Graphique dont tous les valeurs sont normales mais avec peu de points. - - - -Graphique dont la pente est normal et $r_j$ très grand avec un nombre de points faible. - -# Conclusion - -Nous avons pu constater que la régression linéaire ne nous apporte pas une solution exacte mais une approximation qui selon la valeur $\epsilon$ peut-être plus ou moins précise. - -Le nombre de points a également une influence pour la validation des résultats, avec un nombre de points faible les résultats ne seront pas cohérents alors qu'avec un nombre de points important les résultats ont beaucoup plus de sens. - -Si notre droite est générée avec une pente faible, nous nous retrouvons avec un graphique remplis de points et la régression semble approximative tandis qu'avec une pente élevée, les points se retrouvent tous sur la droite. Ceci dépend également du nombre de points du nuage, une pente faible avec peu de points nous donnera les résultats les moins cohérents surtout lors de la validation croisée. - -Le code pourrait-être retravaillé pour le rendre plus propre avec moins de répétitions. -- GitLab