在 Python 中使用多个高斯分布拟合数据
Fitting data with multiple Gaussian profiles in Python
我有一些数据 (data.txt) 并且正在尝试在 Python 中编写代码以不同的方式将它们与高斯分布拟合以获得和比较每个中的峰分离和曲线下面积案例:
- 具有两个高斯分布(考虑顶部的小峰并忽略肩部;红色分布)
- 具有两个高斯分布(忽略顶部的小峰并考虑顶部和肩部的整个单峰;黑色分布)
- 具有三个高斯分布(考虑到肩部两个较短的峰上的高峰;绿色分布)
我尝试了几个脚本,但都失败了。
这些图中的配置文件是假的,我添加它们只是为了更好地说明我的意思。
一种方法如下:
- 定义要适合数据的函数,即应该包含在其中的所有分量的总和。在您的情况下,这是多个高斯分布。
- 找到参数的初始猜测。
- 根据您的喜好使用您的拟合函数来拟合数据。
我查看了您的数据,下面是一个使用 SciPy 的 curve_fit
方法拟合三个高斯分量和连续偏移的非常简单的示例。我会把剩下的留给你。这应该也能让你弄清楚其他情况。请注意,初始猜测通常很重要,因此最好以某种方式进行受过教育猜测,以尽可能接近最佳值。
代码
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np
def gaussian(x, A, x0, sig):
return A*np.exp(-(x-x0)**2/(2*sig**2))
def multi_gaussian(x, *pars):
offset = pars[-1]
g1 = gaussian(x, pars[0], pars[1], pars[2])
g2 = gaussian(x, pars[3], pars[4], pars[5])
g3 = gaussian(x, pars[6], pars[7], pars[8])
return g1 + g2 + g3 + offset
vel, flux = np.loadtxt('data.txt', unpack=True)
# Initial guesses for the parameters to fit:
# 3 amplitudes, means and standard deviations plus a continuum offset.
guess = [4, -50, 10, 4, 50, 10, 7, 0, 50, 1]
popt, pcov = curve_fit(multi_gaussian, vel, flux, guess)
plt.figure()
plt.plot(vel, flux, '-', linewidth=4, label='Data')
plt.plot(vel, multi_gaussian(vel, *popt), 'r--', linewidth=2, label='Fit')
plt.legend()
plt.show()
结果
scikit-learn 有一个 GaussianMixtureModel 的实现,它可以做到这一点。有关示例,请参阅 user guide。
我有一些数据 (data.txt) 并且正在尝试在 Python 中编写代码以不同的方式将它们与高斯分布拟合以获得和比较每个中的峰分离和曲线下面积案例:
- 具有两个高斯分布(考虑顶部的小峰并忽略肩部;红色分布)
- 具有两个高斯分布(忽略顶部的小峰并考虑顶部和肩部的整个单峰;黑色分布)
- 具有三个高斯分布(考虑到肩部两个较短的峰上的高峰;绿色分布)
我尝试了几个脚本,但都失败了。
这些图中的配置文件是假的,我添加它们只是为了更好地说明我的意思。
一种方法如下:
- 定义要适合数据的函数,即应该包含在其中的所有分量的总和。在您的情况下,这是多个高斯分布。
- 找到参数的初始猜测。
- 根据您的喜好使用您的拟合函数来拟合数据。
我查看了您的数据,下面是一个使用 SciPy 的 curve_fit
方法拟合三个高斯分量和连续偏移的非常简单的示例。我会把剩下的留给你。这应该也能让你弄清楚其他情况。请注意,初始猜测通常很重要,因此最好以某种方式进行受过教育猜测,以尽可能接近最佳值。
代码
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np
def gaussian(x, A, x0, sig):
return A*np.exp(-(x-x0)**2/(2*sig**2))
def multi_gaussian(x, *pars):
offset = pars[-1]
g1 = gaussian(x, pars[0], pars[1], pars[2])
g2 = gaussian(x, pars[3], pars[4], pars[5])
g3 = gaussian(x, pars[6], pars[7], pars[8])
return g1 + g2 + g3 + offset
vel, flux = np.loadtxt('data.txt', unpack=True)
# Initial guesses for the parameters to fit:
# 3 amplitudes, means and standard deviations plus a continuum offset.
guess = [4, -50, 10, 4, 50, 10, 7, 0, 50, 1]
popt, pcov = curve_fit(multi_gaussian, vel, flux, guess)
plt.figure()
plt.plot(vel, flux, '-', linewidth=4, label='Data')
plt.plot(vel, multi_gaussian(vel, *popt), 'r--', linewidth=2, label='Fit')
plt.legend()
plt.show()
结果
scikit-learn 有一个 GaussianMixtureModel 的实现,它可以做到这一点。有关示例,请参阅 user guide。