予測する〜最小二乗法
<演習1>[br]次のような販売データがあるときに、最小二乗法で企画日数35の販売数を予測してみよう。[br][br][table][tr][td]企画日数(日)[/td][td]27[/td][td]30[/td][td]31[/td][td]37[/td][td]42[/td][td]43[/td][/tr][tr][td]販売数(個)[/td][td]346[/td][td]365[/td][td]397[/td][td]484[/td][td]524[/td][td]551[/td][/tr][/table][br]<演習2>[br]さらに、SNSいいね数(百個)[br][table][tr][td]627[/td][td]652[/td][td]637[/td][td]731[/td][td]710[/td][td]820[/td][/tr][/table][br]が順にわかったとき、制作日数35、SNSいいね数が800の[br]ときに販売数を予測しよう。[br]
[b][size=150]<最小二乗法>[/size][/b][br](企画日数、販売数)のn=6のときの実データを(xi,yi)(i=1..6)としよう。[br] y=cx+dという関係があるとして、cxi+dと実データyiとの誤差をεiとした総和S=Σ(yi - cxi-d)[sup]2[br][/sup] がc,dの連動して変化する。[br] Sをc,dで偏微分した式=0を整理すると、…(略)…[br] {{Σxi[sup]2[/sup], Σxi}{Σxi, n}}{{c}{d}}={{Σxiyi},{Σyi}}となる。[br][br] [b][color=#0000ff]6行2列の行列A={{x1 , 1},{x2 , 1},......,{x6, 1}}と列ベクトルy={{y1},{y2},....{y6}}を仮定すると、[br] [/color][/b]At A={{Σxi[sup]2[/sup], Σxi}{Σxi, n}}という対称行列, At y={{Σxiyi},{Σyi}}の列ベクトルになるので、[br] 列ベクトルz={{c}{d}}とすると、 [br] [color=#0000ff][b]At A z= At y[/b][/color] となるから、これを解いたz=c,dを使い、x=35を入れて出せるはず。
[b][size=150]<julia>[/size][/b][br][b][color=#1e84cc]using[/color] LinearAlgebra[/b][br]A=[27 1;30 1;31 1;37 1;42 1;43 1][br]At=transpose(A)[br]y=[346;365;397;484;524;551][br]B=At*A[br]C=At*y[br]# Bz=Cを解く。[br]c,d=inv(B)*C[br]c*35+d[br][color=#38761d]#=======================[br]444.500000000003[/color]
[b][size=150]<Python>[/size][/b][br][color=#1e84cc][b]import numpy as np[br]from numpy.linalg import inv[br][/b][/color]A = np.array([[27,1],[30,1],[31,1],[37,1],[42,1],[43,1]])[br]y = np.array([[346],[365],[397],[484],[524],[551]])[br]At=A.transpose()[br]B=At@A[br]C=At@y[br]# Bz=Cを解く。[br]c,d=inv(B)@C[br](c*35+d)[0] [color=#38761d]#c,dともにarrayとなるようだから、第一要素だけ取り出す。[br]#=======================[br]444.5000000000013[br][/color]
[b][size=150]<Geogebra>[/size][/b][br]A = {{27,1},{30,1},{31,1},{37,1},{42,1},{43,1}}[br]y = {{346},{365},{397},{484},{524},{551}}[br]At=transpose(A)[br]B=dot(At,A)[br]C=dot(At,y)[br]# Bz=Cを解く。[br]cd=dot(Invert(B),C)[br]cd(1)*35+cd(2) [color=#38761d]#要素の取り出しは(1),(2)のようなカッコ番号[br]#=======================[br]{444.5}[br][/color]
[b][size=150]<最小二乗法>[/size][/b][br](広告費、取り扱い店舗数、販売数)の実データを(x1,y2,y)としよう。[br] y=c[sub]1[/sub]x[sub]1[/sub]+c[sub]2[/sub]x[sub]2[/sub]+dという関係があるとして、誤差総和Sの最小化をする。[br] [b][color=#0000ff]6行2列の行列A={{x[sub]1[/sub]1 , x[sub]2[/sub]1,1},{x[sub]1[/sub]2 ,x[sub]2[/sub]2 1},......}と列ベクトルy={{y1},{y2},....{y6}}を仮定すると、[br] 課題1と同様に、[/color][/b] [br] [color=#0000ff][b]At A z= At y[/b][/color] となるから、これを解いたz=c[sub]1[/sub],c[sub]2[/sub],dを使い、x[sub]1[/sub]=35,x[sub]2[/sub]=800を入れて出せるはず。
[b][size=150]<julia>[/size][/b][br]using LinearAlgebra[br]A=[27 627 1;30 652 1;31 637 1;37 731 1;42 710 1;43 820 1][br]At=transpose(A)[br]y=[346;365;397;484;524;551][br]B=At*A[br]C=At*y[br]# Bz=Cを解く。[br]c1,c2,d=inv(B)*C[br]c1*35+c2*800+d[br][color=#38761d]#=======================[br][/color]459.5151762151013
[b][size=150]<Python>[/size][/b][br]import numpy as np[br]from numpy.linalg import inv[br][br]A = np.array([[27,627,1],[30,652,1],[31,637,1],[37,731,1],[42,710,1],[43,820,1]])[br]y = np.array([[346],[365],[397],[484],[524],[551]])[br]At=A.transpose()[br]B=At@A[br]C=At@y[br]# Bz=Cを解く。[br]c1,c2,d=inv(B)@C[br](c1*35+c2*800+d)[0][br][color=#38761d]#=======================[br]459.5151762150863[br][/color]
[b][size=150]<Geogebra>[/size][/b][br]A = {{27,627,1},{30,652,1},{31,637,1},{37,731,1},{42,710,1},{43,820,1}}[br]y = {{346},{365},{397},{484},{524},{551}}[br]At=transpose(A)[br]B=dot(At,A)[br]C=dot(At,y)[br]# Bz=Cを解く。[br]cd=dot(Invert(B),C)[br]cd(1)*35+cd(2)*800+cd(3)[color=#38761d][br]#=======================[br]{459.52}[br][/color]