繁体   English   中英

Python 中的非对称高斯拟合

[英]Asymmetric Gaussian Fit in Python

我正在尝试将非对称高斯拟合到此数据: http://ge.tt/99iNaL53 (csv 文件)。

我曾尝试使用 lmfit 的倾斜高斯 model 和样条曲线,但我无法让高斯 model 拟合得很好,样条曲线不是我想要的(我不想要样条曲线完全符合如下所示的数据,并且改变平滑水平无济于事)。

下面是使用上述数据生成 plot 的代码。 第二个图是我试图实现的目标,即从拟合中读取上升和衰减时间。

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import CubicSpline
from scipy.interpolate import UnivariateSpline
from lmfit.models import SkewedGaussianModel

data = np.loadtxt('data.csv', delimiter=',')

x = data[:,0]
y = data[:,1]

# Skewed Gaussian fit
model = SkewedGaussianModel()
params = model.make_params(amplitude=400, center=3, sigma=7, gamma=1)
result = model.fit(y, params, x=x)

# Cubic Spline
cs = CubicSpline(x, y)
x_range = np.arange(x[0], x[-1], 0.1)

# Univariate Spline
us = UnivariateSpline(x, y, k = 1)

# Univariate Spline (smoothed)
us2 = UnivariateSpline(x, y, k = 5)

plt.scatter(x, y, marker = '^', color = 'k', linewidth = 0.5, s = 10, label = 'data')
plt.plot(x_range, cs(x_range), label = 'Cubic Spline')
plt.plot(x_range, us(x_range), label = 'Univariate Spline, k = 1')
plt.plot(x_range, us2(x_range), label = 'Univariate Spline, k = 5')
plt.plot(x, result.best_fit, color = 'red', label = 'Skewed Gaussian Attempt')
plt.xlabel('x')
plt.ylabel('y')
plt.yscale('log')
plt.ylim(1,500)
plt.legend()
plt.show()

数据和拟合尝试 例子

这里有问题吗? 实际上,我没有看到一个。

lmfit结果最适合偏斜的高斯 model。 您已选择 plot 对数刻度的结果。 这完全改变了对合身质量或不合身的看法。

看起来你期待更好的合身,但不是*太好 好吧,看起来您的数据并不能完美地由单个倾斜的高斯表示。 好像你没想到会这样。 您可以为 model function 尝试不同的 forms,比如说倾斜的洛伦兹或其他东西。 但是您的数据有那个低x肩,这绝对不像您未引用的数字。

我为 J. Chem 写了一些东西。 埃德。 [1]涉及将非对称高斯函数拟合到数据,您可以在此处找到核心 repo [2] ,但下面是我如何拟合data集的片段,其中x = data[:,0]y = data[:,1]到您正在使用的 function 类型:

import numpy as np
from scipy.optimize import leastsq
from scipy.special import erf

initials = [6.5, 13, 1, 0] # initial guess

def asymGaussian(x, p):
    amp = (p[0] / (p[2] * np.sqrt(2 * np.pi)))
    spread = np.exp((-(x - p[1]) ** 2.0) / (2 * p[2] ** 2.0))
    skew = (1 + erf((p[3] * (x - p[1])) / (p[2] * np.sqrt(2))))
    return amp * spread * skew

def residuals(p,y,x):
    return y - asymGaussian(x, p)

# executes least-squares regression analysis to optimize initial parameters
cnsts = leastsq(
    residuals, 
    initials, 
    args=(
        data_set[:,1], # y value
        data_set[:,0]  # x value
        ))[0]

y = asymGaussian(data[:,0], cnsts)

最后只是 plot (y, data[:,0]) 希望这可以帮助!

[1] https://pubs.acs.org/doi/10.1021/acs.jchemed.9b00818
[2] https://github.com/1mikegrn/pyGC

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM