🗃
Math&Julia #03|回帰モデル » 線形回帰 » 閉形式解
はじめに
散布図にプロットされたデータを見ると、全体を貫く 1つの傾向が見えることがあります。この傾向を 1本の直線で捉えて、未知のデータの予測に活用したいとします。それでは「この傾向に最も当てはまりの良い直線」はどのようにして求めれば良いのでしょうか?
最小二乗法 (Ordinary Least Squares, OLS)
最小二乗法は、残差平方和
残差平方和 (Residual Sum of Squares, RSS)

図 1 残差
図 1にあるように残差を
回帰係数
式
式
式
閉形式解
ここまでについて、偏差平方和
実装
回帰係数を求めるols関数を作成して閉形式解を実装します。サンプルデータは、直線の方程式
Julia
using Statistics, CairoMakie, Random
# 最小二乗法(閉形式解)で回帰係数を計算
function ols(x::Vector, y::Vector)
μx = mean(x) # xの平均
μy = mean(y) # yの平均
Sxy = sum((x .- μx) .* (y .- μy)) # 偏差積和
Sxx = sum((x .- μx) .^ 2) # 偏差平方和
a = Sxy / Sxx # 傾き
b = μy - a * μx # 切片
(a = a, b = b) # 回帰係数
end
# サンプルデータを人工的に生成
function generate_sample_data()
Random.seed!(0)
x = collect(0:30) # xのデータを生成
noise = randn(length(x)) * 4 # ノイズを生成(正規分布に従う)
y = 1.6x .+ 10 .+ noise # yのデータを生成(ノイズを付加)
x, y
end
# サンプルデータと回帰直線を可視化
function vis_regression_line(x, y, coef)
rl = coef.a .* x .+ coef.b # 回帰直線
a = round(coef.a, digits=2) # 傾き
b = round(coef.b, digits=2) # 切片
eq = "y = $(a)x + $(b)" # 直線の方程式
fig = Figure()
ax = Axis(fig[1,1], xlabel="x", ylabel="y")
scatter!(ax, x, y, color=:blue, markersize=10)
lines!(ax, x, rl, color=:red, linewidth=2)
text!(ax, 0, 56, text=eq, fontsize=20)
ylims!(ax, 0, nothing)
display(fig)
fig
end
ハンズオン
Julia
x, y = generate_sample_data() # サンプルデータを人工的に生成
coef = ols(x, y) # 回帰係数を取得
fig = vis_regression_line(x, y, coef) # サンプルデータと回帰直線を可視化
save("03-fig2.png", fig)

図 2 回帰直線
予測例
図 2の回帰直線
Discussion