10

私の友人が、単純な多項式フィットに関する gnuplot の奇妙な動作を発見しました。誰かこれを説明できますか?

ファイルは次のとおりです。

#!/usr/bin/gnuplot -p

f(x) = B*(x**4) + A
fit f(x) "data.txt" using ($1+273.14):2 via A, B

plot    "data.txt" using ($1+273.14):2 notitle,\
        f(x) notitle

データは次のとおりです。

# content of data.txt
350 3.856
330 3.242
290 2.391
250 1.713
210 1.181
170 0.763
130 0.437

結果のプロットは緑の線です。青い線は、基本的に同じ形式の別の関数を使用すると、はるかによく適合することを示しています。緑の線の場合、A は定数値 (A = 0.2123、つまり約 B*300^4) に置き換えられました。

奇妙なフィッティング動作 gnuplot

f(x) = B*(x**4) - 0.2123したがって、緑色の線は、はるかに優れた結果をもたらし、B*x 4 + A の形式であるため、ここでは明らかに最適ではありません。緑色の近似では、パラメータ **A は gnuplot によって単純に無視され、近似アルゴリズムによって変更されません。A と B に異なる初期値を設定しても、あまり役に立たないようです。A の値は、その初期値に対して決して変化しません。私の友人と私は、Ubuntu に付属している標準の Gnuplot バージョン、gnuplot 4.4 patchlevel 3 を使用しています。

4

2 に答える 2

9

これは非常に優れた (そして複雑な) 質問であり、私には完全な答えはありませんが、うまくいけば次のことが明らかになるでしょう。

Fit は、最小二乗近似ルーチン ( Levenberg–Marquardt ) を使用します。これは、「良い」解に繰り返し収束します。どの程度優れたソリューションが必要かは、FIT_LIMIT変数によって決まります。デフォルトでは、FIT_LIMIT は (保守的な) に設定されています1.e-5。A を変更する場合と比較して、反復ルーティングで B の値を変更することにより、データがはるかに速く収束するようです。あなたの期待 (あなたはより良い適合を得ることを期待しているのでFIT_LIMIT、より低い値に設定します -- 私はそれを1.e-14)、より良い結果が得られます。ここで支払う代償は、フィッティングが収束するまでにはるかに長い時間がかかることです (または発散することさえあります。私はフィッティングの専門家ではありません)。ここで重要なことは、関数のフィッティングは科学というより芸術であるということです。最適なフィッティングなどというものは存在せず、十分なフィッティングのみが存在します。

また、アルゴリズムは残差の二乗の局所最小化 (指定した許容値を満たす) を検索することに注意してください。グローバルな最小値が見つかることを保証するものではありません。

#!/usr/bin/gnuplot -p

FIT_LIMIT=1.e-14
f(x) =A +  B*(x**4)
fit f(x) "data.txt" using ($1+273.14):2 via A, B

plot     "data.txt" using ($1+273.14):2 notitle,\
         f(x) notitle

また、gnuplot が間違った最小値に収束していることに気付いた場合は、次のようにして当てはめルーチンを「種付け」できます。

FIT_LIMIT=1.e-14
f(x) =A +  B*(x**4)
A=1.3  #initial guess for A
fit f(x) "data.txt" using ($1+273.14):2 via A, B

plot     "data.txt" using ($1+273.14):2 notitle,\
         f(x) notitle
于 2012-06-17T22:27:44.377 に答える
6

以下のコードを試してみてください。トリックは、x 変数と y 変数の範囲が同じ大きさであることを確認することです。

reset;
plot 'data.txt' u ($1+273.14):2 w p;
f(x, a, b) = a*(1e-2*x)**4 + b; # note the 1e-2 multiplicative factor
a = 1; b = 1; # initial parmeters
fit f(x,a,b) 'data.txt' u (($1+273.14)):2 via a, b
#plot 'data.txt' u (($1+273.14)):2 w p, f(x, a, b) w l
plot 'data.txt' u (($1+273.14)):2 w p, (a*(1e-2)**4)*x**4+b w l
print sprintf("Fit parameters for the fit function a*x^4 + b are :\n\ta = %e, \n\tb = %f", a*(1e-2)**4, b)

グラフのイメージ

于 2014-11-11T20:10:02.713 に答える