我正在尝试使用scipy.minimize
函数来拟合3个高斯的总和与实验数据。
我需要你的帮助来正确地传递目标函数,因为这似乎是错误指向的地方。显然,我是Python的新手。
对于这种情况,scipy.minimize
的文档没有明确的示例,并且之前在这里提出的关于GMM的问题也表达得很糟糕。敬请指教...
import numpy
from matplotlib import pyplot
from scipy.optimize import minimize, rosen_der, rosen_hess
x = numpy.arange(0, 55)
y = [-0.00058032, -0.00063992, -0.00057869, -0.00058395, -0.00053528, -0.0002694, -0.0003716, -0.000284, 0.00104651, 0.00209935, 0.00360213, 0.00502779, 0.00625538, 0.00715873, 0.00753231, 0.00712235, 0.00689089, 0.0061677, 0.00544124, 0.00478251, 0.00487787, 0.00415067, 0.00368579, 0.00370327, 0.00323007, 0.0029862, 0.00250529, 0.00219493, 0.00212242, 0.00209026, 0.0020827, 0.00204044, 0.00218628, 0.00236552, 0.00245056, 0.00282404, 0.0031072, 0.00332862, 0.00351655, 0.00367349, 0.00387923, 0.00395812, 0.00388796, 0.00379902, 0.00369458, 0.00350222, 0.00337815, 0.0032241, 0.00306897, 0.00294152, 0.00276761, 0.00257586, 0.00231613, 0.00211727, 0.00190347]
# experimental data: y
# objective function that is to be minimized: G1 + G2 + G3 - y
def sumGauss(x, y, *args):
m1, m2, m3, s1, s2, s3, k1, k2, k3 = args
ret = -y
ret += k1 * numpy.exp(-(x - m1)**2 / (2 * s1**2))
ret += k2 * numpy.exp(-(x - m2)**2 / (2 * s2**2))
ret += k3 * numpy.exp(-(x - m3)**2 / (2 * s3**2))
return ret
initial_values = [15, 29, 43, 1, 1, 1, 1, 1, 1]
res = minimize(sumGauss(x, y), initial_values, method='trust-exact',
jac=rosen_der, hess=rosen_hess,
options={'gtol': 1e-8, 'disp': True})
以下是错误消息:
Traceback (most recent call last):
File "fit_gaussian.py", line 64, in <module> res = minimize(sumGauss(x, y), params, method='trust-exact',
File "fit_gaussian.py", line 41, in sumGauss
m1, m2, m3, s1, s2, s3, k1, k2, k3 = args
ValueError: not enough values to unpack (expected 9, got 0)
发布于 2018-05-31 17:47:13
只有几件事需要改变。如果想要拟合数据,最好使用least_squares
from scipy.optimize import least_squares
将y
设置为numpy数组,这样就可以对其执行算术运算:
y=numpy.array(y)
不要解压args
,它们应该保持为单个输入。优化函数通常作用于第一个输入参数,因此将其向前移动:
def sumGauss(args, x, y):
m1, m2, m3, s1, s2, s3, k1, k2, k3 = args
ret = -y
ret += k1 * np.exp(-(x - m1)**2 / (2 * s1**2))
ret += k2 * np.exp(-(x - m2)**2 / (2 * s2**2))
ret += k3 * np.exp(-(x - m3)**2 / (2 * s3**2))
return ret
然后运行优化,这些jacobians用于不同的函数,所以不要使用它们。使用关键字args
将函数所需的额外参数作为元组传递
res = least_squares(sumGauss, initial_values, method='trf', args=(x,y))
优化后的参数:res.x
Plot,res.fun
是残差:
import matplotlib.pyplot as plt
plt.plot(y,'o');plt.plot(res.fun+y);plt.plot(res.fun)
https://stackoverflow.com/questions/50613214
复制相似问题