いくつかの科学データを評価するために Python (2.7) プログラムを作成しました。その主なタスクは、このデータを特定の関数に適合させることです (1)。これは非常に大量のデータであるため、プログラムはマルチプロセッシングを使用して複数のコアにジョブを分散します (= "1 セットのデータに合わせる")。最初の試みで、scipy.optimize の curve_fit を使用してフィッティング プロセスを実装しました。これはかなりうまく機能します。
ここまでは順調ですね。次に、関数 (1) とガウス分布の畳み込みによって、データがより正確に記述されることがわかりました。最初にデータを関数 (1) に適合させ、その結果として推測値を取得してから、データを再度畳み込みに適合させるという考え方でした。データは非常にノイズが多く、7 つのパラメーターを使用して畳み込みに適合させようとしているため、今回の結果はかなり悪いものでした。特にガウス パラメーターは、ある程度物理的に不可能でした。
そこで、PyMinuit でフィッティング プロセスを実装してみました。これにより、パラメータを特定の境界内 (正の振幅など) に制限できるためです。以前に Minuit を使用したことがなく、小さく始めようとしているので、フィッティング プロセスの最初の (「簡単な」) 部分を書き直しました。ジョブを実行するコード スニペットは次のようになります (簡略化)。
import minuit
import numpy as np
# temps are the x-values
# pol are the y-values
def gettc(temps, pol, guess_values):
try:
efunc_chi2 = lambda a,b,c,d: np.sum( (efunc(temps, a,b,c,d) - pol)**2 )
fit = minuit.Minuit(efunc_chi2)
fit.values['a'] = guess_values[0]
fit.values['b'] = guess_values[1]
fit.values['c'] = guess_values[2]
fit.values['d'] = guess_values[3]
fit.fixed['d'] = True
fit.maxcalls = 1000
#fit.tol = 1000.0
fit.migrad()
param = fit.args
popc = fit.covariance
except minuit.MinuitError:
return np.zeros(len(guess_values))
return param,popc
efunc() は関数 (1) です。パラメータ d は、現在使用していないため固定です。
PyMinuit 関数リファレンス
最後に、実際の問題があります: スクリプトを実行すると、Minuit はほぼすべてのフィットに対して出力します。
VariableMetricBuilder: Tolerance is not sufficient - edm is 0.000370555 requested 1e-05 continue the minimization
edm の異なる値で stdout に。フィットは問題なく動作しますが、印刷によりプログラムの速度が大幅に低下します。fit.tol を増やそうとしましたが、さらに高い edm を返すデータセットがたくさんあります。次に、実際に機能するこのソリューションを使用して、 fit.migrad() の出力を非表示にしようとしました。そして今、奇妙なことが起こります。プログラムの途中で、すべてのコアのプロセスが同時に失敗します。最初のフィットではなく、データセット全体の途中です。私が唯一変えたのは、
with suppress_stdout_stderr():
fit.migrad()
これはかなり長い導入であることは承知していますが、フレームワーク全体を知っていると、より役立つと思います。誰かがこの問題にアプローチする方法について何か考えを持っているなら、私は非常に感謝しています.
注: 関数 (1) は次のように定義されます。
def efunc(x,a,b,c,d):
if x < c:
return a*np.exp(b*x**d)
else:
return a*np.exp(b*c**d) # therefore constant
efunc = np.vectorize(efunc)