4. 線形最小二乗法
注 – 例題ワークシートをダウンロードすることができます. 1. 例題ワークシートの入手と使用方法 をご覧ください.
線形最小二乗問題の XLPack による解き方の例を説明します.
例題: 多項式近似
次のデータは, NIST(アメリカ国立標準技術研究所)のホームページ(http://www.itl.nist.gov/div898/strd/lls/data/Norris.shtml)に掲載されているテストデータです.
Data: y x 0.1 0.2 338.8 337.4 118.1 118.2 888.0 884.6 9.2 10.1 228.1 226.5 668.5 666.3 998.5 996.3 449.1 448.6 778.9 777.0 559.2 558.2 0.3 0.4 0.1 0.6 778.1 775.5 668.8 666.9 339.3 338.0 448.9 447.5 10.8 11.6 557.7 556.0 228.3 228.1 998.0 995.8 888.8 887.6 119.6 120.2 0.3 0.3 0.6 0.3 557.6 556.8 339.3 339.1 888.0 887.2 998.5 999.0 778.9 779.0 10.2 11.1 117.6 118.3 228.9 229.2 668.4 669.1 449.2 448.9 0.2 0.5
これを1次多項式(直線)
f(x) ≅ c1 + c2x
により近似します.
以下, ワークシート関数 WDgels と VBA サブルーチン Dgels を使った2種類の解き方を説明します.
ワークシート関数を使用した解き方
まず, ワークシートの適当な場所にデータを入力します(オレンジ色のセル). そして, 係数行列 A (Aij = φj(xi) (i = 1~m, j = 1~n)) を作ります(この場合は, Ai1 = 1, Ai2 = xi となるような式を入れておきります). 次に, 求めるパラメータ c およびその他の結果を入れる n+2 個のセルを選択してワークシート関数 WDgels を入力します(緑色のセル).
WDgels の必要なパラメータは, Trans, Cov, M, N, A, B, Nrhs です. Trans = “N” ならば Ax = b を解き, Trans = “T” ならば (A^T)x = b を解きます. Cov = “N” ならば分散共分散行列を計算しません. Cov = “D” ならば分散(分散共分散行列の対角要素)を計算します. Cov = “C” ならば分散共分散行列を計算します. M はデータ数, N はパラメータ数(この例では 2), A は行列 A のセル範囲, B は右辺ベクトル(= ベクトル y)のセル範囲です. 右辺ベクトルは通常は 1 本ですが, 複数本入力することもでき, Nrhs にはその本数を入力します. Nrhs は入力を省略することができ, その場合は 1 とみなされます.
入力が終了したら Ctrl + Shift + Enter を押すと結果が得られます. ここでは, データを丸で, 計算値を直線で表すグラフも作成してみました.
2つのパラメータが求められました(c1 = -0.26232, c2 = 1.002117). これらは, NIST の値とぴったり一致しています.
VBAプログラムを使用した解き方
上と同じ例を VBA プログラムにより解いてみます. VBA サブルーチン Dgels を使ったプログラム例を示します.
Sub Start()
Const MMax = 100, NMax = 5
Dim M As Long, N As Long
Dim A(MMax, NMax) As Double, B(MMax) As Double
Dim Info As Long, I As Long, J As Long
'--- Input data
M = 36: N = 2
For I = 0 To M - 1
For J = 0 To N - 1
A(I, J) = Cells(5 + I, 3 + J)
Next
B(I) = Cells(5 + I, 2)
Next
'--- Compute least squares solution
Call Dgels("N", M, N, A(), B(), Info)
'--- Output result
For J = 0 To N - 1
Cells(5 + J, 5) = B(J)
Next
Cells(7, 5) = Info
End Sub
所定の位置にデータを入力し, マクロ Start を実行すると次のように上と同じ結果が得られます. ワークシート関数を使用したときと異なり, 係数行列 A と右辺ベクトル b の値を入力しただけでは結果が得られず, VBA プログラムを実行してやる必要があります.