[C++] Régression polynomiale

Régression polynomiale [C++] - C++ - Programmation

Marsh Posté le 10-02-2006 à 00:11:07    

Je dois effectuer une régression polynomiale (degré 2) sur des données, jusque là tout va bien, des dizaines de librairies le proposent.
Mais mon soucis c'est que je veux faire une régression en fixant un des paramètres (la constante), et la je n'ai trouvé aucune librairie...
 
Quelqu'un en connait une?
 
Merci


Message édité par Alprema le 10-02-2006 à 00:11:43
Reply

Marsh Posté le 10-02-2006 à 00:11:07   

Reply

Marsh Posté le 15-02-2006 à 10:34:46    

Si tu cherches à faire une régression aux moindres carrés, il ne devrait pas être très difficile de le faire à la main dans ton cas particulier.
A priori, tu devrais juste te retrouver avec un système 2 x 2 (non linéaire :( ) à résoudre.

Reply

Marsh Posté le 15-02-2006 à 17:07:24    

Tout d'abord merci de m'avoir répondu.
Par contre je dois avouer que je ne comprends pas trop ta réponse...
Déja je ne vois pas comment faire la régression à la main :-/
Et ensuite comment arriver à un système 2 x 2.
Donc si tu pouvais être un peu plus précis, j'apprécierais grandement.
 
Merci !

Reply

Marsh Posté le 15-02-2006 à 18:00:07    

Lorsque tu veux faire une régression sur un ensemble de données (x_i,y_i), tu cherches à minimiser l'ecart entre tes données et une fonction théorique y=f(x)
Dans ton cas, f est une fonction polynomiale de degré 2 :
http://fevotte.free.fr/Downloads/f1.png
 
L'écart entre tes données et la fonction théorique peut être mesuré par le carré des écarts individuels point par point :
http://fevotte.free.fr/Downloads/f2.png
 
Tu cherches en fait à trouver les paramètres 'a' et 'b' (puisque 'c' est constant dans ton cas) qui minimisent cet écart. Or il existe un théorème mathématique qui stipule que pour ces valeurs de paramètres, les dérivées de epsilon sont nulles.
Finalement, tout revient à déterminer le couple (a,b) tel que les dérivées de epsilon sont nulles :
http://fevotte.free.fr/Downloads/f3.png
 
Ceci te donne un système linéaire de deux équations à deux inconnues (a et b) qu'il est très facile de résoudre.
 
Si tu veux, je poste le code correspondant (mais un peu plus tard : là, j'ai pas le temps :) )
 
 
PS: je pense que ce topic est en train de virer du côté de l'algorithmique, et n'est peut-être plus dans la bonne catégorie...

Reply

Marsh Posté le 15-02-2006 à 18:33:34    

Une seconde fois je te remercie.
 
Par contre, je ne suis qu'en BTS et c'est pas vraiment au programme, donc je n'ai jamais bossé sur les regressions de toutes sortes...
Donc en formules ca me parles très moyennement, si jamais tu as du temps à perdre je veux bien un ptit exemple en code (ou en algo, je ne veux pas non plus un truc tout fait, le but est de comprendre, pas de pomper betement).
 
Merci² !
 
PS : Pour le changement de catégorie, tout va dépendre du langage de ta réponse ;)

Reply

Marsh Posté le 16-02-2006 à 14:35:04    

Voila un petit programme qui te permet de faire un test de régression polynomiale.
Un tableau de 1000 données est rempli avec y = 5 x^2 + 3 x + 1 avec une erreur relative sur y de l'ordre de 10%
On fait ensuite une régression polynômiale sur ces données pour trouver 'a' et 'b' (en connaissant déjà la constante 'c' qui vaut 1)
 

Code :
  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <stdlib.h>
  4. #define NB_DATA 1000
  5. #define ERREUR  0.1
  6. int main()
  7. {
  8.   int i;
  9.   double x[NB_DATA], y[NB_DATA]; /* données */
  10.   double M,N,P,Q,R,S; /* coefficients du système linéaire */
  11.   double det_inv;     /* inverse du déterminant du système */
  12.   double a, b;        /* coefficients du polynome */
  13.   double c = 1.;      /* on sait déja que c = 1 */
  14.   /* remplissage des tableaux :
  15.    *   -1 <= x <= 1
  16.    *   y = 5 x^2 + 3 x + 1 + <erreur aléatoire>
  17.    */
  18.   srand(time(NULL));
  19.   for( i=0 ; i<NB_DATA ; ++i )
  20.     {
  21.       x[i]  = (2.*i)/(NB_DATA-1) - 1;
  22.       y[i]  = 5*x[i]*x[i] + 3*x[i] + 1;
  23.       /* erreur relative entre 0 et ERREUR */
  24.       y[i] *= 1-ERREUR+(rand()/(double)RAND_MAX)*2*ERREUR;
  25.     }
  26.   /* REGRESSION */
  27.   /* calcul des coefficients du système linéaire :
  28.    *  
  29.    * M*a + N*b + P = 0
  30.    * Q*a + R*b + S = 0
  31.    */
  32.   M = N = P = Q = R = S = 0;
  33.   for( i=0 ; i<NB_DATA ; ++i )
  34.     {
  35.       double x_square = x[i]*x[i];
  36.       double x_cube   = x_square*x[i];
  37.       M += x_square*x_square;
  38.       N += x_cube;
  39.       P += x_square * (c-y[i]);
  40.       Q += x_cube;
  41.       R += x_square;
  42.       S += x[i] * (c-y[i]);
  43.     }
  44.  
  45.   /* résolution du système : */
  46.   det_inv = 1 / (M*R - N*Q);
  47.   a = det_inv * ( N*S - R*P );
  48.   b = det_inv * ( Q*P - M*S );
  49.   printf( "a = %f\n", a );
  50.   printf( "b = %f\n", b );
  51.   printf( "c = %f\n", c );
  52.   return 0;
  53. }


 
 
exemple d'exécution :

> ./regression
a = 4.998019
b = 2.992004
c = 1.000000

Reply

Marsh Posté le 16-02-2006 à 22:28:52    

MERCIIIIII
 
Décidemment je t'aurais remercié plein de fois... ^^
Je comprends ce que fait le code mais je pèche vraiment coté maths...
Bon, je dois m'absenter quelques jours, mais c'est décidé, à mon retour je me plonge dans un bouquin de math, et je harcèle mon prof de math ^^
Je dois pouvoir comprendre en faisant le rapprochement entre le code et les formules de math.
Et dire que je devrais faire ca en fixant b ET c après.... Faudrais vraiment que mon chef se rappelle que je suis qu'en BTS moi :-/
 
Enfin je te remercie de tes lumières, ton aide m'a été précieuse.

Reply

Marsh Posté le 16-02-2006 à 22:32:14    

en ce qui concerne la regression je ne peux que conseiller un MP a stiffler [:petrus75]

Reply

Marsh Posté le 16-02-2006 à 22:33:23    

Je prends note, je lui en toucherais un mot si je m'en sort pas.
Merci

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed