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.
Die folgenden Funktionen sind aufgeführt.
Die Daten wurden für diesen Artikel erstellt und sind wie folgt dargestellt:
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.
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.
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_')
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')
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.
summary
print(result.fit_report())
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
```
confidence interval
print('[[Confidence Intervals]]')
print(result.ci_report())
[[Confidence Intervals]]
99.73% 95.45% 68.27% _BEST_ 68.27% 95.45% 99.73%
const : -4.72534 -3.05035 -1.49522 21.42002 +1.48820 +3.02111 +4.65531
gauss1_amplitude: -4.37979 -2.84434 -1.40305 88.45665 +1.41243 +2.88513 +4.47133
gauss1_center : -0.00435 -0.00278 -0.00131 5.99652 +0.00131 +0.00278 +0.00436
gauss1_sigma : -0.00479 -0.00312 -0.00154 0.09691 +0.00156 +0.00321 +0.00499
gauss2_amplitude: -4.31612 -2.82491 -1.40294 31.65554 +1.43259 +2.94767 +4.61057
gauss2_sigma : -0.01344 -0.00889 -0.00446 0.09912 +0.00466 +0.00971 +0.01540
--Plot der Anpassungsergebnisse
```python
fig, gridspec = result.plot(data_kws={'markersize': 5})
```
Das folgende Diagramm wird automatisch generiert.
Passendes Ergebnis Die folgenden Eigenschaften haben den optimalen Wert usw. Sie können den Rest erledigen.
result.chisqr #Chi-Quadrat-Wert
result.nfree #Freiheitsgrad
result.redchi #Umgerechneter Chi-Quadrat-Wert
result.aic # aic
result.bic # bic
result.best_fit # best-Modellwert anpassen(Wert des orangefarbenen Diagramms des Anpassungsergebnisses)
result.residual # (best-fit model)-(data)Der Wert der(Werte im oberen Bereich der Anpassungsergebnisse)
result.eval_components(x=df.x) # best-Wert für jede Komponente des Anpassungsmodells
result.best_values #Optimaler Wert für jeden Parameter:Diktat Typ
result.result.params['const'].value #Optimaler Wert des Parameters
result.result.params['const'].stderr #Standardfehler der Parameter
das ist alles. Bitte genießen Sie weiterhin den Artikel von @ rheza_h am 22. Tag.
Recommended Posts