gnuplotプロット例 : 最小二乗法の可視化的説明

データプロットを関数(ax + b)でフィッティング

始めに

 最小二乗法を用いた数値解析によるフィッティングを可視化してみることにしました。
実験で得られた測定データ、表計算や解析ソフトでは簡単に近似曲線と関数が得ることが出来ます。こういうのは実際どういった処理で求めているのかを意識することは無いかも知れません。ただあまりブラックボックスな技術にばかり頼りっきりでもしょうがないので、ちょっと試しに可視化してみることにしました。

用いるデータ

さて、用いたデータプロットは以下のようになっています。これを
関数 f(x) = ax + b
でフィッティング、つまり最適解となる変数a, bを求めます。
用いるデータプロット
用いるデータプロット

ここでは最小二乗法については説明しませんが、手順としてはまず適当にaとbをそれぞれある値に決めます。そこで定まった関数とデータプロットの各点との差を求めます。ここで差は二乗してデータプロット全ての点のそれを合計します(便宜上sumと置く)。そうするとa, b, sumのワンセットが得られます。あとはこれをa, bの値をそれぞれ変化させて、どのパラメーターを取ればsumが最小となるかを求めてそれを解とします。

可視化してみる

  解だけ求めるなら計算してsumが最小となる点を抽出すればいいのですが、その過程を可視化するためにもう少し準備をします。
 まず計算により得られるデータセットは以下の3列からなります。
a1, b1, sum1
a2, b2, sum2
a3, b3, sum3
a4, b4, sum4


なので、aをx、bをy、sumをzとして三次元プロットをしてみます。計算過程を動画にすると以下のようになります(左側がデータプロットと関数の二次元プロット、右側が三次元プロット)。左側のグラフではデータプロットの各点と関数との差を矢印で図示するようにしています。

(Youtubeにアップロードした動画、処理にはPythonによるプログラミングも併用)

 この動画では大雑把にaとbの範囲を設定して計算しているので、どこが最小なのかはいまいち分かり難くなっています。これは、データプロットから大きく外れたときのsumの値がかなり大きくなるので、全部一つの三次元プロットにしてしまうと小さいsumの領域が埋もれてしまうからです.
 もう少し詳しく見るために結果の一部分だけ抜き出して、sumが小さい領域だけを示すと以下のようになります。
三次元プロット(カラーマップ)
真上から見た三次元プロット(カラーマップ)

 ここでは横軸がa、縦軸がbです。そしてカラーマップが示すように色が暗くなっていくほどz、つまりsumの値が小さいことを示します。グラフを見るとaは0〜1.5、bは-5〜10の範囲の色が黒くsumの値が小さくなっています。なので、解としてはこの範囲のどこかにあるだろうと推測できるわけです。より詳しく求めるなら、ここの範囲に絞ってより精度を上げて計算していきます。

最小二乗法の結果

 そんなこんなで、あれやこれやして求めた結果は
a = 0.52727
b = 3.18182

となりました。というわけで求めたい関数は
f(x) = 0.52727x + 3.18182
となります(有効数値をどう扱うかは今回は考慮しません)。 この結果を始めのデータプロットに合わせると以下のようになります。

データプロットと最小二乗法で求めた関数
データプロットと最小二乗法で求めた関数
 だいぶ端折り気味に説明してきましたが、こうやって可視化してみることで最小二乗法の理解につながりやすくなると思います。
(この記事に書いたのは基本的なやり方で、他には解析的に求める方法や数値解析でもいろいろと計算アルゴリズムがあります)


gnuplot関連のブログ記事

コメント

スポンサーリンク


このブログの人気の投稿

Ubuntu Softwareが起動しないのでいろいろと調べてみる(Ubuntu 20.04.1 LTS)

gnuplotでプロットなどの色をcolornameの指定で変更する

gnuplot : グラフにグリッド線を描く方法(set grid)

gnuplot : プロット画像のサイズ指定について(set sizeとの違い)

Pythonのformat()を使って1桁の16進数でも2桁で出力する方法