首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >利用scipy.optimize.least_squares对光谱数据进行高斯混合模型拟合

利用scipy.optimize.least_squares对光谱数据进行高斯混合模型拟合
EN

Stack Overflow用户
提问于 2018-05-31 04:54:20
回答 1查看 511关注 0票数 1

我正在尝试使用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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50613214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档