你會如何使用scipy.optimize.curve_fit在任何y以適應任意鍾/孔曲線或X抵消任何高斯曲線?如何適應與SciPy的
我發現了幾個例子,但他們通常是隻能夠適應非常特殊類型的鐘形曲線的,如果最初的猜測是不緊密,或曲線已經反轉或者甚至它們通常會失敗略微偏移。
該段代碼描述我目前的嘗試:
import os,sys
import numpy as np
import pylab
import scipy
from scipy.optimize import curve_fit
from pylab import *
from numpy import *
def gauss1(x, *p):
A, mu, sigma = p
return A*np.exp(-(x-mu)**2/(2.*sigma**2))
def gauss2(x, *args):
m1, m2, m3, s1, s2, s3, k1, k2, k3 = args
ret = k1*scipy.stats.norm.pdf(x, loc=m1 ,scale=s1)
ret += k2*scipy.stats.norm.pdf(x, loc=m2 ,scale=s2)
ret += k3*scipy.stats.norm.pdf(x, loc=m3 ,scale=s3)
return ret
def gauss3(x, a, b, c, d, x0):
return a*np.exp(-(x-x0)**2/(2*d**2)) + c
ydata = np.array([0.001, 0.1, 0.5, 0.75, 0.9, 1.0, 0.9, 0.75, 0.5, 0.1, 0.001])
xdata = np.array(xrange(len(ydata)))
# Test transformations.
#ydata = 1 - ydata # flip => completely breaks fit
#ydata = ydata + 100 # offset y => distorts fit
#xdata = xdata + 10 # offset x => completely breaks fit
# Equations and initial parameters.
func, p0 = gauss1, [1., 0., 1.] #doesn't handle invert, of x/y offsets
#func, p0 = gauss2, [-50, 3, 20, 1, 1, 1, 1, 1, 1] #handles x-offset, but nothing else
#func, p0 = gauss3, [1,1,1,1,1] #doesn't handle anything
coeff, var_matrix = curve_fit(func, xdata, ydata, p0=p0)
yfit = func(xdata, *coeff)
pylab.plot(xdata, ydata, 'o', label='data', markersize=5)
plt.plot(xdata, yfit, label='Fitted data')
pylab.ylim(ydata.min()-1, ydata.max()+1)
pylab.legend(loc='best')
fn = 'test5_gaussian.png'
pylab.savefig(fn)
pylab.show()
print 'plot saved to %s' % fn
我使用3種不同類型的高斯公式,沒有太大的成功。您可以通過取消註釋不同的轉換和/或方程來查看圖表,瞭解每個圖表是如何破解的。
是否有更好的高斯公式我可以使用,或以某種方式計算初始猜測最大化,它會適應可能性有多大?
你應該做一些閱讀了非線性擬合數據分析。對於大量的分析,如果你沒有接近最初的猜測,那麼你會發現它「爆炸」,你會得到一個不好的結果。這不是Python的限制,而僅僅是數學的限制。 – Ffisegydd
在試圖預先優化猜測?您可以獲取最大數據並假定它接近您的峯值位置。如果你能得到「基準線」的價值,你可以大致計算FWHM的值,並將其用於你的寬度猜測。基線本身會給你粗略估計你的垂直偏移量。最後,基線強度和峯值最大強度之間的差異可以讓您猜測峯值強度。 – Ffisegydd