IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

fit de courbes avec modèles simples


Sujet :

Algorithmes et structures de données

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut fit de courbes avec modèles simples
    Salut tous,

    j'utilise actuellement matlab pour essayer de fitter des courbes "brut" (qui sont donc un peu bruité) afin de pouvoir associer une fonction mathématique à ma courbe et afin d'éliminer le bruit grace à ma courbe mathématique.

    Voici en PJ mes courbes et les données associées à la première courbe.

    j'ai fais pas mal de tentatives (matlab, fonction polyfit) avec des modèles exponentiels/logarithmiques...
    mais ça ne fonctionne pas tout à fait comme je voudrais

    Je viens vous voir car les personnes du forum matlab m'ont renvoyées vers vous pour avoir des informations complémentaires :
    http://www.developpez.net/forums/d12...ifiee-polyfit/

    ps: j'aimerai avoir une fonction monotone de préférence (sinon j'utiliserai un polynome et ça marcherai bien)

    je vous remercie d'avance pour votre aide

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    Juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : Juin 2009
    Messages : 447
    Points : 752
    Points
    752
    Par défaut
    Si tu veux modéliser une courbe, c'est bien de savoir si justement il y a un modèle utilisable derrière. Donc première question:

    D'où viennent ces données, quel phénomène les produit ?

    Sinon à vue de nez la fonction:

    a * log(1+exp(b*(x-x0))) + c

    fait bien l'affaire pour la partie linéaire en tout cas ensuite ça colle moins bien( voir la pièce jointe)

    D'où vient cette formule ? log(1+exp(b*x))∕b est parfois appelé la fonction de cout logistique et c'est une approximation lisse de max(0,x).
    Donc en ajoutant quelques coefficients pour gérer l'échelle le décalage horizontal et le décalage vertical on obtient la formule donnée au début.

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    Juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : Juin 2009
    Messages : 447
    Points : 752
    Points
    752
    Par défaut
    Tu peux faire mieux:

    a*log(1+exp(b*(x-x0)) + c + d*x

    avec ça j'obtiens un fit presque parfait. Tu "fittes" d'abord sans le terme d*x
    (la pente résiduelle etant faible) et tu réutilise les paramètre trouvés pour fitter la formule avec le d*x.

    Explication des paramètres:

    x0: donne la localisation du "coude"
    b: donne la le caractère lisse ou non de la transition au niveau du coude.
    a*b: donne la contribution à la pente loin du coude
    c: le décalage vertical
    d: la pente résiduelle.

    donc dans la partie la plus pentue asymptotiquement la pente est a*b*d
    est dans la partie résiduelle la pente est d.

    Avec cela en tête il est facile d'estimer les paramètres de départ.
    Images attachées Images attachées  

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    merci beaucoup Alexis d'avoir pris le temps de répondre.

    Citation Envoyé par Alexis.M Voir le message
    Si tu veux modéliser une courbe, c'est bien de savoir si justement il y a un modèle utilisable derrière. Donc première question:
    D'où viennent ces données, quel phénomène les produit ?
    oui je vois ce que tu veux dire. Ici c'est un cas un peu complexe car justement on a pas de modèle connu qui permet de réprésenter ceci physiquement. (perte de non linéarité d'un ressort dû à une variation interne de la structure).
    => du coup je veux avoir un modèle simple mais et voir comment évolue les coefficient identifiés en fonction de la variation interne de la structure
    => je veux qqch de monotone car dans la réalité de phénomène est monotone

    Citation Envoyé par Alexis.M Voir le message
    Sinon à vue de nez la fonction:
    a * log(1+exp(b*(x-x0))) + c
    fait bien l'affaire pour la partie linéaire en tout cas ensuite ça colle moins bien( voir la pièce jointe)
    tu as oublié la PJ

    Sinon je pense qu'une relation ou
    doit coller pas mal mais je ne sais pas trop comment les identifier avec polyfit de matlab....

    Citation Envoyé par Alexis.M Voir le message
    D'où vient cette formule ? log(1+exp(b*x))∕b est parfois appelé la fonction de cout logistique et c'est une approximation lisse de max(0,x).
    Donc en ajoutant quelques coefficients pour gérer l'échelle le décalage horizontal et le décalage vertical on obtient la formule donnée au début.
    d'acccord, je comprends le principe, je regarderai.
    merci

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    Citation Envoyé par Alexis.M Voir le message
    Tu peux faire mieux:

    a*log(1+exp(b*(x-x0)) + c + d*x

    avec ça j'obtiens un fit presque parfait. Tu "fittes" d'abord sans le terme d*x
    (la pente résiduelle etant faible) et tu réutilise les paramètre trouvés pour fitter la formule avec le d*x.

    Explication des paramètres:

    x0: donne la localisation du "coude"
    b: donne la le caractère lisse ou non de la transition au niveau du coude.
    a*b: donne la contribution à la pente loin du coude
    c: le décalage vertical
    d: la pente résiduelle.

    donc dans la partie la plus pentue asymptotiquement la pente est a*b*d
    est dans la partie résiduelle la pente est d.

    Avec cela en tête il est facile d'estimer les paramètres de départ.
    ouahou

    c nikel ça
    tu as effectué ceci sur matlab ?

    es ce possible de me montrer ton bout de code ?

  6. #6
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    Juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : Juin 2009
    Messages : 447
    Points : 752
    Points
    752
    Par défaut
    Attention nous avons eu des collisions de messages

    Non j'ai fais ça avec python/scipy/matplotlib

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    Citation Envoyé par Alexis.M Voir le message
    Attention nous avons eu des collisions de messages
    oui, en effet

    Citation Envoyé par Alexis.M Voir le message
    Non j'ai fais ça avec python/scipy/matplotlib
    ah OK. Peux tu me montrer quand meme le bout de code ?

    => quand tu fais l'identification c'est semi automatiquement alors ?

    => tu identifie sans le terme d*x de manière automatique et ensuite tu identifie avec le terme d*x en donnant "à la main" la position de la cassure ?

  8. #8
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    Juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : Juin 2009
    Messages : 447
    Points : 752
    Points
    752
    Par défaut
    si cela t'intéresse:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    import numpy as np
    from scipy.optimize import leastsq
     
    x,y = np.load("data.txt").T
     
    def myfunc(x,x0,a,b,c):
        return b* np.log(1+np.exp(a*(x-x0))) + c
     
    def myfunc2(x,x0,a,b,c,d):
        return b* np.log(1+np.exp(a*(x-x0))) + c + d*x
     
    def err(params):
        return myfunc(x,*params) - y
     
    def err2(params):
        return myfunc2(x,*params) - y
     
    x0, a, b, c  = leastsq(err, [0.004, 1000, 10.,300.0])[0]
    x0, a, b, c, d = leastsq(err2, [x0,a,b,c,0.0])[0]

  9. #9
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    Juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : Juin 2009
    Messages : 447
    Points : 752
    Points
    752
    Par défaut
    L'emplacement du coude est déjà estimer au premier tour, donc tu peux juste mettre la pente à 0.0 pour le deuxième tour.

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    merci Alexis.

    => je vais regarder merci beaucoup pour ton aide.


    ps: j'ai trouvé aussi d'autre choses :
    http://fr.wikipedia.org/wiki/%C3%89q...chaelis-Menten
    et
    je vais regarder du coté des exponentielles ssaturantes (1-exp) exp(A/x) ...

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    Citation Envoyé par Alexis.M Voir le message
    L'emplacement du coude est déjà estimer au premier tour, donc tu peux juste mettre la pente à 0.0 pour le deuxième tour.
    d'accord, du coup ça peut être bien ce modele

    => par contre je n'ai pas trop compris cette histoire de pente. Tu parles bien du coefficient "a" ?

    en tout cas ta régression à l'air super je vais tester

    => pour résumer :
    tu utilises d'abord la première equation pour le fit, ensuite tu refais le fit mais avec une autre equation (la deuxieme mais en conservant les parametres de la première identification) mais du coup c'est quoi cette histoire de 0 ? (lors de l'identification de "d" je met a=0 ?


    Sinon pour la deuxième courbe :


    Tu penses que ça peut fonctionner avec la même fonction ?

    => Au fait, tant qu'à utiliser une regression non linéaire pourquoi ne pas utiliser une formule du genre :

    A(1-exp(-B/x)) ?

    ça doit marcher ça non ?

  12. #12
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    Juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : Juin 2009
    Messages : 447
    Points : 752
    Points
    752
    Par défaut
    Citation Envoyé par 21did21 Voir le message
    d'accord, du coup ça peut être bien ce modele

    => par contre je n'ai pas trop compris cette histoire de pente. Tu parles bien du coefficient "a" ?
    Ta courbe à l'air d'être composée de deux segments de droite reliées de façon lisse.

    assymptotiquement si a>0 on a
    lim x->inf log(1+exp(a*x) = a*x
    lim x->-inf log(1+exp(a*x) = 0

    Cette fonction a donc la proporiété de donner rapidement une contribution nulle lorsque a*x devient négatif et de ce comporter comme une droite de pente a lorsque a*x est positif.

    Malheureusement le paramètre a règle aussi la rapidité de la transition entre les deux "régimes" donc pour pouvoir régler à la fois la courbure du coude et la pente il faut un deuxième paramètre b.

    La pente en régime linéaire est donc a*b.

    Le deuxième segment paramètré par c + d*x à une pente faible. C'est pour cela qu'en première approximation on garde la pente à zero et on n'ajuste que c.

    x0 règle l'emplacement du coude.

    Loin du coude en régime linéaire pour la première partie nous avons donc la contribution des deux segments donc la pente est (a*b+d), de l'autre côté la contribution du terme en 'log' devient nulle et seule le segment c+d*x contribue la pente est donc 'd'.

    => pour résumer :
    tu utilises d'abord la première equation pour le fit, ensuite tu refais le fit mais avec une autre equation (la deuxieme mais en conservant les parametres de la première identification) mais du coup c'est quoi cette histoire de 0 ? (lors de l'identification de "d" je met a=0 ?
    la pente du deuxième segment de droite est très faible donc au premier tour on la fixe à zero. ce qui permet d'avoir moins de paramètre à ajuster.
    Au deuxième tour tu l'initialises à zero mais tu t'attends en sortie à retrouver la bonne contribution

    Sinon pour la deuxième courbe :

    Tu penses que ça peut fonctionner avec la même fonction ?
    Oui il faudra juste modifier les paramètre initiaux pour prendre en compte les sens de courbure.

    => Au fait, tant qu'à utiliser une regression non linéaire pourquoi ne pas utiliser une formule du genre :

    A(1-exp(-B/x)) ?

    ça doit marcher ça non ?
    Je ne pense pas, cette fonction n'a pas de "régime linéaire" où elle peut se comporter comme une droite.

Discussions similaires

  1. Simple courbe avec matplotlib
    Par LinuxUser dans le forum GUI
    Réponses: 10
    Dernier message: 14/02/2012, 11h42
  2. Réponses: 2
    Dernier message: 05/01/2012, 23h11
  3. [Tableaux] souci avec des simples quotes
    Par Jean Fi dans le forum Langage
    Réponses: 6
    Dernier message: 29/03/2006, 20h13
  4. Ksh, problème avec une simple boucle for
    Par herzleid dans le forum Linux
    Réponses: 4
    Dernier message: 22/03/2006, 14h45
  5. problème pour parser un fichier xml avec XML::Simple
    Par black_code dans le forum Modules
    Réponses: 3
    Dernier message: 30/01/2006, 19h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo