回帰分析の最も基本！　線形回帰とは？

#線形回帰とは？
- データの分布を線によって表現する方法。

- 最も簡単な例では、ある入力xが与えられたとき、その予測値yを
      **y=aX+b** 
の形で表現する。

- よって、最適なパラメータ(ここでは、a,b)を求めることが課題。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/56ced590-b994-424b-8974-299636aaa448.png)

#「最適」をどう判断するか？
- 通常は、**「最小二乗法」**を使って、パラメータを決定する。

- 「最小二乗法」では、実際のデータと予測値の差の二乗(二乗誤差)が最小になるように、パラメータを調節する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/c4ff94a1-3b9f-c9cc-bc88-541a09c00a8f.png)

#どうやって「最適」なパラメータを求めるか？

- **解析的**に解く…式の変形によって解を求める。
ex)
**x²-5x+6=0**
→**x=2,3**


- **数値的**に解く…具体的な数値を代入し続け、近似的な解を得る。

# 2種類の解き方が存在する

- 正規方程式…解析的な解法。厳密な解を得られる一方で、常に解が得られるとは限らない。

**(注意)**
正規方程式による解法は、問題によっては最適な解を見つけることが出来ない上、データ数の増加とともに計算コストが急激に増える。

- 勾配降下法…数値的な解法。結果に誤差が生まれることがあるが、ほとんどの場合で解を求めることができる。

#勾配降下法の考え方

1:ランダムな初期値(例えば0)を設定し、損失関数(二乗誤差)を計算する
2:重さwによって偏微分を行い、その点における傾きを求める。
3:傾きが0に近づく方向に重さwを調節する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/0fb0946b-c9bb-b3e8-6a58-981399ef71ce.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/53048a62-f262-c5d0-905d-b6a62b044325.png)

**(注意)**
バッチ勾配降下法…**局所的な最小値**に陥りやすいデメリットがある。

確率的勾配降下法…**局所的な最小値**を回避できるメリットがある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/001c6ec1-45ce-a685-595d-e522b27c5ee8.png)


#学習率とは？
- 学習率…どの程度の大きさでパラメータの更新を行うかを決める。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/3f77a673-2b16-d8f5-e901-9cf555201782.png)


#実践
```py
import numpy as np
import matplotlib.pyplot as plt
#matplotlib inline

#100×1の配列の乱数(一様分布（0.0以上、1.0未満）)
X = np.random.rand(100,1)
y=5+3*X+np.random.rand(100,1)
plt.scatter(X,y)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/66d24c44-9f5f-a7a6-022c-c10f3fba2afd.png)

```py
#数値的に解く
from sklearn.linear_model import LinearRegression
lig_reg = LinearRegression().fit(X,y)
#切片、傾き
lig_reg.intercept_,lig_reg.coef_
#座標xが0,1の時の予測を返せば、その２点を結ぶだけ
x_new=np.array([[0],[1]])
plt.plot(x_new,lig_reg.intercept_+lig_reg.coef_*x_new,"red")
plt.scatter(X,y)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/a82923bf-832a-f48e-2f84-6e5e5a24a135.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/8bc7c829-780f-aaec-7e55-ab54bb4b29a6.png)


```py
#解析的に解く
#勾配降下法で解く
#SGDRegressor…確率的勾配降下法
# ravel関数を適用させると、一次元のリストが返却される。
from sklearn.linear_model import SGDRegressor
sgd_reg_00001=SGDRegressor(loss='squared_loss',eta0=0.0001,max_iter=100).fit(X,y.ravel())
sdg_reg_00001.intercept_,sdg_reg_00001.coef_

plt.plot(x_new,sgd_reg_00001.intercept_+sgd_reg_00001.coef_*x_new,"red")
plt.scatter(X,y)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/ba2a4cd7-e761-650b-da08-9ae02d001920.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/a7972af9-1069-a43b-a90f-c48744cc66b2.png)

```py
# ravel関数を適用させると、一次元のリストが返却される。
sgd_reg_100=SGDRegressor(loss='squared_loss',eta0=100,max_iter=100).fit(X,y.ravel())

plt.plot(x_new,sgd_reg_100.intercept_+sgd_reg_100.coef_*x_new,"red")
plt.scatter(X,y)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/e3aeda78-0a8f-c251-bb1b-a2356885c29a.png)