[英]Minimization through lmfit
我想估計 x 的值。 所以這是我將 x 作為參數時對我有用的代碼。
`
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Parameters, minimize
from numpy import exp, linspace, random
def gaussian(x, amp, cen, wid):
return amp * exp(-(x-cen)**2 / wid)
x = linspace(-10, 10, 101)
data = gaussian(x, 2.33, 0.21, 1.51) + random.normal(0, 0.2, x.size)
Model = gaussian(x, 2.33,0.21,1.51)
plt.plot(x, data, label = 'data')
plt.plot(x, Model, label = 'Model')
plt.legend()
plt.grid(True)
plt.show()
d = 50
print ("\nThe data value at {} is {}\n".format(0, data[0+d]))
params = Parameters()
params.add('x', value =-3)
def objective(params, amp, cen, wid, data):
x = params['x']
m = gaussian(x, amp, cen, wid)
return data - m
result = minimize(objective, params=params, args=(2.33, 0.21, 1.51,data[d]))
print(result.params)
`
所以這里我的參數是 x。 在我的目標函數中,我將數據的值設為 50,這對應於 x 為 0。我將參數的初始值初始化為接近 0 的值,因此我將其設置為 -3。
當您打印 result.params 時,您會看到它收斂到 0。
現在,如果我將 amp cen 和 wid 作為參數,它會給我一個錯誤
類型錯誤:* 之后的objective() 參數必須是可迭代的,而不是 numpy.float64
`
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Parameters, minimize
from numpy import exp, linspace, random
def gaussian(x, amp, cen, wid):
return amp * exp(-(x-cen)**2 / wid)
x = linspace(-10, 10, 101)
data = gaussian(x, 2.33, 0.21, 1.51) + random.normal(0, 0.2, x.size)
Model = gaussian(x, 2.33,0.21,1.51)
plt.plot(x, data, label = 'data')
plt.plot(x, Model, label = 'Model')
plt.legend()
plt.grid(True)
plt.show()
d = 50
print ("\nThe data value at {} is {}\n".format(0, data[0+d]))
params = Parameters()
params.add('x', value =-5)
params.add('amp', value = 1)
params.add('cen', value = 1)
params.add('wid', value = 1)
def objective(params, data):
x = params['x']
amp = params['amp']
cen = params['cen']
wid = params['wid']
m = gaussian(x, amp, cen, wid)
return data - m
result = minimize(objective, params=params, args=( data[d]))
print(result.params)
`
我究竟做錯了什么?
好吧,基本上您是在要求更改 4 個不同的變量( x
、 amp
、 cen
和wid
)以匹配 1 個數據點: data[d]
。 你得到的錯誤信息:
......
out = self.userfcn(params, *self.userargs, **self.userkws)
TypeError: objective() argument after * must be an iterable, not numpy.float64
是擬合告訴您目標函數的返回值必須是數組,而不是單個浮點數。
4 個變量的擬合至少需要 4 個y
值。 否則,您可以在連續的值范圍內更改x
、 amp
、 cen
和wid
以使gaussian(x, amp, can, wid)
匹配data[d]
- 該問題沒有單一的解決方案。
如果這個想法是找到的值x
為其高斯函數,有一個特別的y
值,你可以做,使用“求根” -至少給出可能的范圍內,將有至少2個x
的值每個有效的y
值。
為此,您可以使用scipy.optimize.root
查找gaussian(x, amp, cen, wid) - data[d]
為零的值:
def objective(x, amp, cen, wid, yval):
return gaussian(x, amp, cen, wid) - yval
from scipy.optimize import root
init_x = 0.0 # initial guess for `x` value
result = root(objective, init_x, (100, 1.22, 2.5, data[50]))
print(result.x)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.