【问题标题】:Python-load data and do multi Gaussian fitPython 加载数据并进行多高斯拟合
【发布时间】:2015-01-12 04:54:47
【问题描述】:

我一直在寻找一种方法来对我的数据进行多重高斯拟合。到目前为止,我发现的大多数示例都使用正态分布来生成随机数。但我有兴趣查看我的数据图并检查是否有 1-3 个峰值。

我可以做到这一点,但我不知道如何做到更多。

比如我有这个数据:http://www.filedropper.com/data_11

我尝试过使用 lmfit,当然还有 scipy,但效果不佳。

感谢您的帮助!

【问题讨论】:

  • 您的问题并不完全清楚:您想将高斯拟合到您的(相当嘈杂的)数据中吗?你想找到最大值的位置吗?数据是 1-3 个高斯的总和,您想得到每个的均值和标准方差吗?
  • 嗨!感谢您的回复:) 我想为每个峰值拟合一个高斯。
  • " 数据是 1-3 个高斯的总和,你想得到每个的均值和标准方差吗?"正是!

标签: python python-2.7 curve-fitting gaussian


【解决方案1】:

简单地制作单个高斯和的参数化模型函数。为您的初始猜测选择一个合适的值(这是一个非常关键的步骤),然后让scipy.optimize 稍微调整一下这些数字。

你可以这样做:

import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize

data = np.genfromtxt('data.txt')
def gaussian(x, height, center, width, offset):
    return height*np.exp(-(x - center)**2/(2*width**2)) + offset
def three_gaussians(x, h1, c1, w1, h2, c2, w2, h3, c3, w3, offset):
    return (gaussian(x, h1, c1, w1, offset=0) +
        gaussian(x, h2, c2, w2, offset=0) +
        gaussian(x, h3, c3, w3, offset=0) + offset)

def two_gaussians(x, h1, c1, w1, h2, c2, w2, offset):
    return three_gaussians(x, h1, c1, w1, h2, c2, w2, 0,0,1, offset)

errfunc3 = lambda p, x, y: (three_gaussians(x, *p) - y)**2
errfunc2 = lambda p, x, y: (two_gaussians(x, *p) - y)**2

guess3 = [0.49, 0.55, 0.01, 0.6, 0.61, 0.01, 1, 0.64, 0.01, 0]  # I guess there are 3 peaks, 2 are clear, but between them there seems to be another one, based on the change in slope smoothness there
guess2 = [0.49, 0.55, 0.01, 1, 0.64, 0.01, 0]  # I removed the peak I'm not too sure about
optim3, success = optimize.leastsq(errfunc3, guess3[:], args=(data[:,0], data[:,1]))
optim2, success = optimize.leastsq(errfunc2, guess2[:], args=(data[:,0], data[:,1]))
optim3

plt.plot(data[:,0], data[:,1], lw=5, c='g', label='measurement')
plt.plot(data[:,0], three_gaussians(data[:,0], *optim3),
    lw=3, c='b', label='fit of 3 Gaussians')
plt.plot(data[:,0], two_gaussians(data[:,0], *optim2),
    lw=1, c='r', ls='--', label='fit of 2 Gaussians')
plt.legend(loc='best')
plt.savefig('result.png')

如您所见,这两种拟合(视觉上)几乎没有区别。因此,您无法确定源中是否存在 3 个高斯函数或只有 2 个。但是,如果您必须进行猜测,请检查最小的残差:

err3 = np.sqrt(errfunc3(optim3, data[:,0], data[:,1])).sum()
err2 = np.sqrt(errfunc2(optim2, data[:,0], data[:,1])).sum()
print('Residual error when fitting 3 Gaussians: {}\n'
    'Residual error when fitting 2 Gaussians: {}'.format(err3, err2))
# Residual error when fitting 3 Gaussians: 3.52000910965
# Residual error when fitting 2 Gaussians: 3.82054499044

在这种情况下,3 高斯给出了更好的结果,但我的初步猜测也相当准确。

【讨论】:

  • 您好。非常感谢您的回答。我曾尝试获取两个单独的高斯,然后将它们组合起来,但在看到您的解决方案后,我明白这是一个错误的想法。请您向我解释一下“中心”和“偏移”参数是什么?非常感谢您的帮助!
  • 这将是高斯的平均值和给定的垂直偏移量。检查我对Gaussian 的定义以验证;-) 欢迎使用 Stackoverflow。如果对您有帮助,请不要忘记upvote or accept the answer
  • 嗨奥利弗!再次感谢你 :)我确实理解脚本,但你是怎么猜到的?我会使用 numpy,但我觉得有更简单和更快的东西你做的。再次感谢你:)
  • @astromath,我对平均值的猜测仅仅是基于对数据的视觉检查。但是,您可以使用众多峰值检测算法之一轻松找到两个局部最大值。
  • 好的,谢谢:)我有一些脚本可以完成这项工作。我会看看我能做什么。再次非常感谢 Oliver :)
猜你喜欢
  • 1970-01-01
  • 2017-08-30
  • 2021-03-04
  • 1970-01-01
  • 1970-01-01
  • 2019-07-17
  • 2013-10-12
  • 1970-01-01
  • 2020-06-08
相关资源
最近更新 更多