[PYTHON] Modellbefestigung mit lmfit

Einführung

Dieser Artikel ist der 21. Tagesartikel von Adventskalender 2019 von ACCESS Co., Ltd.. ist.

In einem bestimmten Fall unseres Unternehmens sollten wir eine nichtlineare minimale quadratische Anpassung durchführen. Daher werden wir zur Vorbereitung die zuvor verwendete nichtlineare minimale quadratische Anpassung mit "lmfit" überprüfen und hier zusammenfassen. ..

lmfit

lmfit ist ein nichtlineares Minimum von zwei, da der offizielle Untertitel "Nichtlineare Minimierung kleinster Quadrate und Kurvenanpassung für Python" lautet. Eine Bibliothek zur Modellanpassung mithilfe der Multiplikation, die auf der Grundlage vieler Optimierungsmethoden in scipy.optimize erweitert wurde. , Es wurde entwickelt.

Eigenschaften

Die folgenden Funktionen sind aufgeführt.

Wo ich es nützlich finde (subjektiv)

Einfache Handhabung von Modellen und Modellparametern

Modellbefestigung mit lmfit

Die Daten wurden für diesen Artikel erstellt und sind wie folgt dargestellt: plot1.png

Wie Sie auf einen Blick sehen können, haben diese Daten zwei Strukturen, und um 6.0 und 7.5 ist eine Struktur wie eine Normalverteilung zu sehen. Lassen Sie uns diese Daten anpassen.

Modell-

Wie oben erwähnt, gibt es zwei normalverteilungsähnliche Strukturen, daher muss ein Modell eingeführt werden, das sie darstellt. Da es anscheinend einen konstanten Versatz ungleich Null gibt, ist es auch erforderlich, eine Komponente, die dies reproduziert, in das Modell aufzunehmen. Die Formel lautet wie folgt.

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

Dies kann mit dem Klassenobjekt lmfit.models wie folgt ausgedrückt werden.

import lmfit as lf
import lmfit.models as lfm

#Modelldefinition
model = lfm.ConstantModel() +  lfm.GaussianModel(prefix='gauss1_') + lfm.GaussianModel(prefix='gauss2_')

Durch die Angabe von "Präfix" ist dies praktisch, da Parameter auch dann unterschieden werden können, wenn dieselbe Modellfunktion verwendet wird.

Bei der Einführung Ihres eigenen Modells

Es kann auf einmal eingeführt werden, indem die im Modellklassenobjekt definierte Funktion übergeben wird.


def constant(x, const):
    return const

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

Parameter

Selbst wenn Sie ein Klassenobjekt "Modell" deklarieren, wird das Klassenobjekt "Parameter" für dieses Klassenobjekt "Modell" nicht deklariert. Beginnen Sie also mit dieser Deklaration.

#Stellen Sie den Anfangswert jedes Parameters ein
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
}

#Deklaration des Parameterobjekts für das definierte Modell
params = model.make_params()
for name in model.param_names: 
    params[name].set(
        value=par_val[name], #Ursprünglicher Wert
        min=par_min[name], #untere Grenze
        max=par_max[name], #Höchstgrenze
        vary=par_vary[name] #Gibt an, ob der Parameter verschoben werden soll
    )

Die Beziehung zwischen Parametern kann wie folgt algebraisch eingeschränkt werden.

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

passend zu

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

Hinweis: Die Daten sind im DataFrame-Objekt von pandas angegeben.

Bestätigung des Anpassungsergebnisses

Sie können die Zusammenfassung der Anpassungsergebnisse wie folgt sehen.

```
[[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
```

--Plot der Anpassungsergebnisse

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

Das folgende Diagramm wird automatisch generiert. plot2.png

das ist alles. Bitte genießen Sie weiterhin den Artikel von @ rheza_h am 22. Tag.

Recommended Posts

Modellbefestigung mit lmfit
Regression mit einem linearen Modell
Passend zu ARMA, ARIMA Modell
[Python] Kurvenanpassung mit Polypolyse
Kalibrieren Sie das Modell mit PyCaret
Verwenden Sie MLflow mit Databricks ④ - Anrufmodell -
Führen Sie eine minimale quadratische Anpassung mit numpy durch.
Passen Sie Modell / Ebene / Metrik mit TensorFlow an
Mehrschichtiges Perzeptron mit Kette: Funktionsanpassung
Einfaches Klassifizierungsmodell mit neuronalem Netz
Generieren Sie automatisch ein Modellbeziehungsdiagramm mit Django
Multi-Input / Multi-Output-Modell mit funktionaler API
[Python] Gemischtes Gaußsches Modell mit Pyro
Katzenerkennung mit OpenCV (Modellverteilung)
Erstellen Sie mit PySide einen Modelliterator
Validieren Sie das Trainingsmodell mit Pylearn2
Seq2Seq (2) ~ Achtung Model Edition ~ mit Chainer
Invertiertes Pendel mit modellprädiktiver Steuerung
Lassen Sie uns die Hyperparameter des Modells mit scikit-learn abstimmen!
Achtung Seq2 Führen Sie das Dialogmodell mit Seq aus
Infer Custom Vision Modell mit Raspeye
Verwenden von MLflow mit Databricks ③ - Modelllebenszyklusmanagement -
Implementieren Sie ein Modell mit Status und Verhalten
Vorhersage von Epidemien von Infektionskrankheiten mit dem SIR-Modell
Probieren Sie TensorFlows RNN mit einem Basismodell aus