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 :

[python] ajuster une courbe avec scipy.optimize.curve_fit()


Sujet :

Algorithmes et structures de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Profil pro
    conseil scientifique
    Inscrit en
    Septembre 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : conseil scientifique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8
    Par défaut [python] ajuster une courbe avec scipy.optimize.curve_fit()
    Bonjour ou bonsoir, je travaille avec Python (v.3.13) pour modéliser mes données (mesures de spectres de raies en spectrométrie), (x_i, y_i) i=range(n), avec divers types de courbes, dont la base est une somme en nombre variable de gaussiennes (ou autres formes, mais laissons ça de côté). Pour ça, je recours à la fonction du package scipy, "scipy.optimize.curve_fit". Mon problème est que "curve_fit" s'attend à recevoir la fonction à ajuster (enfin, ses paramètres), avec une liste explicite et "figée" de paramètres. Pour simplifier, je suppose ici que je connais exactement la position et la largeur des gaussiennes, et que je n'ai que leurs hauteurs à ajuster. Si par exemple, j'ai 3 raies, ma fonction d'ajustement sera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def spectreThéoriq(xdata, haut1, haut2, haut3) :
       return ( haut1*gaus1(xdata) + haut2*gaus2(xdata) + haut3*gaus3(xdata) )
    où les (trois) fonctions "gaus1", etc., sont définies avant dans mon code. L'ajustement se fera ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    parmOptim = scipy.optimize.curve_fit(spectreThéoriq, xDonnées, yDonnées)
    où xDonnées est le vecteur des [x_i, i=1..n] (notation non python…) et similairement pour yDonnées.

    Mon problème est donc le suivant : je préfèrerais passer, ici le triplet des paramètres à ajuster, via un vecteur : parms = [haut1, haut2, haut3], parce que, comme dit plus haut, le nombre des gaussiennes est variable (et en réalité, j'ai aussi les autres paramètres comme les positions et les largeurs de ces "gaussiennes" à ajuster ; ici j'ai simplifié). Voici un script simplifié qui fonctionne, mais redemande du travail si je veux prendre en compte la 4è raie ! :-(

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #!/usr/bin/env python3
    ## fit_spectre_exmpl.py
     
    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.optimize as sop
     
    def gaus_(xdata, posit, larg) :
       return np.exp(-0.5*((xdata-posit)/larg)**2)
    def gaus1(xdata) : return gaus_(xdata, 2.5, 0.3)
    def gaus2(xdata) : return gaus_(xdata, 4.5, 0.4)
    def gaus3(xdata) : return gaus_(xdata, 6.0, 0.4)
    def gaus4(xdata) : return gaus_(xdata, 8.0, 0.3)
     
    np.random.seed(145320) # reproductibilité du hasard
    xDonnées = np.linspace(0.5,10.,100)
    yDonnées = 1.2 * gaus1(xDonnées) + 3.2 * gaus2(xDonnées)
    yDonnées += 2.1 * gaus3(xDonnées) + 0.7 * gaus4(xDonnées)
    yDonnées += 0.2 * np.random.randn(len(xDonnées))
     
    def spectreThéoriq(xObs, h1, h2, h3) :
       return ( h1 * gaus1(xObs) + h2 * gaus2(xObs) + h3 * gaus3(xObs) )
     
    hOpt, hCov = sop.curve_fit(spectreThéoriq, xDonnées, yDonnées)
    print("Hauteurs optimisées =", hOpt)
    yAjustés = spectreThéoriq(xDonnées, *hOpt)
     
    plt.plot(xDonnées, yDonnées, "bo-")
    plt.plot(xDonnées, yAjustés, "r-")
    plt.show()
    ##
    Comment faire pour travailler avec un "def spectreThéoriq(xObs, hautS) :" où l vecteur hautS contient les (ici 3) paramètres ? Sur la base de l'utilisation des "arguments étoilés", j'ai essayé ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def spectreThéoriq(xObs, *hautS) :
       hautS = hautS[0]
       nParm = len(hautS)
      ...
    mais curve_fit me renvoie cette erreur :
    ValueError: Unable to determine number of fit parameters.

    Merci par avance de vos suggestions. -- ÉLw.py

  2. #2
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 594
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 594
    Billets dans le blog
    67
    Par défaut
    Bonjour,

    Citation Envoyé par ELw.py
    Comment faire pour travailler avec un "def spectreThéoriq(xObs, hautS) :" où l vecteur hautS contient les (ici 3) paramètres ? Sur la base de l'utilisation des "arguments étoilés", j'ai essayé ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def spectreThéoriq(xObs, *hautS) :
       hautS = hautS[0]
       nParm = len(hautS)
    A première vue, il est précisé dans l'aide concernant la fonction f d'ajustement :

    La fonction f doit prendre la variable indépendante comme premier argument et les paramètres d'ajustement comme arguments restants séparés (au moment de définir la fonction).

    https://docs.scipy.org/doc/scipy/ref...curve_fit.html

    Avec *hautS il ne voit pas le nombre de paramètres/arguments d'ajustement (d'où le message d'erreur).

    Maintenant si vous souhaitez plus d'info vous pouvez aussi poser votre question sur le forum Python..

    Cdlt
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

Discussions similaires

  1. [Python 2.X] scipy.optimize.curve_fit avec une fonction log et echelle log
    Par Suntory dans le forum Calcul scientifique
    Réponses: 6
    Dernier message: 06/06/2019, 09h05
  2. comment tracer une courbe avec gtk
    Par killer_instinct dans le forum GTK+ avec C & C++
    Réponses: 5
    Dernier message: 01/10/2007, 22h53
  3. Tracer une courbe avec GTK+
    Par insa59 dans le forum GTK+ avec C & C++
    Réponses: 11
    Dernier message: 16/03/2007, 15h29
  4. dessiner une courbe avec OleExcel
    Par blondelle dans le forum C++Builder
    Réponses: 9
    Dernier message: 28/09/2006, 22h05
  5. Tracer une courbe avec 2 tableau de points
    Par babarpapa dans le forum 2D
    Réponses: 3
    Dernier message: 19/04/2006, 15h24

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