10. 一次の最小二乗法 2014/12/14 1 最小二乗法 実験やシミュレーションによって、データが得られた際に、そのデータが従う 式を推定することが多くあります。最小二乗法は、そのような方式の代表的なも のです。 二次元のデータ点の列 {xk , yk }(k = 0, · · · , n − 1) があるとし、その関数形を y = f (x) と予想したとします。関数には、一般にパラメタが含まれていることに 注意します。そのときに、データと予想した関数との二乗誤差 S= n−1 ∑ [yk − f (xk )]2 (1.1) k=0 を最小化することで、データに合う曲線 y = f (x) を求めるのが最小二乗法です。 その最も簡単な形式が、予想した関数として一次関数 y = ax + b を仮定するも のです。このときの二乗誤差は S= n−1 ∑ [yk − axk − b]2 (1.2) k=0 となります。S を最小化するような係数 a と b を求めることを考えましょう。 S は係数 a と b の下に凸な二次関数ですから、a と b を変化させた時の極値、つ まり傾きゼロの点は、極小値となります。従って n−1 ∑ ∂S = −2 xk [yk − axk − b] = 0 ∂a k=0 (1.3) n−1 ∑ ∂S = −2 [yk − axk − b] = 0 ∂b k=0 (1.4) の解、a と b が二乗誤差を最小化します。この式を整理すると a n−1 ∑ x2k k=0 n−1 ∑ a k=0 +b n−1 ∑ xk = k=0 n−1 ∑ xk + b k=0 1 1 = n−1 ∑ k=0 n−1 ∑ k=0 xk yk (1.5) yk (1.6) という連立方程式となります。 ここで、 ∑ 1 n−1 xk n k=0 (1.7) = ∑ 1 n−1 x2 n k=0 k (1.8) hyi = ∑ 1 n−1 yk n k=0 (1.9) hxi = D x2 E hxyi = ∑ 1 n−1 xk yk n k=0 (1.10) を用いると、 D E a x2 + b hxi = hxyi a hxi + b = hyi (1.11) (1.12) と整理できます。従って、解として 1 [hxyi − hxi hyi] σx2 ] 1 [D 2 E b = x hyi − hxi hxyi σx2 a = D σx2 = E x2 − hxi2 (1.13) (1.14) (1.15) を得ることができます。 片対数と両対数 2 9 8 7 5 y y 6 4 3 2 1 0 0 2 4 6 8 10 1010 100 10-10 10-20 10-30 10-40 10-50 10-60 10-70 10-80 10-90 0 x 10 20 30 40 50 60 70 80 90 100 x 図 1: データの例:1 データの従う関数として一次関数を採用した場合の最小二乗法は、簡単に以下 の二つの場合に拡張することができます。 2 図 1 左のようなデータがあったとしましょう。これは、当然直線に従うもので はありません。その大きな特徴は、x が大きくなると、y が急速に小さくなること ですそこで、y 軸を対数で表示してみましょう。それが図 1 右です。直線的に変化 している様子が見えます。y 軸の対数をとったものが、x の一次関数に従うので、 ln y = −ax + b (2.1) のような振る舞いです。ここで、ln y = loge y は自然対数を表していることに注意 します。式 (2.1) の両辺の指数関数をとると y = e−ax+b = eb e−ax (2.2) 101 10 9 8 7 6 5 4 3 2 1 0 100 10-1 10-2 y y つまり、y は x の指数関数に従うことが分かります。 10-3 10-4 10 -5 10 -6 10-7 0 2 4 6 8 10-8 100 10 101 x 102 x 103 104 図 2: データの例:2 次に図 2 左の図を見ましょう。これも、当然直線に従うものではありません。そ の大きな特徴は、x が大きくなると、y が急速に小さくなることですが、図 1 より も、減少の仕方が緩く見えます。そこで、x と y の両方を対数をとって表示したも のが図 2 右です。直線になりました。 ln y = −a ln x + b (2.3) という振る舞いです。式 (2.3) の両辺の指数関数をとると y = eb x−a (2.4) となります。つまり、y は x のべき関数ということが分かります。 3 準備 それでは、プログラムを作成する準備をしましょう。プロジェクト LeastSquare を作成します。さらに、以下の URL から Java ソースファイルを取得し、プロジェ クト LeastSquare のソースファイルの下に置きます。また、ライブラリ MyLib も 設定しましょう。 3 http://http://aoba.cc.saga-u.ac.jp/lecture /ModelingAndSimulation/javasrc/LeastSquare/src.zip 4 データの準備 プロジェクト LeastSquare のソースファイルには、二つのパッケージがありま す。最初のパッケージ data は、最小二乗法で合わせることができるデータを生成 します。クラス DataGenerator を実行すると、三つのデータファイルを生成しま す。直線で合わせることができるデータ out-linear.txt、指数関数で合わせるこ とができるデータ out-exp.txt、そしてべき関数で合わせることができるデータ out-pow.txt の三つです。まずは、gnuplot をもちいて、データを図示しましょう。 5 データの関数形の推計 もう一つのパッケージ leastSquare は、データに対して最小二乗法で関数形を 推計するクラスが入っています。まず、データをファイルから読む必要がありま す。クラス FileRead は、そのようなメソッドもつライブラリです。 メソッド openReader は、ファイル名を指定して、BufferedReader クラスのイ ンスタンスを開きます。メソッド readData は、ファイル名を指定すると、内部で メソッド openReader を使って BufferedReader クラスのインスタンスを開き、そ こから、double 型数値がスペース区切りで一行に二つあると仮定して、データを 読み出します。各行のデータは、xy-座標のクラス Point2D.Double のインスタン スとしてリストになって戻ります。 クラス LeastSquare は、ファイル名を指定してデータを読み出し、直線を使っ た最小二乗法を実行します。このクラスは、前述の指数関数、べき関数にも対応 します。その区別は static public enum Type { Normal, SemiLog, LogLog } という enum 型で定義され、メソッド fit に引数として指定します。 最小二乗法の本体はプライベートメソッド fitSub です (Program 5.1)。引数は xy座標となったデータ点のリストです。指数関数やべき関数での推計が対象の場合に は、すでに対数をとる処理がなされています。クラス Point2D.Double のインスタ ンスを p とすると、p.x が x-座標の値、p.y が y-座標の値になります。Program 5.1 を完成させましょう。 クラス LeastSquare を実行すると、先に作った out-linear.txt、out-exp.txt、 及び out-pow.txt の三つを読み込み、それぞれの関数形を推計して画面に表示し ます。データとともに、それらの関数形を図示しましょう。 4 private Point2D.Double fitSub(List<Point2D.Double> d) { double ax = 0.;//x の平均 double ax2 = 0;//x^2 の平均 double ay = 0;//y の平均 double axy = 0.;//x*y の平均 int n = 0;//データ点の数 for (Point2D.Double p : d) {//全てのデータに対して //x、x^2、y、xy の和を計算 } ax /= n; ax2 /= n; ay /= n; axy /= n; double sigma2 = ax2 - ax * ax; double a = (axy - ax * ay) / sigma2; double b = (ay * ax2 - axy * ax) / sigma2; return new Point2D.Double(a, b); } Program 5.1: fitSub メソッド 5
© Copyright 2024 ExpyDoc