[解決済み] scipy curve_fit raises "OptimizeWarning: パラメータの共分散が推定できませんでした" を上げる
質問
この関数をあるデータに当てはめようとしています。
しかし、私のコードを使用すると
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
def f(x, start, end):
res = np.empty_like(x)
res[x < start] =-1
res[x > end] = 1
linear = np.all([[start <= x], [x <= end]], axis=0)[0]
res[linear] = np.linspace(-1., 1., num=np.sum(linear))
return res
if __name__ == '__main__':
xdata = np.linspace(0., 1000., 1000)
ydata = -np.ones(1000)
ydata[500:1000] = 1.
ydata = ydata + np.random.normal(0., 0.25, len(ydata))
popt, pcov = curve_fit(f, xdata, ydata, p0=[495., 505.])
print(popt, pcov)
plt.figure()
plt.plot(xdata, f(xdata, *popt), 'r-', label='fit')
plt.plot(xdata, ydata, 'b-', label='data')
plt.show()
エラーが表示される
OptimizeWarning: パラメータの共分散を推定できませんでした。
出力します。
この例では、開始と終了は500に近いはずですが、最初の推測と全く変わりません。
どのように解決するのですか?
の警告(エラーではない)が表示されます。
OptimizeWarning: Covariance of the parameters could not be estimated
は、フィットがフィッティングパラメータの不確かさ(分散)を決定できなかったことを意味します。
主な問題は、あなたのモデル関数
f
は、パラメータ
start
と
end
を離散値として、関数形式の変更のための整数の位置として使用されます。
curve_fit
(の他のすべての最適化ルーチンを含む)。
scipy.optimize
) は、パラメータが
連続的
の変数で、離散ではありません。
フィット手順では、パラメータに小さなステップ(通常は機械精度程度)を加えて、変数に対する残差の数値微分(ヤコビアン)を得ようとします。 離散変数として使用される値では、これらの導関数はゼロとなり、フィット手順は、フィット感を向上させるために値を変更する方法を知ることができません。
ステップ関数をデータにフィットさせようとしているようですね。そこで、次のことを試してみてください。
lmfit
(
https://lmfit.github.io/lmfit-py
) は、曲線当てはめの上位インタフェースを提供し、多くの組み込みモデルを持っています。 例えば、これには
StepModel
を使えば、あなたのデータをモデル化することができるはずです。
データを少し修正する(有限のステップを持つようにする)には、以下のスクリプトに
lmfit
はそのようなデータに適合させることができる。
#!/usr/bin/python
import numpy as np
from lmfit.models import StepModel, LinearModel
import matplotlib.pyplot as plt
np.random.seed(0)
xdata = np.linspace(0., 1000., 1000)
ydata = -np.ones(1000)
ydata[500:1000] = 1.
# note that a linear step is added here:
ydata[490:510] = -1 + np.arange(20)/10.0
ydata = ydata + np.random.normal(size=len(xdata), scale=0.1)
# model data as Step + Line
step_mod = StepModel(form='linear', prefix='step_')
line_mod = LinearModel(prefix='line_')
model = step_mod + line_mod
# make named parameters, giving initial values:
pars = model.make_params(line_intercept=ydata.min(),
line_slope=0,
step_center=xdata.mean(),
step_amplitude=ydata.std(),
step_sigma=2.0)
# fit data to this model with these parameters
out = model.fit(ydata, pars, x=xdata)
# print results
print(out.fit_report())
# plot data and best-fit
plt.plot(xdata, ydata, 'b')
plt.plot(xdata, out.best_fit, 'r-')
plt.show()
をプリントアウトするものです。
[[Model]]
(Model(step, prefix='step_', form='linear') + Model(linear, prefix='line_'))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 49
# data points = 1000
# variables = 5
chi-square = 9.72660131
reduced chi-square = 0.00977548
Akaike info crit = -4622.89074
Bayesian info crit = -4598.35197
[[Variables]]
step_sigma: 20.6227793 +/- 0.77214167 (3.74%) (init = 2)
step_center: 490.167878 +/- 0.44804412 (0.09%) (init = 500)
step_amplitude: 1.98946656 +/- 0.01304854 (0.66%) (init = 0.996283)
line_intercept: -1.00628058 +/- 0.00706005 (0.70%) (init = -1.277259)
line_slope: 1.3947e-05 +/- 2.2340e-05 (160.18%) (init = 0)
[[Correlations]] (unreported correlations are < 0.100)
C(step_amplitude, line_slope) = -0.875
C(step_sigma, step_center) = -0.863
C(line_intercept, line_slope) = -0.774
C(step_amplitude, line_intercept) = 0.461
C(step_sigma, step_amplitude) = 0.170
C(step_sigma, line_slope) = -0.147
C(step_center, step_amplitude) = -0.146
C(step_center, line_slope) = 0.127
Lmfitにはたくさんの追加機能があります。 例えば、パラメータ値のいくつかに境界を設定したり、一部が変化しないように固定したい場合、次のようにすることができます。
# make named parameters, giving initial values:
pars = model.make_params(line_intercept=ydata.min(),
line_slope=0,
step_center=xdata.mean(),
step_amplitude=ydata.std(),
step_sigma=2.0)
# now set max and min values for step amplitude"
pars['step_amplitude'].min = 0
pars['step_amplitude'].max = 100
# fix the offset of the line to be -1.0
pars['line_offset'].value = -1.0
pars['line_offset'].vary = False
# then run fit with these parameters
out = model.fit(ydata, pars, x=xdata)
もし、モデルが
Step+Constant
であり、定数は固定であるべきで、モデルを次のように修正することもできます。
from lmfit.models import ConstantModel
# model data as Step + Constant
step_mod = StepModel(form='linear', prefix='step_')
const_mod = ConstantModel(prefix='const_')
model = step_mod + const_mod
pars = model.make_params(const_c=-1,
step_center=xdata.mean(),
step_amplitude=ydata.std(),
step_sigma=2.0)
pars['const_c'].vary = False
関連
-
ピロウズ画像色処理の具体的な活用方法
-
pyCaret効率化乗算器 オープンソース ローコード Python機械学習ツール
-
PythonによるExcelファイルの一括操作の説明
-
FacebookオープンソースワンストップサービスpythonのタイミングツールKats詳細
-
[解決済み】TypeError: unhashable type: 'numpy.ndarray'.
-
[解決済み】お使いのCPUは、このTensorFlowバイナリが使用するようにコンパイルされていない命令をサポートしています。AVX AVX2
-
[解決済み] 'DataFrame' オブジェクトに 'sort' 属性がない
-
[解決済み】Pythonでgoogle APIのJSONコードを読み込むとエラーになる件
-
[解決済み】IndexError: invalid index to scalar variableを修正する方法
-
[解決済み】「OverflowError: Python int too large to convert to C long" on windows but not mac
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python関数の高度な応用を解説
-
PicgoのイメージベッドツールをPythonで実装する
-
Python機械学習Githubが8.9Kstarsに達したモデルインタープリタLIME
-
Pythonの学習とデータマイニングのために知っておくべきターミナルコマンドのトップ10
-
パッケージングツールPyinstallerの使用と落とし穴の回避
-
Python入門 openを使ったファイルの読み書きの方法
-
FacebookオープンソースワンストップサービスpythonのタイミングツールKats詳細
-
[解決済み】csv.Error:イテレータはバイトではなく文字列を返すべき
-
[解決済み】 AttributeError("'str' object has no attribute 'read'")
-
[解決済み】ImportError: bs4という名前のモジュールがない(BeautifulSoup)