本記事はMATLAB R2021aを用いています.
Excelの最小二乗法による近似曲線の種類
- 線形近似
- 多項式近似
- 対数近似
- 指数近似
- 累乗近似
今回はMATLABでこれらを描いていく.
MATLABでデータを作る
今回は近似を行うデータもMATLABで作っていく. もし, Excelのdataを用いたい場合はMATLABのreadtable関数を使えば, 簡単にデータをインポートできる.
今回は. 近似のターゲットとなる関数にrandn関数による誤差を足すことによってデータを作った.
MATLABでの近似曲線の実装
ここから, MATLABで近似曲線を作っていく. 主に参考となるリンクは以下となる.
近似曲線を計算する
グラフを描く
グラフのいろいろ
最小二乗法による線形近似
今回のターゲット関数は,
$$ y = 1-x $$
として, 以下のデータを作った.
data_num = 100;
data_x = 10*rand(1,data_num);
data_y = 1 - data_x + 0.5*randn(1,data_num);
MATLABで最小二乗法による近似はpolyfit関数とpolyval関数で行うことができる.
x = linspace(0,10,100);
p = polyfit(data_x,data_y,1);
y = polyval(p,x);
ちなみに, この近似曲線の式は,
$$ y = p(1)x + p(2) $$
となっている.
最小二乗法による多項式近似
ここでのターゲット関数は,
$$ y = 2 + x - \frac{1}{2}x^2 - x^3 $$
とした. そして, 以下のデータを作った.
order = 3;
data_num = 100;
a = [2, 1, -1/2, -1];
data_x = 10*rand(1,data_num);
data_y = zeros(1,data_num);
for i=1:order+1
data_y = data_y + a(i)*data_x.^(i-1);
end
data_y = data_y + 5*randn(1,data_num);
MATLABでは, 多項式近似は線形近似とほぼ何も変わらない. polyfit関数は,
p = polyfit(xデータ, yデータ,多項式の次数);
となっているため, 今回は,
x = 0:10/99:10;
p = polyfit(data_x,data_y,3);
y = polyval(p,x);
により, 以下のような近似曲線が得られる.
ちなみに, 近似曲線の式は,
$$ y = p(1)x^3+p(2)x^2+p(3)x+p(4) $$
となる.
最小二乗法による対数近似
ここで得たい, 近似曲線は,
$$ y = a + b\log x $$
であり, この$a$と$b$を求める.
まず, ターゲット関数は,
$$ y = 1 -\log x $$
として以下のデータを作成した.
data_num = 100;
a = [1,-1];
data_x = 10*rand(1,data_num);
data_y = a(1) + a(2)*log(data_x) + 0.1*randn(1,data_num);
そして, このような非線形の近似曲線を求める場合は, MATLABプログラムでの近似を用いて, 以下のように書ける.
x = 0.01:10/99:10;
X = [ones(data_num,1), log(data_x')];
p = X\data_y';
y = [ones(size(x')), log(x')]*p;
このプログラム中にあるバックスラッシュは, 線形方程式の最小二乗解を求める. この手順を踏むことで, 以下の近似曲線を得られる.
また, 対数近似により得られた曲線は片対数グラフにおいて直線になる.
最小二乗法による指数近似
指数近似では,
$$ y = ae^{bx} $$
の$a$および$b$を求める. この式の両辺について対数をとると,
$$ \log y = \log a + bx $$
となり, 線形近似に変換することができる. 今回は, この性質を用いて近似曲線を求める.
今回は, ターゲット関数を,
$$ y = 10e^{-\frac{1}{4}x} $$
として, 以下のようなデータを作った.
data_num = 100;
a = [10,-1/4];
data_x = 10*rand(1,data_num);
data_y = a(1).*exp(a(2).*data_x) + 0.1*randn(1,data_num);
ここでは線形近似を行うため, polyfit関数を用いるが, 式変形に従い,
x = 0:10/99:10;
p = polyfit(data_x,log(data_y),1); % data_yではなくlog(data_y)にする!!
y = exp(p(2)+p(1).*x);
として, 以下の近似曲線を得る.
また, 指数近似についても片対数グラフにおいて直線となる.
最小二乗法による累乗近似
累乗近似では,
$$ y=ax^b $$
の$a$および$b$を求める. こちらについても両辺の対数をとり,
$$ \log y = \log a + b\log x $$
となる. これを用いて対数近似と同様の作業を行ってもよいが, 今回は, この式を
$$ y' = s + b x' $$
($y' = \log y$, $s = \log a$, $x'=\log x$)とみて, polyfit関数での線形近似を行う.
ここでのターゲット関数は,
$$ y = 10x^{-\frac{1}{4}} $$
として以下のようにデータを作った.
data_num = 100;
a = [10,-1/4];
data_x = 10*rand(1,data_num);
data_y = a(1).*data_x.^a(2) + 0.1*randn(1,data_num);
そして, polyfit関数を用いて, 近似曲線を求める.
x = 0.01:10/99:10;
p = polyfit(log(data_x),log(data_y),1); % data_xとdata_yをlog(data_x)とlog(data_y)とする
y = exp(p(2)).*x.^p(1);
おわりに
コロナ禍により, 試験が減りレポート課題が増えてきているように感じます(公平性の担保が簡単だからなのかな..)
レポート課題が増えると, 大学の先生はたくさんの似たようなレポートを見ることになると思います(たぶん..)
こんなとき, 目で見て理解できるグラフなどがあると, それだけであなたのレポートは目立つでしょう!!
MATLABはたくさんのグラフを作れるとても優秀なツールなので, みんなでグラフを作っていい点もぎ取りましょう!!(作りすぎ&載せすぎには注意です.)