単線形回帰

目次(このページで分かること)

単線形回帰とは何か?

単線形回帰は、実験値などの複数のデータの組が与えられた場合、そのデータ間の最ももっともらしい関係式を求める方法です。

例えば、バネを引っ張る「力」と、その時のバネ「長さ」を計測した結果、以下のようなグラフになったとします。

データ間が一次関数(\( \displaystyle L = \beta_{1} F + \beta_{0}\))の関係にあると仮定し、単線形回帰により具体の関係式を求める( \( \beta_{0} \)、\( \beta_{1} \)を求める )と次式となります。

\( \displaystyle L = 0.97792 F + 0.30316 \)

グラフにすると以下となり、バラつきのある実験値の中央付近を通っていることが分かります。

関係式を得ることで任意の力\( F \)の値におけるバネの長さ\( L \)の推定値を得ることができるようになります。

このように単線形回帰ではデータの関係式の基本的な形(一次関数)を仮定し、その具体の係数を求める、という手順で、データの組の最ももっともらしい関係式を求めます。

具体の計算方法は下で解説します。

単線形回帰の計算

計算手順の概要

STEP
計測データの組が与えられる

\( (x_{i},y_{i}) \hspace{10pt}i = 1 \cdots n \)

STEP
データ間の関係式を仮定する

単線形回帰の場合は次式

\( y = \beta_{1} x + \beta_{0} \)

STEP
誤差(計測データと関係式による計算値の差)の二乗和が最小になるように関係式の係数を決定する

具体の計算方法

次のような\( n \)個のデータの組が与えられたとします。

データNo.\( x \)\( y \)
1\( x_{1} \)\( y_{1} \)
\( \vdots \)\( \vdots \)\( \vdots \)
\( i \)\( x_{i} \)\( y_{i} \)
\( \vdots \)\( \vdots \)\( \vdots \)
\( n \)\( x_{n} \)\( y_{n} \)

\( x_{i} \)や\( y_{i} \)は実際に計測された数値(例えばバネの「伸びの長さ」や「力の大きさ」など)です。

そして、データの関係式が次のような一次式になると仮定します。

$$ \displaystyle y = \beta_{1} x + \beta_{0}$$

ここからは最小二乗法により、係数\( \beta_{1} \)、\( \beta_{0} \)を計算します。

この関係式により予測される\( \hat{y} = \beta_{1} x + \beta_{0} \)の値とデータとして与えられた\( y_{i} \)の値の差を誤差\( \epsilon_{i} \)とします。

\( \hspace{10pt} \displaystyle 誤差 \epsilon_{i} = y_{i} – \hat{y} \)

\( \hspace{35pt} \displaystyle = y_{i} -(\beta_{1} x + \beta_{0} x_{i}) \)

グラフにすると下図になります。

最小二乗法では、全てのデータの誤差の二乗を足し上げ(誤差の二乗和)、それを最小とするように\( \beta_{1} \)、\( \beta_{0} \)を決定します。

\( \hspace{10pt} \displaystyle 誤差の二乗和 \hspace{10pt} E(\beta_{0},\beta_{1}) =  \sum_{i=1}^{n} \epsilon_{i}^{2} =  \sum_{i=1}^{n} \left\{ y_{i} – (\beta_{1} x_{i} + \beta_{0}) \right\}^{2} \)

この誤差の二乗和の関数\( E(\beta_{0},\beta_{1}) \)は変数として\( \beta_{1} \)、\( \beta_{0} \)を持つ多変数関数です。

\( x_{i} \)、\( y_{i} \)は与えられたデータ(定数)であって、変数でないことに注意してください。

この\( E(\beta_{0},\beta_{1}) \)を展開すると、

\( \hspace{10pt} \displaystyle E(\beta_{0},\beta_{1}) =  \sum_{i=1}^{n} \left\{ y_{i}^{2} – 2 y_{i} (\beta_{1} x_{i} + \beta_{0}) + (\beta_{1} x_{i} + \beta_{0})^{2} \right\} \)

\( \hspace{15pt} \displaystyle =  \sum_{i=1}^{n} \left\{ y_{i}^{2} – 2 y_{i} (\beta_{1} x_{i} + \beta_{0}) + x_{i}^{2} \beta_{1}^{2} + 2 x_{i} \beta_{1} \beta_{0} + \beta_{0}^{2} \right\} \)

となり、変数である\( \beta_{1}^{2} \)、\( \beta_{0}^{2} \)の係数が正となるため、下のグラフのように下に凸の形状になります。

つまり、下に凸(谷底)のところで極小値(最小値)をとります。

また、多変数関数は極小値や極大値で勾配ベクトルがゼロとなります。

このグラフでは、コーン状の形で勾配ベクトルを表現しています。

コーンの方向がベクトルの方向、コーンの大きさがベクトルの大きさです。

谷底のところで勾配ベクトルのコーンが無くなっている(勾配ベクトルがゼロになる)ことが分かると思います。

このグラフはドラッグで回転できますので、よければ色々見てみてくださいね。

\( \hspace{10pt} \displaystyle 勾配ベクトル = \nabla E(\beta_{0},\beta_{1}) = \frac{\partial E(\beta_{0},\beta_{1})}{\partial \beta_{0}} \mathbf{i} + \frac{\partial E(\beta_{0},\beta_{1})}{\partial \beta_{1}} \mathbf{j} \)

ですので、基底ベクトル\( \mathbf{i} \)、\( \mathbf{j} \)の両方の係数がゼロのところで、極小値(最小値)となります。

\( \hspace{10pt} \displaystyle \frac{\partial E(\beta_{0},\beta_{1})}{\partial \beta_{0}} = 0 \hspace{10pt},\hspace{10pt} \displaystyle \frac{\partial E(\beta_{0},\beta_{1})}{\partial \beta_{1}} = 0 \)

これを計算すると、次式となります。

\( \hspace{10pt} \displaystyle \sum_{i=1}^{n} y_{i} = \beta_{1} \sum_{i=1}^{n} x_{i} + n \beta_{0} \hspace{10pt},\hspace{10pt} \displaystyle \sum_{i=1}^{n} x_{i} y_{i} = \beta_{1} \sum_{i=1}^{n} x_{i}^{2} + \beta_{0} \sum_{i=1}^{n} x_{i} \)

導出過程を見たい方はここをクリックして展開してください。

\( \hspace{10pt} \displaystyle \frac{\partial E(\beta_{0},\beta_{1})}{\partial \beta_{0}} = 0 \hspace{10pt},\hspace{10pt} \displaystyle \frac{\partial E(\beta_{0},\beta_{1})}{\partial \beta_{1}} = 0 \)

\( E(\beta_{0},\beta_{1}) \)を代入すると

\( \hspace{10pt} \displaystyle \sum_{i=1}^{n} \frac{  \partial \epsilon_{i}^{2} }{\partial \beta_{0}} = 0 \hspace{10pt},\hspace{10pt} \displaystyle \sum_{i=1}^{n} \frac{ \partial \epsilon_{i}^{2} }{\partial \beta_{1}} = 0 \)

ここで\( f(\epsilon) = \epsilon^{2} \)として、微分の連鎖律を使用すると、

\( \hspace{10pt} \displaystyle \sum_{i=1}^{n} \frac{  \partial f }{\partial \epsilon}\frac{  \partial \epsilon }{\partial \beta_{0}} = 0 \hspace{10pt},\hspace{10pt} \displaystyle \sum_{i=1}^{n} \frac{  \partial f }{\partial \epsilon}\frac{  \partial \epsilon }{\partial \beta_{1}} = 0 \)

ここで、

\( \hspace{10pt} \displaystyle \frac{  \partial f }{\partial \epsilon} = 2 \epsilon \)

\( \hspace{10pt} \displaystyle \frac{  \partial \epsilon }{\partial \beta_{0}} = -1 \)

\( \hspace{10pt} \displaystyle \frac{  \partial \epsilon }{\partial \beta_{1}} = -x_{i} \)

ですので、

\( \hspace{10pt} \displaystyle \sum_{i=1}^{n} -2 \epsilon = 0 \hspace{10pt},\hspace{10pt} \displaystyle \sum_{i=1}^{n} – 2 \epsilon x_{i} = 0 \)

誤差の定義式\( \displaystyle \epsilon_{i} = y_{i} -(\beta_{1} x_{i} + \beta_{0}) \)を代入すると

\( \hspace{10pt} \displaystyle \sum_{i=1}^{n} -2 \{ y_{i} -(\beta_{1} x_{i} + \beta_{0}) \} = 0 \hspace{10pt},\hspace{10pt} \displaystyle \sum_{i=1}^{n} – 2 \{ y_{i} -(\beta_{1} x_{i} + \beta_{0}) \} x_{i} = 0 \)

最終的に次式となります。

\( \hspace{10pt} \displaystyle \sum_{i=1}^{n} y_{i} = \beta_{1} \sum_{i=1}^{n} x_{i} + n \beta_{0} \hspace{10pt},\hspace{10pt} \displaystyle \sum_{i=1}^{n} x_{i} y_{i} = \beta_{1} \sum_{i=1}^{n} x_{i}^{2} + \beta_{0} \sum_{i=1}^{n} x_{i} \)

ここで、\( \displaystyle \sum_{i=1}^{n} \beta_{0} = n \beta_{0} \)を使いました。

この\( \beta_{1} \)、\( \beta_{0} \)に関する連立一次方程式を解くと最終的に次式となります。

\( \hspace{10pt} \displaystyle \beta_{0} = \bar{y} – \beta_{1} \bar{x} \)
\( \hspace{10pt} \)
\( \hspace{10pt} \displaystyle \beta_{1} = \frac{\displaystyle \frac{1}{n}\sum_{i=1}^{n} (x_{i}-\bar{x})(y_{i}-\bar{y})}{\displaystyle \frac{1}{n} \sum_{i=1}^{n} (x_{i}-\bar{x})^{2}} = \frac{s_{xy}}{s_{xx}} \)

これが誤差の二乗和が最小となる\( \beta_{1} \)、\( \beta_{0} \)です。

ここで、\( \bar{x} \)、\( \bar{y} \)は次式で計算される\( x_{i} \)、\( y_{i} \)の平均値です。

\( \hspace{10pt} \displaystyle \bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_{i} \)

\( \hspace{10pt} \displaystyle \bar{y} = \frac{1}{n} \sum_{i=1}^{n} y_{i} \)

また、\( s_{xy} \)、\( s_{xx} \)はそれぞれ\( x_{i} \)、\( y_{i} \)の共分散、\( x_{i} \)の分散と言われるもので、次式になります。

\( \hspace{10pt} \displaystyle s_{xy} = \frac{1}{n}\sum_{i=1}^{n} (x_{i}-\bar{x})(y_{i}-\bar{y}) \)

\( \hspace{10pt} \displaystyle s_{xx} = \frac{1}{n} \sum_{i=1}^{n} (x_{i}-\bar{x})^{2} \)

導出過程を見たい方はここをクリックして展開してください。

\( \hspace{10pt} \displaystyle \sum_{i=1}^{n} y_{i} = \beta_{1} \sum_{i=1}^{n} x_{i} + n \beta_{0} \)

を\( \beta_{0} \)に関して解いて、

\( \hspace{10pt} \displaystyle \beta_{0} = \bar{y} – \beta_{1} \bar{x} \)

を得ます。

これを

\( \hspace{10pt} \displaystyle \displaystyle \sum_{i=1}^{n} x_{i} y_{i} = \beta_{1} \sum_{i=1}^{n} x_{i}^{2} + \beta_{0} \sum_{i=1}^{n} x_{i} \)

に代入すると、

\( \hspace{10pt} \displaystyle \displaystyle \sum_{i=1}^{n} x_{i} y_{i} = \beta_{1} \sum_{i=1}^{n} x_{i}^{2} + (\bar{y} – \beta_{1} \bar{x}) \sum_{i=1}^{n} x_{i} \)

\( \hspace{10pt} \displaystyle \left( \sum_{i=1}^{n} x_{i}^{2} – \bar{x}\sum_{i=1}^{n} x_{i} \right) \beta_{1} = \sum_{i=1}^{n} x_{i}y_{i} – \bar{y}\sum_{i=1}^{n} x_{i} \)

よって\( \beta_{1} \)は

\( \hspace{10pt} \displaystyle \beta_{1} = \frac{\displaystyle \sum_{i=1}^{n} x_{i}y_{i} – \bar{y}\sum_{i=1}^{n} x_{i}}{\displaystyle \sum_{i=1}^{n} x_{i}^{2} – \bar{x}\sum_{i=1}^{n} x_{i}} \)

右辺の分母、分子を\( n \)で割り\( x \)、\( y \)の平均\( \bar{x} \)、\( \bar{y} \)を使うと、

\( \hspace{15pt} \displaystyle = \frac{\displaystyle \frac{1}{n}\sum_{i=1}^{n} x_{i}y_{i} – \bar{x}\bar{y}}{\displaystyle \frac{1}{n} \sum_{i=1}^{n} x_{i}^{2} – \bar{x}^{2}} \)

この式の分母、分子それぞれを式変形していきます。

\( \hspace{10pt} \displaystyle 分母 = \frac{1}{n} \sum_{i=1}^{n} x_{i}^{2} – \bar{x}^{2} \)

\( \hspace{15pt} \displaystyle = \frac{1}{n} \sum_{i=1}^{n} x_{i}^{2} – 2\bar{x}^{2} + \bar{x}^{2} \)

\( \hspace{15pt} \displaystyle = \frac{1}{n} \sum_{i=1}^{n} x_{i}^{2} – 2\bar{x}\frac{1}{n}\sum_{i=1}^{n} x_{i} + \frac{1}{n} \sum_{i=1}^{n} \bar{x}^{2} \)

\( \hspace{15pt} \displaystyle = \frac{1}{n} \sum_{i=1}^{n} (x_{i} – \bar{x})^{2} \)

\( \hspace{15pt} \displaystyle = s_{xx} \)

次に分子は

\( \hspace{10pt} \displaystyle 分子 = \frac{1}{n}\sum_{i=1}^{n} x_{i}y_{i} – \bar{x}\bar{y} \)

\( \hspace{15pt} \displaystyle = \frac{1}{n}\sum_{i=1}^{n} x_{i}y_{i} – \bar{x}\bar{y} – \bar{x}\bar{y} + \bar{x}\bar{y} \)

\( \hspace{15pt} \displaystyle = \frac{1}{n}\sum_{i=1}^{n} x_{i}y_{i} – \sum_{i=1}^{n} x_{i} \bar{y} – \sum_{i=1}^{n}\bar{x}y_{i} + \frac{1}{n}\sum_{i=1}^{n}\bar{x}\bar{y} \)

\( \hspace{15pt} \displaystyle = \frac{1}{n}\sum_{i=1}^{n} (x_{i}-\bar{x})(y_{i}-\bar{y}) \)

\( \hspace{15pt} \displaystyle = s_{xy} \)

以上から、

\( \hspace{10pt} \displaystyle \beta_{1} = \frac{\displaystyle \frac{1}{n}\sum_{i=1}^{n} (x_{i}-\bar{x})(y_{i}-\bar{y})}{\displaystyle \frac{1}{n} \sum_{i=1}^{n} (x_{i}-\bar{x})^{2}} = \frac{s_{xy}}{s_{xx}} \)

を得ます。

用語説明

単線形回帰では各記号を以下のように呼んだりします。

例題:バネの実験

あるバネについて、「伸び」とその時のバネの引っ張る「力」を計測する実験を20回行ったところ、以下の計測値が得られたとします。

データNo.\( F \):力\( L \):バネの長さ
10.010.46513
20.062110.37002
30.114210.43161
40.166320.45908
50.218420.31799
60.270530.58499
70.322630.47251
80.374740.69585
90.426840.67102
100.478950.8874
110.531050.81242
120.583160.88462
130.635260.82771
140.687371.05159
150.739471.02144
160.791581.15361
170.843681.22478
180.895791.27358
190.947891.22415
2011.11081

グラフにすると下図になります。

関係式が次式のような一時式に従うと仮定し、単線形回帰を適用してみます。

\( \displaystyle L = \beta_{1} F + \beta_{0} \)

先程の\( \beta_{0} \)、\( \beta_{1} \)を求める式におい\( n \)⇒\( 20 \)、\( x \)⇒\( F \)、\( y \)⇒\( L \)と置き換えると、次式になります。

\( \hspace{10pt} \displaystyle \beta_{0} = \bar{L} – \beta_{1} \bar{F} \)

\( \hspace{10pt} \displaystyle \beta_{1} = \frac{\displaystyle \frac{1}{20}\sum_{i=1}^{20} (F_{i}-\bar{F})(L_{i}-\bar{L})}{\displaystyle \frac{1}{20} \sum_{i=1}^{20} (F_{i}-\bar{F})^{2}} = \frac{s_{FL}}{s_{FF}} \)

これを具体に計算すると、推定される関係式は

\( \displaystyle L = 0.97792 F + 0.30316 \)

となります。

グラフにすると下図となり、バラツキの中心付近を通ります。

ちなみに、誤差の二乗和 \( \hspace{10pt} E(\beta_{0},\beta_{1}) \)をグラフにすると次図になります。

このグラフは回転できます。

Webページの表示速度が遅くなるため、少ないデータでグラフ化しているので等高線がカクカクしてすみません。

ですが、計算した極小値の位置(黄色い丸 \( \beta_{1} = 0.97792 \)、\( \beta_{0} = 0.30316 \) )が谷底の位置(最小値)になっていることが分かるかと思います。

Pythonによる計算

機械学習ライブラリを使用しない場合

コード全体と出力結果

import numpy as np

# データ生成用関数
def f(x):
    np.random.seed(14)
    return x + 0.3 + np.random.normal(0, 0.1, size=len(x)) 

# データ数
n = 20

# データ生成
x = np.linspace(0.01, 1, n)
y = f(x)


# 係数計算
beta1 = ( 1/n*np.dot(x- np.mean(x), y- np.mean(y)) )/ ( 1/n*np.dot(x - np.mean(x), x - np.mean(x)) )
beta0 = np.mean(y) - beta1*np.mean(x)

# 結果表示
print('回帰変数 beta1: %.5f' %beta1)
print('切片   beta0: %.5f' %beta0)
print('y= %.5fx + %.5f' % (beta1 , beta0))
# 出力
回帰変数 beta1: 0.97792
切片   beta0: 0.30316
y= 0.97792x + 0.30316

コード解説

  • 「データ生成用関数」部分で、「\( x \) + 0.3 + 乱数 」の関数を定義し、これを基にデータの組を作成
  • データ数 \( n= 20 \)
  • 上で導出した式を使って\( \beta_{1} \)回帰係数と、\( \beta_{0} \)切片を計算
  • 計算の際はnumpyライブラリで平均(np.mean)やデータの掛け算(np.dot)を行う
  • 最後に係数を画面出力

機械学習ライブラリを使用した場合

コード全体と出力結果

import numpy as np
from sklearn.linear_model import LinearRegression


# データ生成用関数
def f(x):
    np.random.seed(14)
    return x + 0.3 + np.random.normal(0, 0.1, size=len(x)) 

# データ数
n = 20

# データ生成
x = np.linspace(0.01, 1, n)
y = f(x)

# 単線形回帰
model = LinearRegression()
model.fit(x.reshape(-1, 1), y)

# 結果表示
print('回帰変数 beta1: %.5f' %model.coef_[0])
print('切片   beta0: %.5f' %model.intercept_)
print('y= %.5fx + %.5f' % (model.coef_[0] , model.intercept_))

# 出力
回帰変数 beta1: 0.97792
切片   beta0: 0.30316
y= 0.97792x + 0.30316

コード解説

  • 「データ生成用関数」部分で、「\( x \) + 0.3 + 乱数 」の関数を定義し、これを基にデータの組を作成
  • データ数 \( n= 20 \)
  • 機械学習ライブラリ scikit-learn(sklearn)を使ってβ1回帰係数と、β0切片を計算
  • 最後に係数を画面出力
ご意見・ご感想をください
葉っぱ

サイトをご訪問いただき、ありがとうございました。
このサイトの作成者の葉っぱです。
分かりやすく、面白いサイトを作るため、ご意見・ご感想をいただけると嬉しいです。
いただく際は次のTwitterのDM、もしくはページ下部の「お問い合わせ」からお願いいたします。

目次(このページで分かること)