第8回 最小二乗法

今回は,データ処理の一つの要である最小二乗法について学ぶ.

実験データや計測データなどには必ず誤差が含まれている.
例えば,理論的な関数関係(比例関係など)が判っているものを計測し,グラフを作成しても,必ずしも一直線上にデータが綺麗にのるとは限らない.

このような場合は,得られたデータ群をもとに,最もよく当てはまる関数を決める方法が用いられる. その代表例が最小二乗法である.

最小二乗法

計測データなど,N 個の点群 (xi, yi ) が得られたとする.
例えば,これらは比例関係にあることが事前に分かっているとして,もっともよく当てはまる関数(この場合は直線)を決定する方法が最小二乗法である.

いま,直線の式を y = ax+b とする

leqstsqr
図1:最小二乗法(1次関数)

直線と,既知の点との差(青色矢印の部分)は,当てはめの度合いを示しており,残差と呼ばれる.
この値の合計が小さいほど,直線が点群の傾向をよく表していると言える.
実際には,残差の符号は正負になるので,これを二乗して足したものを最小化することを考える.

残差の二乗和 e(a,b) は以下の式で表され,直線の係数a,b の関数である.

eqn1.png            (1)

e a, b の2次関数となるので,これが最小となる条件は,

eqn2.png            (2)

である.式を展開して

eqn3.png            (3)

これは,a,b の連立一次方程式であるから,a, b について解いて

eqn4.png            (4)

となる.
それぞれ右辺は既知の点(xi, yi)のみで表されるから,簡単な代数計算により係数a, b が求まる.
注:


課題0

まず,上記の式(4) を各自で導出せよ.紙に記述すること.(提出の必要は無い.)

課題1

以下のソースコード内の配列x,yはそれぞれバネの荷重と変位のデータである.
荷重と変位の間には比例関係があるとして,この比例係数(ばね定数)を求めよ.

  1. まず,ソースコード中のコメントを参考にして,式(4)に出現する各値(x,yの和,和の二乗,二乗の和,内積など)を計算せよ.
  2. 次に,最小二乗法による一次関数の各係数(つまり,直線の傾きと切片)を求めよ.
  3. 計算結果を画面に表示するプログラムを作成せよ.
参考ソースコード:

int main()
{
    const int N = 10;
    /* あるばねにおける 荷重 x[kg] に対する 変位 y[m] */
    double x[N]={1.1, 2.05, 3.0, 4.1,  5.0,  5.9,  7.1, 7.8, 8.9, 10.0};
    double y[N]={1.0, 2.1 , 2.9, 4.05, 5.01, 5.99, 7.0, 8.1, 8.7, 9.5 };

    double a, b;    /* 一次関数の係数 */


    /* 以下にコードを記述 */;

    printf("最小二乗法による係数 a, b \n");
    printf("a = %lf, b = %lf \n", a, b);
            
}
実行例:
  最小二乗法による係数a,b
  a=0.977565, b=0.063278

課題2

計算により得られた係数を使って,以下のようなグラフを描け.