1

symfit documentationに従って、 symfitパッケージでグローバル フィッティングを実行しようとしています。

import numpy as np
import symfit as sf
import matplotlib.pyplot as plt
%matplotlib inline # for ipynb

# Generate example data
t = np.arange(0.0, 600.1, 30)
k = 0.005
C1_0, C2_0 = 1.0, 2.0
C1 = C1_0 * np.exp(-k*t)
C2 = C2_0 * np.exp(-k*t)

# Construct model
x_1, x_2, y_1, y_2 = sf.variables('x_1, x_2, y_1, y_2')
kg = sf.Parameter(value=0.01, min=0.0, max=0.1)
a_1, a_2 = sf.parameters('a_1, a_2')
globalmodel = sf.Model({
    y_1: a_1 * np.e**(- kg * x_1),
    y_2: a_2 * np.e**(- kg * x_2),
})

# Do fit
globalfit = sf.Fit(globalmodel, x_1=t, x_2=t, y_1=C1, y_2=C2)
globalfit_result = globalfit.execute()
print(globalfit_result)

### EDITED START
while globalfit_result.r_squared < 0.99:
    kg = sf.Parameter(value=globalfit_result.params['kg'])
    a_1 = sf.Parameter(value=globalfit_result.params['a_1'])
    a_2 = sf.Parameter(value=globalfit_result.params['a_2'])
    globalmodel = sf.Model({
        y_1: a_1 * np.e**(- kg * x_1),
        y_2: a_2 * np.e**(- kg * x_2),
    })
    globalfit = sf.Fit(globalmodel, x_1=t, x_2=t, y_1=C1, y_2=C2)
    globalfit_result = globalfit.execute()
### EDITED END

y_r = globalmodel(x_1=t, x_2=t, **globalfit_result.params)

# Plot fit
plt.plot(t,C1,'ro')
plt.plot(t,C2,'b+')
plt.plot(t,y_r[0],'r-')
plt.plot(t,y_r[1],'b-')
plt.show()

この例では、"globalmodel" の "kg" パラメータが 0.005 に最適化されていることを期待しています。ただし、「kg」の値は約 9.6e-3 であり、初期値 (10.0e-3) に近すぎます。私は愚かなことをしていると思いますが、それを理解することはできません。

コメントや提案は大歓迎です!

編集済み

最適なフィットを得るために (非常に醜い) while ループを追加しました。なぜそうなのかはわかりませんが、うまくいくようです。

4

1 に答える 1

1

境界が問題を引き起こしているようです。テストでそれらを削除したところ、すべて正常に動作しました。This is a known problem in symfit 0.3.3, a̶n̶d̶ ̶o̶n̶e̶ ̶I̶ ̶a̶l̶r̶e̶a̶d̶y̶ ̶f̶i̶x̶e̶d̶ ̶i̶n̶ ̶t̶h̶e̶ ̶[̶ ̶m̶a̶s̶t̶e̶r̶̶]̶[̶1̶]̶ ̶b̶r̶a̶n̶c̶h̶ ̶o̶n̶ ̶G̶i̶t̶h̶u̶b̶.̶ ̶ ̶ ̶I̶ ̶u̶p̶l̶o̶a̶d̶e̶d̶ ̶a̶ ̶n̶e̶w̶ ̶d̶e̶v̶ ̶v̶e̶r̶s̶i̶o̶n̶ ̶y̶o̶u̶ ̶c̶o̶u̶l̶d̶ ̶n̶o̶w̶ ̶i̶n̶s̶t̶a̶l̶l̶ ̶u̶s̶i̶n̶g̶ ̶ ̶p̶i̶p̶ ̶i̶n̶s̶t̶a̶l̶l̶ ̶s̶y̶m̶f̶i̶t̶=̶=̶0̶.̶3̶.̶3̶.̶d̶e̶v̶1̶5̶5̶ ̶-̶-̶u̶p̶g̶r̶a̶d̶e̶̶,̶ ̶u̶n̶t̶i̶l̶ ̶I̶ ̶o̶f̶f̶i̶c̶i̶a̶l̶l̶y̶ ̶r̶e̶l̶e̶a̶s̶e̶ ̶0̶.̶3̶.̶4̶ ̶(̶w̶h̶i̶c̶h̶ ̶w̶i̶l̶l̶ ̶b̶e̶ ̶i̶d̶e̶n̶t̶i̶c̶a̶l̶ ̶b̶u̶t̶w̶i̶t̶h̶ ̶e̶x̶t̶e̶n̶d̶e̶d̶ ̶d̶o̶c̶u̶m̶e̶n̶t̶a̶t̶i̶o̶n)

それは象徴的であるため、に変更np.eしたことに注意してください。sf.exp私の作業コードは以下のとおりです。言及されて実行されている変更を除いて、あなたのものと同じです0.3.3.dev155

import numpy as np
import symfit as sf
import matplotlib.pyplot as plt

# Generate example data
t = np.arange(0.0, 600.1, 30)
k = 0.005
C1_0, C2_0 = 1.0, 2.0
C1 = C1_0 * np.exp(-k*t)
C2 = C2_0 * np.exp(-k*t)

# Construct model
x_1, x_2, y_1, y_2 = sf.variables('x_1, x_2, y_1, y_2')
kg = sf.Parameter(value=0.01, min=0.0, max=0.1)
a_1, a_2 = sf.parameters('a_1, a_2')
globalmodel = sf.Model({
    y_1: a_1 * sf.exp(- kg * x_1),
    y_2: a_2 * sf.exp(- kg * x_2),
})

# Do fit
globalfit = sf.Fit(globalmodel, x_1=t, x_2=t, y_1=C1, y_2=C2)
globalfit_result = globalfit.execute()
print(globalfit_result)

y_r = globalmodel(x_1=t, x_2=t, **globalfit_result.params)

# Plot fit
plt.plot(t,C1,'ro')
plt.plot(t,C2,'b+')
plt.plot(t,y_r[0],'r-')
plt.plot(t,y_r[1],'b-')
plt.show()
于 2016-12-04T16:32:17.030 に答える