【问题标题】:Use scipy.optimize.least_squares to fit Gaussian Mixture Model to spectral data使用 scipy.optimize.least_squares 将高斯混合模型拟合到光谱数据
【发布时间】:2018-11-09 19:29:59
【问题描述】:

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

【问题讨论】:

    标签: python-3.x scipy gaussian minimization mixture-model


    【解决方案1】:

    只有几件事需要改变。如果要拟合数据,最好使用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
    

    然后运行优化,那些 jacobian 用于不同的功能,所以不要使用它们。使用关键字args 将函数所需的额外参数作为元组传递:

    res = least_squares(sumGauss, initial_values, method='trf', args=(x,y))

    您优化的参数: res.x

    绘图,res.fun 是残差:

    import matplotlib.pyplot as plt
    plt.plot(y,'o');plt.plot(res.fun+y);plt.plot(res.fun)
    

    【讨论】:

      猜你喜欢
      • 2017-02-26
      • 2014-08-02
      • 2018-07-19
      • 1970-01-01
      • 2021-09-30
      • 2014-10-08
      • 2019-09-10
      • 1970-01-01
      • 2020-08-12
      相关资源
      最近更新 更多