前回の相談事例で, 初期値を与えないバージョンを示しましたが, 実際に使う場合には,
初期値を与えないと解けない場合も多々あるようです.
相談者(院生さん)が, 前回示した toy example をもとに, 自分のデータに curve_fit を適用したところ,
初期値なしではうまくいかず, 初期値を与えたところうまくいった, との報告をいただきました.
初期値の与え方を相談者に教えてもらったので, カーブフィットの
コードを, 初期値を与えるものにバージョン・アップしたものをここに記します.
このように, 相談者からも色々と教えてもらえるのが, 統計Cafeの楽しいところです.
jupyter notebook での計算を前提にしたコードですが, 一部修正すれば多くの
Python 3 環境で動くはずです.
import matplotlib.pyplot as plt
import numpy as np
import scipy.optimize
import scipy.stats
def func(x, a, b, c, d, e):
return a * np.exp(- ((x - b) / c)**2) + d * x + e
# Creating mock data
y_base_0 = .5
amp_noize= 0.5
a_0 = 20
b_0 = 1
c_0 = .1
d_0 = .6
e_0 = 1
xs = np.linspace(0, 2, 100)
y_func = func(xs, a_0, b_0, c_0, d_0, e_0) # Value of the func at xs.
yerr = scipy.stats.norm.rvs(scale=amp_noize, size=len(xs)) # Noise
ys = y_func + yerr
# Fitting the data to the function, func. NOTE, One line.
#
# We set the initial values for the optimization, p0=guess=[a_0, b_0, c_0, d_0, e_0]
#
guess = [a_0, b_0, c_0, d_0, e_0]
res = scipy.optimize.curve_fit(func, xs, ys, p0=guess)
print(res)
par = res[0]
a, b, c, d, e= par[0], par[1], par[2], par[3], par[4]
print('Fitted [a, b, c, d, e] = ', a, b, c, d, e)
# Plotting the data and fitted line
fig, ax = plt.subplots()
ax.scatter(xs, ys) # Data
ax.plot(xs, func(xs, a, b, c, d, e) , c='r') # Fitted line
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.savefig('fitting_a_peak.png')
コメント
コメントを投稿