1

他の質問に対するユーザーの回答について質問したかったのですが、何らかの理由でコメント ボックスが表示されません。私が何か間違ったことをしているなら、ごめんなさい。

いずれにせよ、この返信に関して: https://stackoverflow.com/a/11507723/1950164

次の質問があります。このコードを使用して、さまざまなデータをさまざまな関数に適合させるにはどうすればよいですか? 私は彼が解決したものと同様の問題を抱えています.累積分布に適合させたいと思っています. そこで、コードを一般化しようと始めました。私は3つの変更を行いました:

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()
4

1 に答える 1

0

関数とは異なり、math関数numpyはベクトル入力を受け入れます。

>>> import numpy, math
>>> numpy.exp([4,5])
array([  54.59815003,  148.4131591 ])
>>> math.exp([4,5])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a float is required
于 2014-02-01T18:45:14.433 に答える