作業中のメモ

よく「計算機」を使って作業をする.知らなかったことを中心にまとめるつもり.

n 変数関数の最小二乗近似

どうも,筆者です.数点のデータから,関数フィッティングを行う必要が出てきたので,原理から考えたいと思う. gnuplot の fit コマンドを使えば,解は出てくるけど,C 言語等のプログラム中で処理を行いたいため,1 から考えてみる.

最小二乗近似

まず, {n} {\boldsymbol{x} = (x_{1}, x_{2}, \cdots, x_{n})^{T}} から得られる観測データ  {y} {m} 個あるとする.

これらを関数

 { \displaystyle 
  f(\boldsymbol{x}) = \sum_{i = 1}^{n} a_{i}g_{i}(x_{i}) \qquad (1)
}

で近似することを考える.ここで,関数  {g_{i}(x_{i})} {i} 番目の基底関数である. このとき,測定値の組  {(\boldsymbol{x}_{j}, y_{j}), (j = 1, 2, \cdots, m)} における誤差  {\varepsilon_{j}}

 { \displaystyle
  \varepsilon_{j} = f(\boldsymbol{x}_{j}) - y_{j}\qquad (2)
}

で定義する.そして, {m} 個のデータの二乗誤差  {J}

 { \displaystyle
  J = \dfrac{1}{2} \sum_{j = 1}^{m} \varepsilon_{j}^{2}\qquad (3)
}

を最小にするような係数  {a_{i}, (i = 1, \cdots, n)} を求める.これを満たす  {a_{i}} は,

 { \displaystyle
  \dfrac{\partial J}{\partial a_{i}} = 0\qquad (4)
}

を解くことで求められる.ここで,式 (4) の左辺は,

 {
  \begin{eqnarray}
    \dfrac{\partial J}{\partial a_{i}} & = & \dfrac{1}{2} \dfrac{\partial}{\partial a_{i}} \sum_{j = 1}^{m} \varepsilon_{j}^{2} \\
    & = & \dfrac{1}{2} \sum_{j = 1}^{m} \dfrac{\partial \varepsilon_{j}^{2}}{\partial a_{i}} \\
    & = & \sum_{j = 1}^{m} \varepsilon_{j} \cdot \dfrac{\partial \varepsilon_{j}}{\partial a_{i}} \qquad (5)
  \end{eqnarray}
}

で求められる.式 (2) から,実際に偏微分の値を求めると,

 {
  \begin{eqnarray}
   \dfrac{\partial \varepsilon_{j}}{\partial a_{i}} & = & g_{i}(x_{i, j})\\
  \end{eqnarray}
}

となるので,これらを式 (5) に代入すると, {n} 個の連立方程式

 {
  \begin{equation}
    \left\{
      \begin{array}{ccc}
        \sum\limits_{j = 1}^{m} \left( \sum\limits_{i = 1}^{n} a_{i}g_{i}(x_{i, j}) - y_{j} \right)g_{1}(x_{1, j}) & = & 0\\
        \sum\limits_{j = 1}^{m} \left( \sum\limits_{i = 1}^{n} a_{i}g_{i}(x_{i, j}) - y_{j} \right)g_{2}(x_{2, j}) & = & 0\\
                   \vdots & \vdots & \vdots\\
        \sum\limits_{j = 1}^{m} \left( \sum\limits_{i = 1}^{n} a_{i}g_{i}(x_{i, j}) - y_{j} \right)g_{n}(x_{n, j}) & = & 0\\
      \end{array}
    \right. \qquad (6)
  \end{equation}
}

が得られる.これは

 {
  \begin{equation}
    \left\{
      \begin{array}{cc}
        \sum\limits_{j = 1}^{m} a_{1}g_{1}(x_{1, j})g_{1}(x_{1, j}) + \sum\limits_{j = 1}^{m} a_{2}g_{2}(x_{2, j})g_{1}(x_{1, j}) + \cdots + \sum\limits_{j = 1}^{m} a_{n}g_{n}(x_{n, j})g_{1}(x_{1, j}) & = & \sum\limits_{j = 1}^{m} g_{1}(x_{1, j})y_{j}\\
        \sum\limits_{j = 1}^{m} a_{1}g_{1}(x_{1, j})g_{2}(x_{2, j}) + \sum\limits_{j = 1}^{m} a_{2}g_{2}(x_{2, j})g_{2}(x_{2, j}) + \cdots + \sum\limits_{j = 1}^{m} a_{n}g_{n}(x_{n, j})g_{2}(x_{2, j}) & = & \sum\limits_{j = 1}^{m} g_{2}(x_{2, j})y_{j}\\
        \vdots & \vdots & \vdots\\
        \sum\limits_{j = 1}^{m} a_{1}g_{1}(x_{1, j})g_{n}(x_{n, j}) + \sum\limits_{j = 1}^{m} a_{2}g_{2}(x_{2, j})g_{n}(x_{n, j}) + \cdots + \sum\limits_{j = 1}^{m} a_{n}g_{n}(x_{n, j})g_{n}(x_{n, j}) & = & \sum\limits_{j = 1}^{m} g_{2}(x_{n, j})y_{j}\\
      \end{array}
    \right. \qquad (6)
  \end{equation}
}

と書き換えることが出来, {m \times n} の行列  {G = (\boldsymbol{g}_{1}(\boldsymbol{x}), \boldsymbol{g}_{2}(\boldsymbol{x}), \cdots, \boldsymbol{g}_{n}(\boldsymbol{x})), \quad \boldsymbol{g}_{i}(\boldsymbol{x}) = (g_{i}(x_{1}), g_{i}(x_{2}), \cdots, g_{i}(x_{m}))^{T}} {n} 次元ベクトル  {\boldsymbol{a} = (a_{1}, a_{2}, \cdots, a_{n})^{T}} {m} 次元ベクトル  {\boldsymbol{y} = (y_{1}, y_{2}, \cdots, y_{m})^{T}} を用いて,

 { \displaystyle
  G^{T}G \boldsymbol{a} = G^{T}\boldsymbol{y}\qquad (7)
}

と表せる.これは,正規方程式と呼ばれる.ガウスジョルダン法等を用いて解を求める.行列が特異になる場合は,特異値分解を用いて,解くことになる.

はてなブログにおける数式の表記

よく分からないが,文章中の数式に関して,「_」を数式中で使用すると,正しく表示されないことが分かった.なので, {(x_{1}, x_{2})} などを文章中で表示するには,「\_」と「_」をエスケープすることで,表示することが出来る.はてなブログ {\LaTeX} 記法には,まだまだ慣れない.少しずつ解決していこうと思う.現段階でまだ謎なのは,

  • <pre> 中で,「_」をエスケープしなくても表示出来る理由
  • 数式中で式番号を表示する方法.出来れば,label をつけて相互参照を行いたい(現段階では,直接数字を入力している).
  • どの程度まで  {\LaTeX} の表記が使えるか.

ということである.3 つ目に関しては,色々試すのが早い気がする...

参考サイト

最小二乗法 - Wikipedia