単回帰分析(勉強用)

[多変量解析入門の書籍](https://amzn.to/2KYgTbM)を元に、各種分析の理論的背景を整理し、pythonで実行結果を確認します。本のまんまです。

# 単回帰分析

回帰分析の入門的位置
実務ではやくに立たないが、単回帰分析の理論的説明は重回帰分析の理解に必要となる。
実際はエクセルやスプレッドシートで単回帰分析の仕方をググれば簡単に試すことが可能。

単回帰分析は説明変数1つで目的変数の予測を行う。

## 導入
あるサイトのページビューxとCV数yの関係を調べるために、n=10のデータがある。

```python

x = [71, 81, 86, 72, 77, 73, 80, 81, 85, 74]
y = [2.2, 4.1, 5.5, 1.9, 3.4, 2.6, 4.2, 3.7, 4.9, 3.2]
```

### spreadsheetで解析した結果

![04de3f2d54146316738c33ff5c367d28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35291/35300021-48e0-cd80-ec71-377bb52ba976.png)

ページビュー数が増えるにつれて、CV数も増えている関係が見て取れます。図で直線が引かれていますが、この直線をデータから求めます。

## 解析ストーリ

解析のストーリを以下に示します。

(1) 単回帰モデル

```math
y_{i}=\beta_{0}+\beta_{1}x_{i}+\epsilon_{i},　\epsilon_{i} \sim N(0,σ^2)
```
(誤差$\epsilon_{i}$は互いに独立に$N(0, σ^2)$に従う)を想定し、回帰母数$\beta_{0}$と$\beta_{1}$を**最小二乗法**で推定する。

(2) 寄与率や自由度調整寄与率を求めて(1)で得られた回帰式の性能を評価する
(3) 回帰係数$\beta_{1}$について検定・区間推定を行う
(4) 残差とてテコ比の検討を行い、得られた回帰式の妥当性を検討する
(5) 得られた回帰式を利用して、任意に指定した値x0に対して母回帰B0+B1x0を推定し、y0=B0+B1x0+e0の値を予測する。

**この記事では(1) 単回帰モデルのパラメータ推定の解説を行います。**

## 解析方法

(1) 最小二乗法による回帰式の推定

観測された$y_{i}$の値は$\beta_{0}+\beta_{1}x_{i}$のパラメータ$\beta_{0}と\beta_{1}$によって決まる。このパラメータを使って直線を求めることから始める。このパラメータを求めるために、最小二乗法を使用する。
求める直線を

```math
\hat{y}=\hat{\beta_{0}}+\hat{\beta_{1}}x
```

とおく。実際のデータを当て込み

```math
\hat{y_{i}}=\hat{\beta_{0}}+\hat{\beta_{1}}x_{i}
```
とする。${\hat{y_{i}}}$を**予測値**と呼び、実測値($y_{i}$)と区別する。実測値と予測値の差を**残差**と呼ぶ。つまり残差$\epsilon_{i}$は

```math
\epsilon_{i} = y_{i} - \hat{y_{i}} = y_{i} - (\beta_{0}+\beta_{1}x_{i})
```
となり、そして次の**残差平方和**が最小になる$\beta_{0}$と$\beta_{1}$を求める。

```math
S_{e} = \sum_{i=1}^{n}e_i^2 = \sum_{i=1}^{n}\left\{y_{i} - (\beta_{0}+\beta_{1}x_{i})\right\}^2
```


そのためには、$S_{e}$を偏微分して0となる箇所が答えになるので、それぞれ、

```math
\frac{\partial S_{e}}{\partial \beta_{0}} = -2\sum_{i=1}^n(y_{i}-\beta_{0}-\beta_{1}x_{i}) = 0
```
```math
\frac{\partial S_{e}}{\partial \beta_{1}} = -2\sum_{i=1}^nx_{i}(y_{i}-\beta_{0}-\beta_{1}x_{i}) = 0
```

式を整理すると

(4.8)

```math
\hat{\beta_{0}}n+\hat{\beta_{1}}\sum x_{i}= \sum y_{i}　　
```

(4.9)

```math
\hat{\beta_{0}}\sum x_{i} +  \hat{\beta_{1}}\sum x_i^2 = \sum x_{i}y_{i}
```

を得る。これを正規方程式と呼ぶ。(4.8)式より

(4.10)

```math
\hat{\beta_{0}} = \frac{\sum y_{i}}{n} - \hat{\beta_{1}} \frac{\sum x_{i}}{n} = \overline{y}-\hat{\beta_{1}}\overline{x}
```

(4.10)より、$\hat{\beta_{0}}$の推定値が求まった。この式を元に$\hat{\beta_{1}}$を求めていく。(4.10)の式を(4.9)に代入すれば、

```math
\left(\frac{\sum y_{i}}{n} - \hat{\beta_{1}} \frac{\sum x_{i}}{n}\right)\sum x_{i} + \hat{\beta_{1}}\sum x_i^2 = \sum x_{i}y_{i}
```

となり、整理すれば、

(4.12) 

```math
\hat{\beta_{1}}\left(\sum x_i^2-\frac{\left(\sum x_{i}\right)^2}{n}\right)=\sum x_{i}y_{i}-\frac{\sum x_{i}\sum y_{i}}{n}
```
を得る。ここで、xとyの偏差積和およびxの平方和

```math
S_{xy} = \sum x_{i}y_{i}-\frac{\sum x_{i}\sum y_{i}}{n}
```

```math
S_{xx} = \sum x_i^2-\frac{\left(\sum x_{i}\right)^2}{n}
```

を用いれば、(4.12)式より、次のように表すことができる。

```math
\hat{\beta_1} = \frac{S_{xy}}{S_{xx}}
```

$\hat{\beta_1}$の値が求まった。


----
### 導出してみた(補足)

途中、偏微分から式整理までの過程がなかったので、$\beta_{0}$のみ導出してみました。


[合成微分の公式](https://mathtrain.jp/composite)より
$\mu=y_{i} - (\beta_{0}+\beta_{1}x_{i})$とおくと 

```math
\sum \mu^2
```

このとき

```math
\frac{\text{d}y}{\text{d}\mu}=2\sum \mu
```

```math
\frac{\text{d}\mu}{\text{d}\beta_{0}}=0-1-0\times x_{i}=-1
```

よって、

```math
\frac{\partial S_{e}}{\partial \beta_{0}} = 2\sum \mu \times - 1
```
```math
= -2\sum \mu
```
```math
= -2\sum_{i=1}^n (y_{i} - \beta_{0}-\beta_{1}x_{i}) = 0
```

[シグマの展開公式](https://rikeilabo.com/sum-formula-of-numerical-sequence)より

```math
-2\sum_{i_1}^n y_{i} + 2\beta_{0}n + 2\beta_{1}\sum_{i=1}^n x_{i} = 0
```

```math
2\beta_{0}n + 2\beta_{1}\sum_{i=1}^n x_{i} = 2\sum_{i_1}^n y_{i}
```

```math
\beta_{0}n + \beta_{1}\sum_{i=1}^n x_{i} = \sum_{i_1}^n y_{i}
```

ここまで

## pythonで解く

求めたい直線の回帰式がこれで、

```math
\hat{y}=\hat{\beta_{0}}+\hat{\beta_{1}}x
```

パラメータはそれぞれ以下で求まることがわかりました。

```math
\hat{\beta_{0}} = \overline{y}-\hat{\beta_{1}}\overline{x}
```

```math
\hat{\beta_1} = \frac{S_{xy}}{S_{xx}}
```

実際にpythonを使って求めてみたいと思います。改めてデータを用意

```python

x = [71, 81, 86, 72, 77, 73, 80, 81, 85, 74]
y = [2.2, 4.1, 5.5, 1.9, 3.4, 2.6, 4.2, 3.7, 4.9, 3.2]
```

x,yの平均を求める

```python
x_mean = sum(x) / len(x)
y_mean = sum(y) / len(y)

print('xの平均は{}'.format(x_mean))
print('yの平均は{}'.format(y_mean))
# xの平均は78.0
# yの平均は3.5700000000000003
```

xの偏差平方和を求める

```python
s_xx =  sum([(_x - x_mean) ** 2 for _x in x])
print('xの偏差平方和は{}'.format(s_xx))
# xの偏差平方和は262.0
```


xとyの偏差積和を求める


```python
s_xy = sum([ (_x - x_mean) * (_y - y_mean) for (_x, _y) in zip(x, y)])
print('sとxの偏差積和は{}'.format(s_xy))
# sとxの偏差積和は54.10000000000001
```

$\beta_{1}$を求める

```python
beta_1 = s_xy / s_xx
print('回帰係数は{}'.format(beta_1))
# 回帰係数は0.20648854961832064
```

$\beta_{0}$を求める

```python
beta_0 = y_mean - beta_1 * x_mean
print('切片は{}'.format(beta_0))
# 切片は-12.536106870229009
```

ライブラリで値があってるか確認

```python
from sklearn import linear_model

X = [[71], [81], [86], [72], [77],[73], [80], [81], [85], [74]]
Y = [[2.2], [4.1], [5.5], [1.9], [3.4], [2.6], [4.2], [3.7], [4.9], [3.2]]
clf = linear_model.LinearRegression()
clf.fit(X,Y)
print("回帰係数=", clf.coef_)
print("切片：",clf.intercept_)
```

>回帰係数= [[0.20648855]]
切片： [-12.53610687]


あってました。