LoginSignup
8
5

More than 1 year has passed since last update.

近似曲線をMATLABで書く!!

Posted at

本記事はMATLAB R2021aを用いています.

Excelの最小二乗法による近似曲線の種類

Excelの近似曲線は主に以下がある.
excel.PNG

  • 線形近似
  • 多項式近似
  • 対数近似
  • 指数近似
  • 累乗近似

今回はMATLABでこれらを描いていく.

MATLABでデータを作る

今回は近似を行うデータもMATLABで作っていく. もし, Excelのdataを用いたい場合はMATLABのreadtable関数を使えば, 簡単にデータをインポートできる.

今回は. 近似のターゲットとなる関数にrandn関数による誤差を足すことによってデータを作った.

MATLABでの近似曲線の実装

ここから, MATLABで近似曲線を作っていく. 主に参考となるリンクは以下となる.

近似曲線を計算する

グラフを描く

グラフのいろいろ

最小二乗法による線形近似

今回のターゲット関数は,
$$ y = 1-x $$
として, 以下のデータを作った.

matlab
data_num = 100;
data_x = 10*rand(1,data_num);
data_y = 1 - data_x + 0.5*randn(1,data_num);

linear_regression_data.png

MATLABで最小二乗法による近似はpolyfit関数polyval関数で行うことができる.

matlab
x = linspace(0,10,100);
p = polyfit(data_x,data_y,1);
y = polyval(p,x);

linear_regression_plot.png

ちなみに, この近似曲線の式は,
$$ y = p(1)x + p(2) $$
となっている.

最小二乗法による多項式近似

ここでのターゲット関数は,
$$ y = 2 + x - \frac{1}{2}x^2 - x^3 $$
とした. そして, 以下のデータを作った.

matlab
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);

polynomial_regression_data.png

MATLABでは, 多項式近似は線形近似とほぼ何も変わらない. polyfit関数は,

p = polyfit(xデータ, yデータ,多項式の次数);

となっているため, 今回は,

matlab
x = 0:10/99:10;
p = polyfit(data_x,data_y,3);
y = polyval(p,x);

により, 以下のような近似曲線が得られる.

polynomial_regression_plot.png

ちなみに, 近似曲線の式は,
$$ 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 $$

として以下のデータを作成した.

matlab
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);

log_approx_data.png

そして, このような非線形の近似曲線を求める場合は, MATLABプログラムでの近似を用いて, 以下のように書ける.

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;

このプログラム中にあるバックスラッシュは, 線形方程式の最小二乗解を求める. この手順を踏むことで, 以下の近似曲線を得られる.

log_approx_plot.png

また, 対数近似により得られた曲線は片対数グラフにおいて直線になる.

log_approx_semix.png

最小二乗法による指数近似

指数近似では,
$$ y = ae^{bx} $$
の$a$および$b$を求める. この式の両辺について対数をとると,
$$ \log y = \log a + bx $$
となり, 線形近似に変換することができる. 今回は, この性質を用いて近似曲線を求める.

今回は, ターゲット関数を,
$$ y = 10e^{-\frac{1}{4}x} $$
として, 以下のようなデータを作った.

matlab
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);

exp_approx_data.png

ここでは線形近似を行うため, polyfit関数を用いるが, 式変形に従い,

matlab
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);

として, 以下の近似曲線を得る.

exp_approx_plot.png

また, 指数近似についても片対数グラフにおいて直線となる.

exp_approx_semiy.png

最小二乗法による累乗近似

累乗近似では,

$$ 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}} $$

として以下のようにデータを作った.

matlab
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);

exponent_approx_data.png

そして, polyfit関数を用いて, 近似曲線を求める.

matlab
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);

exponent_approx_plot.png

おわりに

コロナ禍により, 試験が減りレポート課題が増えてきているように感じます(公平性の担保が簡単だからなのかな..)
レポート課題が増えると, 大学の先生はたくさんの似たようなレポートを見ることになると思います(たぶん..)
こんなとき, 目で見て理解できるグラフなどがあると, それだけであなたのレポートは目立つでしょう!!
MATLABはたくさんのグラフを作れるとても優秀なツールなので, みんなでグラフを作っていい点もぎ取りましょう!!(作りすぎ&載せすぎには注意です.)

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5