[PYTHON] Montage du modèle avec lmfit

introduction

Cet article est l'article du 21e jour du Calendrier de l'Avent 2019 de ACCESS Co., Ltd. est.

Dans un certain cas de notre entreprise, nous devrions faire un ajustement carré minimum non linéaire, donc pour la préparation, nous examinerons le raccord carré minimum non linéaire par lmfit que nous avons utilisé auparavant et le résumerons ici. ..

lmfit

lmfit est un minimum de deux non-linéaires comme le sous-titre officiel dit «Minimisation non linéaire des moindres carrés et ajustement de courbe pour Python». Une bibliothèque pour l'ajustement de modèle utilisant la multiplication, étendue basée sur de nombreuses méthodes d'optimisation dans scipy.optimize. , A été développé.

traits

Les fonctionnalités suivantes sont répertoriées.

Où je le trouve utile (subjectivement)

Facilité de manipulation des modèles et des paramètres de modèle

Montage du modèle avec lmfit

Les données ont été créées pour cet article et sont tracées comme suit: plot1.png

Comme vous pouvez le voir en un coup d'œil, ces données ont deux structures, et autour de 6,0 et 7,5, une structure comme une distribution normale peut être vue. Adaptez ces données.

modèle

Comme mentionné ci-dessus, il existe deux structures de type distribution normale, il est donc nécessaire d'introduire un modèle qui les représente. De plus, comme il semble qu'il existe un décalage constant non nul, il est nécessaire d'incorporer un composant qui le reproduit dans le modèle. La formule est la suivante.

f\left( x \right) = G_1 \left( x \right) +  G_2 \left( x \right) + C

Cela peut être exprimé en utilisant l'objet de classe lmfit.models comme suit.

import lmfit as lf
import lmfit.models as lfm

#Définition du modèle
model = lfm.ConstantModel() +  lfm.GaussianModel(prefix='gauss1_') + lfm.GaussianModel(prefix='gauss2_')

En spécifiant prefix, c'est pratique car les paramètres peuvent être distingués même si la même fonction de modèle est utilisée.

Lors de la présentation de votre propre modèle

Il peut être introduit d'un seul coup en passant la fonction définie dans l'objet de classe Model.


def constant(x, const):
    return const

model = lf.Model(constant) +  lfm.GaussianModel(prefix='gauss1_') + lfm.GaussianModel(prefix='gauss2_')

Paramètres

Même si vous déclarez un objet de classe Model, l'objet de classe Parameters pour cet objet de classe Model n'est pas déclaré, alors commencez par cette déclaration.

#Définissez la valeur initiale de chaque paramètre
par_val = {
    'c' : 20,
    'const' : 20,
    'gauss1_center' : 6.0,
    'gauss1_sigma' : 1.0,
    'gauss1_amplitude' : 400,
    'gauss2_center' : 7.5,
    'gauss2_sigma' : 1.0,
    'gauss2_amplitude' : 150
}

par_min = { 
    'c' : 0,
    'const' : 0,
    'gauss1_center' : 0,
    'gauss1_sigma' : 0,
    'gauss1_amplitude' : 0,
    'gauss2_center' : 0,
    'gauss2_sigma' : 0,
    'gauss2_amplitude' : 0
}

par_max = { 
    'c' : 100,
    'const' : 100,
    'gauss1_center' : 10,
    'gauss1_sigma' : 10,
    'gauss1_amplitude' : 1000,
    'gauss2_center' : 10,
    'gauss2_sigma' : 10,
    'gauss2_amplitude' : 1000
}

par_vary = { 
    'c' : True,
    'const' : True,
    'gauss1_center' : True,
    'gauss1_sigma' : True,
    'gauss1_amplitude' : True,
    'gauss2_center' : True,
    'gauss2_sigma' : True,
    'gauss2_amplitude' : True
}

#Objet de classe Déclaration de paramètres pour le modèle défini
params = model.make_params()
for name in model.param_names: 
    params[name].set(
        value=par_val[name], #valeur initiale
        min=par_min[name], #limite inférieure
        max=par_max[name], #limite supérieure
        vary=par_vary[name] #Déplacer le paramètre
    )

La relation entre les paramètres peut être contrainte algébriquement comme suit.

params['gauss2_center'].set(expr='gauss1_center*1.25')

raccord

result = model.fit(x=df.x, data=df.y, weights=df.dy**(-1.0), params=params, method='leastsq')

Remarque: Les données sont données dans l'objet DataFrame de pandas.

Confirmation du résultat de l'ajustement

Vous pouvez voir le résumé des résultats de l'ajustement comme suit.

```
[[Model]]
    ((Model(constant) + Model(gaussian, prefix='gauss1_')) + Model(gaussian, prefix='gauss2_'))
[[Fit Statistics]]
    # fitting method   = leastsq
    # function evals   = 383
    # data points      = 50
    # variables        = 6
    chi-square         = 29.2390839
    reduced chi-square = 0.66452463
    Akaike info crit   = -14.8258350
    Bayesian info crit = -3.35369698
[[Variables]]
    const:             21.4200227 +/- 1.47331527 (6.88%) (init = 20)
    gauss1_amplitude:  88.4566498 +/- 1.39004141 (1.57%) (init = 400)
    gauss1_center:     5.99651706 +/- 0.00136123 (0.02%) (init = 6)
    gauss1_sigma:      0.09691089 +/- 0.00153157 (1.58%) (init = 1)
    gauss2_amplitude:  31.6555368 +/- 1.39743186 (4.41%) (init = 150)
    gauss2_center:     7.49564632 +/- 0.00170154 (0.02%) == 'gauss1_center*1.25'
    gauss2_sigma:      0.09911853 +/- 0.00446584 (4.51%) (init = 1)
    gauss1_fwhm:       0.22820770 +/- 0.00360656 (1.58%) == '2.3548200*gauss1_sigma'
    gauss1_height:     364.139673 +/- 4.89553113 (1.34%) == '0.3989423*gauss1_amplitude/max(2.220446049250313e-16, gauss1_sigma)'
    gauss2_fwhm:       0.23340629 +/- 0.01051624 (4.51%) == '2.3548200*gauss2_sigma'
    gauss2_height:     127.410415 +/- 4.77590041 (3.75%) == '0.3989423*gauss2_amplitude/max(2.220446049250313e-16, gauss2_sigma)'
[[Correlations]](unreported correlations are < 0.100)
    C(gauss2_amplitude, gauss2_sigma)     =  0.647
    C(gauss1_amplitude, gauss1_sigma)     =  0.636
    C(const, gauss2_amplitude)            = -0.555
    C(const, gauss1_amplitude)            = -0.552
    C(const, gauss1_sigma)                = -0.367
    C(const, gauss2_sigma)                = -0.359
    C(gauss1_amplitude, gauss2_amplitude) =  0.306
    C(gauss1_sigma, gauss2_amplitude)     =  0.203
    C(gauss1_amplitude, gauss2_sigma)     =  0.198
    C(gauss1_sigma, gauss2_sigma)         =  0.131
```

--Tracé des résultats de l'ajustement

```python
fig, gridspec = result.plot(data_kws={'markersize': 5})
```

Le graphique suivant est généré automatiquement. plot2.png

-Résultat d'ajustement Les propriétés suivantes ont la valeur optimale, etc., alors n'hésitez pas à faire le reste.

```python
result.chisqr #Valeur du chi carré
result.nfree  #Degré de liberté
result.redchi #Valeur chi carré convertie
result.aic    # aic
result.bic    # bic    
result.best_fit  # best-ajustement de la valeur du modèle(Valeur du graphique orange du résultat de l'ajustement)
result.residual  # (best-fit model)-(data)La valeur du(Valeurs dans le panneau supérieur des résultats d'ajustement)
result.eval_components(x=df.x)  # best-Valeur pour chaque composant du modèle d'ajustement
result.best_values #Valeur optimale pour chaque paramètre:type de dict
result.result.params['const'].value  #Valeur optimale du paramètre
result.result.params['const'].stderr #Erreur standard des paramètres
```

c'est tout. Veuillez continuer à profiter de l'article de @ rheza_h le 22e jour.

Recommended Posts

Montage du modèle avec lmfit
Régression avec un modèle linéaire
Adapté au modèle ARMA, ARIMA
[Python] Ajustement de courbe avec polypoly
Calibrer le modèle avec PyCaret
Utiliser MLflow avec Databricks ④ --Call model -
Effectuez un ajustement carré minimum avec numpy.
Personnaliser le modèle / la couche / la métrique avec TensorFlow
Perceptron multicouche avec chaînette: ajustement fonctionnel
Modèle de classification simple avec réseau neuronal
Générer automatiquement un diagramme de relation de modèle avec Django
Modèle multi-entrées / multi-sorties avec API fonctionnelle
[Python] Modèle gaussien mixte avec Pyro
Détection de chat avec OpenCV (distribution de modèles)
Créer un itérateur de modèle avec PySide
Validez le modèle d'entraînement avec Pylearn2
Seq2Seq (2) ~ Attention Model edition ~ avec chainer
Pendule inversé avec contrôle prédictif du modèle
Affinons les hyper paramètres du modèle avec scikit-learn!
Attention Seq2 Exécutez le modèle de dialogue avec Seq
Modèle Infer Custom Vision avec Raspeye
Utilisation de MLflow avec Databricks ③ --Gestion du cycle de vie des modèles -
Implémenter un modèle avec état et comportement
Prédire les épidémies de maladies infectieuses avec le modèle SIR
Essayez TensorFlow RNN avec un modèle de base