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