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}$$
\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 :
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
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.
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}$$
\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 :
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
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.