web-dev-qa-db-ja.com

Scipyシグモイド曲線フィッティング

いくつかのデータポイントがあり、当てはめ関数を見つけたいと思っています。累積ガウスシグモイド関数が当てはまると思いますが、それを実現する方法がわかりません。

これは私が今持っているものです:

import numpy as np
import pylab
from scipy.optimize
import curve_fit

def sigmoid(x, a, b):
     y = 1 / (1 + np.exp(-b*(x-a)))
     return y

xdata = np.array([400, 600, 800, 1000, 1200, 1400, 1600])
ydata = np.array([0, 0, 0.13, 0.35, 0.75, 0.89, 0.91])

popt, pcov = curve_fit(sigmoid, xdata, ydata)
print(popt)

x = np.linspace(-1, 2000, 50)
y = sigmoid(x, *popt)

pylab.plot(xdata, ydata, 'o', label='data')
pylab.plot(x,y, label='fit')
pylab.ylim(0, 1.05)
pylab.legend(loc='best')
pylab.show()

しかし、次の警告が表示されます。

.../scipy/optimize/minpack.py:779:OptimizeWarning:パラメータの共分散を推定できませんでしたcategory = OptimizeWarning)

誰か助けてもらえますか?私はまた、他の可能性についてもオープンにしています!このデータに何らかの方法でカーブフィットが必要です。

6

たとえば、次のようにして、パラメータに適切な範囲を設定できます。

def fsigmoid(x, a, b):
    return 1.0 / (1.0 + np.exp(-a*(x-b)))

popt, pcov = curve_fit(fsigmoid, xdata, ydata, method='dogbox', bounds=([0., 600.],[0.01, 1200.]))

私は出力を持っています

[7.27380294e-03 1.07431197e+03]

そして曲線は次のようになります

enter image description here

(400,0)の最初のポイントは役に立たないものとして削除されました。追加できますが、結果はそれほど変わりません...

更新

境界が([low_a、low_b]、[high_a、high_b])として設定されていることに注意してください。スケールを[0 ... 0.01]以内に、位置を[600 ... 1200]以内に設定するように求めました。

1

結果のフィットが完全に正しくないことに気づいたかもしれません。 curve_fit引数を使用して、適切な初期パラメータをp0に渡してみます。

popt, pcov = curve_fit(sigmoid, xdata, ydata, p0=[1000, 0.001])

はるかに良い適合を与えるはずであり、おそらく警告もありません。

(デフォルトの開始パラメーターは[1、1]です。これは実際のパラメーターから離れすぎているため、適切に適合させることはできません。)

3
9769953