我想问一个关于用户对其他问题的回复的问题,但由于某种原因,评论框没有出现。对不起,如果我做错了什么。
无论如何,关于这个回复: https ://stackoverflow.com/a/11507723/1950164
我有以下问题:如何使用此代码将不同的数据适合不同的功能?我有一个与他解决的问题类似的问题,希望我想拟合累积分布。所以我开始尝试概括代码。我做了三个修改:
a)在计算直方图的那一行之后,我添加了
hist = numpy.cumsum(hist)
这将我们的分布转换为累积分布
b) 我定义了一个新函数,而不是示例中的高斯函数
def myerf(x, *p):
A, mu, sigma = p
return A/2. * (1+math.erf((x-mu)/(math.sqrt(2)*sigma)))
这就是高斯的累积分布。
c) 最后,当然,我更改了 curve_fit 线来调用我的函数:
coeff, var_matrix = curve_fit(myerf, bin_centres, hist, p0=p0)
这应该是一个微不足道的练习,但它不起作用。该程序现在返回以下错误消息:
bash-3.2$ python fitting.py
Traceback (most recent call last):
File "fitting.py", line 27, in <module>
coeff, var_matrix = curve_fit(myerf, bin_centres, hist, p0=p0)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 506, in curve_fit
res = leastsq(func, p0, args=args, full_output=1, **kw)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 348, in leastsq
m = _check_func('leastsq', 'func', func, x0, args, n)[0]
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 14, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 418, in _general_function
return function(xdata, *params) - ydata
File "fitting.py", line 22, in myerf
return A/2. * (1+math.erf((x-mu)/(math.sqrt(2)*sigma)))
TypeError: only length-1 arrays can be converted to Python scalars
那么我做错了什么?
奖励:给我一个参考,解释函数参数中的 *p 是什么。
谢谢!
编辑:我尝试使用累积分布数据运行程序,但仍然调用高斯函数。这行得通,你只是不合适。所以错误应该在 myerf 函数的某个地方。
EDIT2:如果我尝试用更简单的东西代替 myerf 函数的返回,比如
return A + mu*x + sigma*x**2
然后它工作。所以在那个回报中一定有一些东西没有做它应该做的事情。
EDIT3:所以,我尝试使用 scipy 中的错误函数而不是数学中的错误函数,现在它可以工作了。我不知道为什么它以前不起作用,但它现在起作用了。所以代码是:
import matplotlib
matplotlib.use('Agg')
import numpy, math
import pylab as pl
from scipy.optimize import curve_fit
from scipy.special import erf
# Define some test data which is close to Gaussian
data = numpy.random.normal(size=10000)
hist, bin_edges = numpy.histogram(data, density=True)
bin_centres = (bin_edges[:-1] + bin_edges[1:])/2
hist = numpy.cumsum(hist)
def myerf(x, *p):
A, mu, sigma = p
return A/2. * ( 1+erf(((x-mu)/(math.sqrt(2)*sigma))) )
# p0 is the initial guess for the fitting coefficients (A, mu and sigma above)
p0 = [1., 0., 1.]
coeff, var_matrix = curve_fit(myerf, bin_centres, hist, p0=p0)
# Get the fitted curve
hist_fit = myerf(bin_centres, *coeff)
pl.plot(bin_centres, hist, label='Test data')
pl.plot(bin_centres, hist_fit, label='Fitted data')
# Finally, lets get the fitting parameters, i.e. the mean and standard deviation:
print 'Fitted mean = ', coeff[1]
print 'Fitted standard deviation = ', coeff[2]
pl.savefig('fitting.png')
pl.show()