Accueil > > > RÉGRESSION NON-LINÉAIRE POLYNOMIALE PAR LA MÉTHODE DES MOINDRES CARRÉS
RÉGRESSION NON-LINÉAIRE POLYNOMIALE PAR LA MÉTHODE DES MOINDRES CARRÉS
Information sur la source
Description
N'ayant pas trouvé de code simple traitant la régression non-linéaire par des polynômes, je me suis décidé à la programmer moi-même. Ce code me paraît simple à reprendre. Il suffit d'indiquer les valeurs x et y sur lesquelles porte la régression dans un fichier nommé "valeurs_init.txt". Ce fichier doit être placé dans le même répertoire que le fichier .bas Ensuite, il fait lancer la procédure main. Par défaut le polynôme de tendance est de degré 6, il est possible d'en changer en indiquant le degré voulu lors de l'appel de la procédure régression. Le code génère alors les valeurs x et y = a0 + a1*x + ... + a6*x^6
Source
- Option Explicit
-
- Public x() As Double 'Données d'entrée (xi et yi)
- Public y() As Double
- Public ai_p() As Double 'Valeurs des coefficients du polynôme de tendance
-
-
- Sub main()
- Dim i As Integer, j As Integer
- Dim ligne As String
- Dim virg_deb As Long
- Dim virg_fin As Long
-
- Dim a As String
-
- i = 0
- 'Boucle de récupération des données xi et yi à traiter
- Open "valeurs_init.txt" For Input As #1
- While Not EOF(1)
- i = i + 1
- ReDim Preserve x(1 To i)
- ReDim Preserve y(1 To i)
-
- Line Input #1, ligne
-
- 'Remplacement des blancs par des séparateurs (chr(47) = "/")
- ligne = Replace(ligne, Chr(9), Chr(47))
- ligne = Replace(ligne, Chr(32), Chr(47))
- ligne = Chr(47) & ligne & Chr(47)
-
- 'Récupération des données x(i) et y(i)
- 'Recherche des séparateurs (/) et stockage des valeurs indiquées entre les séparateurs
- virg_deb = InStr(1, ligne, Chr(47))
- virg_fin = InStr((virg_deb + 1), ligne, Chr(47))
- x(i) = CDbl(Mid(ligne, (virg_deb + 1), (virg_fin - virg_deb - 1)))
-
- virg_deb = InStr((virg_fin), ligne, Chr(47))
- virg_fin = InStr((virg_deb + 1), ligne, Chr(47))
- y(i) = CDbl(Mid(ligne, (virg_deb + 1), (virg_fin - virg_deb - 1)))
- Wend
-
- Close #1
-
- 'Appel de la procédure de régression polynômiale :
- 'le premier argument est le degré du polynôme de tendance chosi, x() et y() sont les données à traiter
- 'ai_p() est un argument de retour renvoyant les coef ai du polynôme
- Call regression_polynomiale(6, x(), y(), ai_p())
-
-
- Dim xf() As Double
- Dim yf() As Double
- ReDim xf(1 To UBound(x))
- ReDim yf(1 To UBound(y))
-
- 'Boucle générant un fichier texte contenant les valeurs xf(i) et yf(i) approchées
- Open "valeurs_fin.txt" For Output As #1
- For i = 1 To UBound(x)
- xf(i) = x(i)
- yf(i) = ai_p(0)
- For j = 1 To (UBound(ai_p()))
- yf(i) = yf(i) + ai_p(j) * xf(i) ^ j
- Next j
-
- Print #1, xf(i) & Chr(9) & Format(yf(i), "####0.000")
- Next i
-
- End Sub
-
-
- Sub regression_polynomiale(deg_pol As Integer, xi() As Double, yi() As Double, coef_pol() As Double)
- Dim i As Integer, j As Integer
- Dim k As Integer, l As Integer
- Dim nb_pts As Integer
- Dim mat_A() As Double, mat_B() As Double
- Dim mat_At() As Double, mat_Bt() As Double
- Dim dim_mat As Integer
-
- dim_mat = deg_pol + 1
-
- 'Nombre de points
- nb_pts = UBound(xi)
- If nb_pts <> UBound(yi) Then MsgBox "Problème, il n'y a pas le même nombre de valeurs pour les x et les y"
-
-
- ReDim mat_A(1 To dim_mat, 1 To dim_mat)
- ReDim mat_B(1 To dim_mat)
- ReDim mat_At(1 To dim_mat, 1 To dim_mat)
- ReDim mat_Bt(1 To dim_mat)
- ReDim coef_pol(0 To deg_pol)
-
-
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- '' Etape 1 :
- '' Mise en équation du problème de minimisation par la méthode des moindres carrés
- '' on cherche à minimiser : E(a0,..., ap) = somme(yi-somme(aj*xi^j)²) où p est le degré du pôlynome
- '' les dérivées partielles de E par rapport à chacun des coef du polynôme de tendance doivent être nulles,
- '' c'est une condition nécessaire !
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- ' les xi et yi sont transmis en paramètres
- ' la procédure renvoie alors en sortie 2 matrices mat_A et mat_B tq :
- ' mat_A * vect_des_aj = mat_B
- Call mise_en_éq(nb_pts, deg_pol, xi(), yi(), mat_A(), mat_B())
-
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- '' Etape 2 :
- '' On réalise alors la triangulation de la mat_A et les opérations équivalentes sur mat_B
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- ' mat_A et mat_B sont données en arguments d'entrée
- ' mat_At et mat_Bt sont renvoyées en arguments de sortie, après triangulation de mat_A
- Call triangulation(dim_mat, mat_A(), mat_B(), mat_At(), mat_Bt())
-
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- '' Etape 3 :
- '' Cette procédure résout alors le système et renvoie les coefficients aj du pôlynome de tendance
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- 'les matrices mat_At et mat_Bt sont données en arguments d'entrée
- 'les coef aj sont renvoyées en arguments de sortie sous le nom de variable coef_pol
- Call resolution(dim_mat, mat_At(), mat_Bt(), coef_pol())
-
-
- End Sub
-
-
- Sub mise_en_éq(n As Integer, p As Integer, vect1() As Double, vect2() As Double, mat1() As Double, mat2() As Double)
-
- Dim i As Integer, j As Integer, k As Integer
-
- For k = 0 To p ' on balaie les lignes
- For j = 0 To p ' on balaie les colonnes
- mat1(k + 1, j + 1) = 0
- For i = 1 To n ' on somme tous les xi^(k+j)
- mat1(k + 1, j + 1) = mat1(k + 1, j + 1) + vect1(i) ^ (k + j)
- Next i
- Next j
- Next k
-
-
- For k = 0 To p ' on balaie les lignes
- mat2(k + 1) = 0
- For i = 1 To n ' on somme tous les (yi*xi^(k))
- mat2(k + 1) = mat2(k + 1) + (vect2(i) * vect1(i) ^ (k))
- Next i
- Next k
-
- End Sub
-
- Sub triangulation(n As Integer, mat1() As Double, mat2() As Double, mat3() As Double, mat4() As Double)
-
- Dim i As Integer, j As Integer, k As Integer
- Dim mat3k() As Double, mat4k() As Double
- ReDim mat3k(1 To n, 1 To n, 1 To n) As Double
- ReDim mat4k(1 To n, 1 To n) As Double
-
- For i = 1 To n
- mat4k(i, 1) = mat2(i)
- For j = 1 To n
- mat3k(i, j, 1) = mat1(i, j)
- Next j
- Next i
-
- For k = 1 To (n - 1)
- For i = 1 To n
- For j = 1 To n
- If i <= k Then
- mat3k(i, j, (k + 1)) = mat3k(i, j, k) ' on conserve les mêmes valeurs
- mat4k(i, (k + 1)) = mat4k(i, k)
- Else
- mat4k(i, (k + 1)) = mat4k(i, k) - (mat3k(i, k, k) * mat4k(k, k) / mat3k(k, k, k))
- If j <= k Then
- mat3k(i, j, (k + 1)) = 0
- Else
- mat3k(i, j, (k + 1)) = mat3k(i, j, k) - (mat3k(i, k, k) * mat3k(k, j, k) / mat3k(k, k, k))
- End If
- End If
- Next j
- Next i
- Next k
-
- For i = 1 To n
- mat4(i) = mat4k(i, n)
- For j = 1 To n
- mat3(i, j) = mat3k(i, j, n)
- Next j
- Next i
- End Sub
-
-
- Sub resolution(n As Integer, mat3() As Double, mat4() As Double, coef_pol() As Double)
-
- Dim i As Integer, j As Integer, k As Integer
- Dim xsol() As Double
- Dim som_aijxj As Double
- ReDim xsol(1 To n)
-
- xsol(n) = mat4(n) / mat3(n, n)
- coef_pol(n - 1) = xsol(n)
-
- For i = (n - 1) To 1 Step (-1)
- som_aijxj = 0
- For j = i + 1 To n
- som_aijxj = som_aijxj + mat3(i, j) * xsol(j)
- Next j
- xsol(i) = 1 / mat3(i, i) * (mat4(i) - som_aijxj)
- coef_pol(i - 1) = xsol(i)
- Next i
-
- End Sub
-
-
-
-
-
Option Explicit
Public x() As Double 'Données d'entrée (xi et yi)
Public y() As Double
Public ai_p() As Double 'Valeurs des coefficients du polynôme de tendance
Sub main()
Dim i As Integer, j As Integer
Dim ligne As String
Dim virg_deb As Long
Dim virg_fin As Long
Dim a As String
i = 0
'Boucle de récupération des données xi et yi à traiter
Open "valeurs_init.txt" For Input As #1
While Not EOF(1)
i = i + 1
ReDim Preserve x(1 To i)
ReDim Preserve y(1 To i)
Line Input #1, ligne
'Remplacement des blancs par des séparateurs (chr(47) = "/")
ligne = Replace(ligne, Chr(9), Chr(47))
ligne = Replace(ligne, Chr(32), Chr(47))
ligne = Chr(47) & ligne & Chr(47)
'Récupération des données x(i) et y(i)
'Recherche des séparateurs (/) et stockage des valeurs indiquées entre les séparateurs
virg_deb = InStr(1, ligne, Chr(47))
virg_fin = InStr((virg_deb + 1), ligne, Chr(47))
x(i) = CDbl(Mid(ligne, (virg_deb + 1), (virg_fin - virg_deb - 1)))
virg_deb = InStr((virg_fin), ligne, Chr(47))
virg_fin = InStr((virg_deb + 1), ligne, Chr(47))
y(i) = CDbl(Mid(ligne, (virg_deb + 1), (virg_fin - virg_deb - 1)))
Wend
Close #1
'Appel de la procédure de régression polynômiale :
'le premier argument est le degré du polynôme de tendance chosi, x() et y() sont les données à traiter
'ai_p() est un argument de retour renvoyant les coef ai du polynôme
Call regression_polynomiale(6, x(), y(), ai_p())
Dim xf() As Double
Dim yf() As Double
ReDim xf(1 To UBound(x))
ReDim yf(1 To UBound(y))
'Boucle générant un fichier texte contenant les valeurs xf(i) et yf(i) approchées
Open "valeurs_fin.txt" For Output As #1
For i = 1 To UBound(x)
xf(i) = x(i)
yf(i) = ai_p(0)
For j = 1 To (UBound(ai_p()))
yf(i) = yf(i) + ai_p(j) * xf(i) ^ j
Next j
Print #1, xf(i) & Chr(9) & Format(yf(i), "####0.000")
Next i
End Sub
Sub regression_polynomiale(deg_pol As Integer, xi() As Double, yi() As Double, coef_pol() As Double)
Dim i As Integer, j As Integer
Dim k As Integer, l As Integer
Dim nb_pts As Integer
Dim mat_A() As Double, mat_B() As Double
Dim mat_At() As Double, mat_Bt() As Double
Dim dim_mat As Integer
dim_mat = deg_pol + 1
'Nombre de points
nb_pts = UBound(xi)
If nb_pts <> UBound(yi) Then MsgBox "Problème, il n'y a pas le même nombre de valeurs pour les x et les y"
ReDim mat_A(1 To dim_mat, 1 To dim_mat)
ReDim mat_B(1 To dim_mat)
ReDim mat_At(1 To dim_mat, 1 To dim_mat)
ReDim mat_Bt(1 To dim_mat)
ReDim coef_pol(0 To deg_pol)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Etape 1 :
'' Mise en équation du problème de minimisation par la méthode des moindres carrés
'' on cherche à minimiser : E(a0,..., ap) = somme(yi-somme(aj*xi^j)²) où p est le degré du pôlynome
'' les dérivées partielles de E par rapport à chacun des coef du polynôme de tendance doivent être nulles,
'' c'est une condition nécessaire !
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' les xi et yi sont transmis en paramètres
' la procédure renvoie alors en sortie 2 matrices mat_A et mat_B tq :
' mat_A * vect_des_aj = mat_B
Call mise_en_éq(nb_pts, deg_pol, xi(), yi(), mat_A(), mat_B())
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Etape 2 :
'' On réalise alors la triangulation de la mat_A et les opérations équivalentes sur mat_B
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' mat_A et mat_B sont données en arguments d'entrée
' mat_At et mat_Bt sont renvoyées en arguments de sortie, après triangulation de mat_A
Call triangulation(dim_mat, mat_A(), mat_B(), mat_At(), mat_Bt())
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Etape 3 :
'' Cette procédure résout alors le système et renvoie les coefficients aj du pôlynome de tendance
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'les matrices mat_At et mat_Bt sont données en arguments d'entrée
'les coef aj sont renvoyées en arguments de sortie sous le nom de variable coef_pol
Call resolution(dim_mat, mat_At(), mat_Bt(), coef_pol())
End Sub
Sub mise_en_éq(n As Integer, p As Integer, vect1() As Double, vect2() As Double, mat1() As Double, mat2() As Double)
Dim i As Integer, j As Integer, k As Integer
For k = 0 To p ' on balaie les lignes
For j = 0 To p ' on balaie les colonnes
mat1(k + 1, j + 1) = 0
For i = 1 To n ' on somme tous les xi^(k+j)
mat1(k + 1, j + 1) = mat1(k + 1, j + 1) + vect1(i) ^ (k + j)
Next i
Next j
Next k
For k = 0 To p ' on balaie les lignes
mat2(k + 1) = 0
For i = 1 To n ' on somme tous les (yi*xi^(k))
mat2(k + 1) = mat2(k + 1) + (vect2(i) * vect1(i) ^ (k))
Next i
Next k
End Sub
Sub triangulation(n As Integer, mat1() As Double, mat2() As Double, mat3() As Double, mat4() As Double)
Dim i As Integer, j As Integer, k As Integer
Dim mat3k() As Double, mat4k() As Double
ReDim mat3k(1 To n, 1 To n, 1 To n) As Double
ReDim mat4k(1 To n, 1 To n) As Double
For i = 1 To n
mat4k(i, 1) = mat2(i)
For j = 1 To n
mat3k(i, j, 1) = mat1(i, j)
Next j
Next i
For k = 1 To (n - 1)
For i = 1 To n
For j = 1 To n
If i <= k Then
mat3k(i, j, (k + 1)) = mat3k(i, j, k) ' on conserve les mêmes valeurs
mat4k(i, (k + 1)) = mat4k(i, k)
Else
mat4k(i, (k + 1)) = mat4k(i, k) - (mat3k(i, k, k) * mat4k(k, k) / mat3k(k, k, k))
If j <= k Then
mat3k(i, j, (k + 1)) = 0
Else
mat3k(i, j, (k + 1)) = mat3k(i, j, k) - (mat3k(i, k, k) * mat3k(k, j, k) / mat3k(k, k, k))
End If
End If
Next j
Next i
Next k
For i = 1 To n
mat4(i) = mat4k(i, n)
For j = 1 To n
mat3(i, j) = mat3k(i, j, n)
Next j
Next i
End Sub
Sub resolution(n As Integer, mat3() As Double, mat4() As Double, coef_pol() As Double)
Dim i As Integer, j As Integer, k As Integer
Dim xsol() As Double
Dim som_aijxj As Double
ReDim xsol(1 To n)
xsol(n) = mat4(n) / mat3(n, n)
coef_pol(n - 1) = xsol(n)
For i = (n - 1) To 1 Step (-1)
som_aijxj = 0
For j = i + 1 To n
som_aijxj = som_aijxj + mat3(i, j) * xsol(j)
Next j
xsol(i) = 1 / mat3(i, i) * (mat4(i) - som_aijxj)
coef_pol(i - 1) = xsol(i)
Next i
End Sub
Conclusion
J'espère que ce code s'avèrera utile à certains. N'hésitez pas à me faire part de vos remarques.
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Moindres carrés [ par Biloute ]
Dans le cadre de recherche je recherche ( sic!!) un prog quin approxime des points avec la méthode des moindres carrés ( approximation polynomiale d'o
moindres carrés [ par tibogl ]
bonjourj'ai deux equations a deux inconnues je souhaiterais utiliser les moindres carrés pour effectuer une regression et obtenir des valeurs pou
moindres carrés avec modele de Cox Ingersoll et Ross [ par coulisn ]
Bonjour à tous et à toutes,Je m'excuse de parler d'autres choses. En fait, je fais un stage et je dois implémenter un modèle de taux (il s'agit du mod
méthode des moindres carrés [ par inge68 ]
Bonjour,j'aimerai trouvé un lien entre plusieurs points mesurés (X1,X2,X3...Xn) et (Y1,Y2,Y3,...Yn).Mon but est de modeliser ce systeme de points et d
Regression polynomiale par les moindres carrés VB express 2008 [ par dantore ]
Bonjour, Je cherche une fonction qui puisse m'effectuer une regression polynomial par les moindres carré en VB 2008 ...J'en ai trouvé pour VB6 ( <a hr
Conserver une variable comme inconnu? [ par abdannour ]
Bonjour, Je travaille sur Excel/VBA. J'espère que ma question sera claire. Je me lance. Je fait plein de calculs matriciels (par l'intermédiaire de su
Drag and drop graphique [ par andrebernard ]
Bonjour à tousVoila, je voudrais faire une fenetre dans laquelle il y aurais par exemple des carrés de differentes couleurs à gauche que je fais gliss
Logiciels open source pour Tests de non-régression, robustesse, etc. [ par Chabossio ]
Bonjour à tous, <p class="M
Régression linéaire en VB [ par BigBob ]
Bonjour,Comment peut on effectuer une régression linéaire (ajustement linéaire par la méthode des moindres carrés) dans VB afin d'obtenir les coeffici
CRC32 [ par mandrac ]
Est ce que le polynome du calcul du CRC32 est normalisé? par exemple j'ai celui-ci : 0xEDB88320, est ce que tous les code source du CRC32 utilise
|
Derniers Blogs
TECHDAYS PARIS 2012 : WINDOWS SERVER "8" QUOI DE 9 !TECHDAYS PARIS 2012 : WINDOWS SERVER "8" QUOI DE 9 ! par ROMELARD Fabrice
Speakers: Fabrice Meillon et Stanislas Quastana Cette session est basée entièrement sur celle donnée lors de la BUILD cet hiver. Il n'y a pas d'ajout d'information en rapport avec cet évènement passé. Windows 8 Server sera intégralem...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice [HTML5] AUTOUR DU W3C : NOUVEAUX STANDARDS ET WEB MOBILE (LILLE)[HTML5] AUTOUR DU W3C : NOUVEAUX STANDARDS ET WEB MOBILE (LILLE) par Gio
Je m'y prends un peu tard je sais, mais bon je suis développeur web et donc hyper fainéant ! Toujours dans le cadre des technologies émergentes, ici HTML5, parce qu'on aime HTML5 chez Wyg , nous seront présent, le vieux ( Aurélien V.) et moi, pour pr...
Cliquez pour lire la suite de l'article par Gio [WP7] DYNAMICALLY CHANGE STARTUP PAGE[WP7] DYNAMICALLY CHANGE STARTUP PAGE par KooKiz
Let's say that you want to allow the user to customize the startup page of your application. You can easily change the startup page by editing the 'NavigationPage' attribute in the manifest file. But the manifest cannot be modified once the applicatio...
Cliquez pour lire la suite de l'article par KooKiz SESSION SILVERLIGHT 5 3D : SLIDES ET DEMOSSESSION SILVERLIGHT 5 3D : SLIDES ET DEMOS par Groc
Durant les techdays, j'ai eu le plaisir d'animer une session sur Silverlight 5 et la 3D avec Simon Ferquel. Comme promis, voici nos slides et mes démos (celles avec le viper BSG) ici et là. Pour mémoire, les démos utilisent toutes le viper BSG...
Cliquez pour lire la suite de l'article par Groc
Logiciels
DocTranslate (V3.1.0.0)DOCTRANSLATE (V3.1.0.0)DocTranslate est un traducteur de document Microsoft Word, PowerPoint et Excel. Il permet d'autom... Cliquez pour télécharger DocTranslate Tribler (2012)TRIBLER (2012)Tribler est un client pair à pair (P2P/Peer-to-Peer) open source avec la capacité de regarder des... Cliquez pour télécharger Tribler OneSwarm (2012)ONESWARM (2012)Le peer-to-peer qui protège votre vie privée, c'est OneSwarm.
Ce logiciel de peer-to-peer crypté... Cliquez pour télécharger OneSwarm PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V8.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V8.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System
|