Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python的高斯拟合_Python_Gaussian - Fatal编程技术网

Python的高斯拟合

Python的高斯拟合,python,gaussian,Python,Gaussian,我正在尝试为我的数据拟合高斯分布(这已经是一个粗略的高斯分布)。我已经采纳了这里的建议,尝试了curve\u fit和leastsq,但我认为我遗漏了一些更基本的东西(因为我不知道如何使用该命令)。 下面是我到目前为止的剧本 import pylab as plb import matplotlib.pyplot as plt # Read in data -- first 2 rows are header in this example. data = plb.loadtxt('part

我正在尝试为我的数据拟合高斯分布(这已经是一个粗略的高斯分布)。我已经采纳了这里的建议,尝试了
curve\u fit
leastsq
,但我认为我遗漏了一些更基本的东西(因为我不知道如何使用该命令)。 下面是我到目前为止的剧本

import pylab as plb
import matplotlib.pyplot as plt

# Read in data -- first 2 rows are header in this example. 
data = plb.loadtxt('part 2.csv', skiprows=2, delimiter=',')

x = data[:,2]
y = data[:,3]
mean = sum(x*y)
sigma = sum(y*(x - mean)**2)

def gauss_function(x, a, x0, sigma):
    return a*np.exp(-(x-x0)**2/(2*sigma**2))
popt, pcov = curve_fit(gauss_function, x, y, p0 = [1, mean, sigma])
plt.plot(x, gauss_function(x, *popt), label='fit')

# plot data

plt.plot(x, y,'b')

# Add some axis labels

plt.legend()
plt.title('Fig. 3 - Fit for Time Constant')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()
我从中得到的是一个高斯形状,这是我的原始数据,和一条直线

另外,我想用点来绘制图形,而不是将它们连接起来。
欢迎您的任何意见

这里是更正的代码:

import pylab as plb
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy import asarray as ar,exp

x = ar(range(10))
y = ar([0,1,2,3,4,5,4,3,2,1])

n = len(x)                          #the number of data
mean = sum(x*y)/n                   #note this correction
sigma = sum(y*(x-mean)**2)/n        #note this correction

def gaus(x,a,x0,sigma):
    return a*exp(-(x-x0)**2/(2*sigma**2))

popt,pcov = curve_fit(gaus,x,y,p0=[1,mean,sigma])

plt.plot(x,y,'b+:',label='data')
plt.plot(x,gaus(x,*popt),'ro:',label='fit')
plt.legend()
plt.title('Fig. 3 - Fit for Time Constant')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()
结果:

你得到一条水平直线,因为它没有收敛


如果将拟合的第一个参数(p0)设置为最大值(y),在示例中为5,而不是1,则会获得更好的收敛性。

在花费数小时试图查找我的错误后,问题在于您的公式:

sigma=总和(y*(x-均值)**2)/n

前面的公式是错误的,正确的公式是这个的平方根

sqrt(和(y*(x-均值)**2)/n)


希望这对您有所帮助

还有另一种方法可以进行拟合,即使用“lmfit”软件包。它基本上使用cuve_配合,但在配合方面要好得多,而且还提供复杂的配合。 下面的链接中给出了详细的分步说明。

应该是

sigma = np.sqrt(sum(y*(x - mean)**2))
解释 您需要良好的起始值,以便
曲线拟合
函数收敛于“良好”值。我真的说不出为什么你的拟合没有收敛(即使你的平均值的定义很奇怪-检查下面),但我会给你一个策略,适用于像你这样的非标准化高斯函数

例子 估计参数应接近最终值(使用-除以所有值之和):

我个人更喜欢使用numpy

对平均值定义的评论(包括开发商的回答) 由于审阅者不喜欢我的代码,我将解释我建议改进代码的情况。显影剂的平均值不符合平均值的正常定义之一

您的定义返回:

>>> sum(x * y)
125
>>> sum(x * y) / len(x)
12.5 #for Python 3.x
开发者定义返回:

>>> sum(x * y)
125
>>> sum(x * y) / len(x)
12.5 #for Python 3.x
加权算术平均数:

>>> sum(x * y) / sum(y)
5.0
同样,您可以比较标准偏差的定义(
sigma
)。与结果拟合图进行比较:

Python2.x用户评论 在Python 2.x中,还应使用新的除法,以避免出现奇怪的结果,或显式转换除法之前的数字:

from __future__ import division
或例如

sum(x * y) * 1. / sum(y)

实际上,你不需要做第一个猜测。简单地做

import matplotlib.pyplot as plt  
from scipy.optimize import curve_fit
from scipy import asarray as ar,exp

x = ar(range(10))
y = ar([0,1,2,3,4,5,4,3,2,1])

n = len(x)                          #the number of data
mean = sum(x*y)/n                   #note this correction
sigma = sum(y*(x-mean)**2)/n        #note this correction

def gaus(x,a,x0,sigma):
    return a*exp(-(x-x0)**2/(2*sigma**2))

popt,pcov = curve_fit(gaus,x,y)
#popt,pcov = curve_fit(gaus,x,y,p0=[1,mean,sigma])

plt.plot(x,y,'b+:',label='data')
plt.plot(x,gaus(x,*popt),'ro:',label='fit')
plt.legend()
plt.title('Fig. 3 - Fit for Time Constant')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()
很好。这更简单,因为猜测并不是一件小事。我有更复杂的数据,无法进行正确的第一次猜测,但简单地删除第一次猜测效果很好:)


注意:更好地使用numpy.exp(),scipy的一个警告说,您缺少一些或您的导入
mean
是乘积之和,因此需要除以
len(x)
如果使用
plt.plot(x,y,'b+',label='data')
它们将只是点。谢谢!顺便问一下,您添加的两个更正是什么?这个答案没有解释为什么更正比原始定义更有效。为了使用不同的数据集,我添加了
yn=max(y)
y/=yn
,然后在绘图过程中,我将
y
更改为
y*yn
plt.plot(x,y*yn,…)
@Hereis如果输入数据非常大(很小),拟合程序可能会在内部遇到浮动溢出(下溢)。标准化为最大输入值通常可以防止这种情况。还有另一个错误:它不是1/n,而是1/sum(y)。退房