簡體   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