機械学習を学びなおしてみた1（単回帰モデル）

# はじめに
分析コンペに参加してみたが自分の理解の甘さを痛感したのでモデルについて学習しなおすことにしました。
基本的にsklearnのドキュメントを見ながら勉強していきます。

*注意：
前処理やチューニング等は特に行ってません。
単回帰分析が何なのか等の細かい部分は記述していません。


# データの用意
今回はsignateの練習用コンペの「自動車の走行距離予測」のデータを使用します。
データから"weight"（独立変数）、"mpg"（従属変数）のみを取り出して使用します。


# 事前準備
まずはsklearn経由でモデルをインポートします。
その後にインスタンス化します。
```
# モデルのインポート
from sklearn.linear_model import LinearRegression

# インスタンス化
reg = LinearRegression()
```

他に使用するライブラリは次の通りです。
```
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
```


# LinearRegressionのパラメーターについて

|パラメータ名|デフォルト|Dtype|説明|
|:-:|:-:|:-:|:-:|
|fit_intercept|True|bool|切片を計算するかどうか。|
|copy_X|True|bool|使用した元のデータをコピーして使うかどうか。Falseにすると元のデータを書き換える恐れがある。|
|n_jobs|None|int|プロセッサ等の内部のお話。基本的に触ることは無い。|
|positive|False|bool|Trueだと係数が正であることを強制する。|


# Attributesについて
Attributesはモデルの学習後に実行できるものです。(pridict等)
rank_とsingular_については理解が浅いです。

|Attributes|戻り値|
|:-:|:-:|
|coef_|モデルの回帰係数の配列|
|rank_|独立変数Xそれぞれがどれだけ独立した値を持っているかどうか。強い相関を持つものが含まれていたりすると値が小さくなる。特徴量数より小さいと良くない。
|singular_|従属変数Xの行列の特異値
|intercept_|モデルの切片。パラメーターで切片を計算しないようにしてる場合は0を返す。
|n_features_in_|fitで学習中に観測された特徴量数
|feature_names_in_|fitで学習中に観測された特徴量の名前


# Methodsについて

|メソッド名|引数|説明|
|:-:|:-:|:-:|
|fit|X, y ,[sample_weight]|線形モデルの学習|
|get_metadata_routing|なし|モデルのメタ情報を取得（使ってるの見たことない）|
|get_params|[deep]|モデルのハイパーパラメーターの取得|
|predict|X|予測の実行|
|score|X, y,[sample_weight]|予測の決定係数r_2を返す。|
|set_fit_request|*[sample_weight]|fit メソッドに渡されるリクエストのメタデータ？|
|set_params|**params|ハイパーパラメーターの設定に使用する。|
|set_score_request|*[sample_weight]|scoreメソッド内のメタデータを触るもの？|


# 検証
いくつかの内容について実際にコードを書いて確かめてみます。

### モデルの学習まで
```
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# dfは事前に加工済みで用意してある。
# Xが独立変数、yが従属変数
X = df[["weight"]]
y = df[["mpg"]]

# モデルをインスタンス化
# パラメーターは指定していないのでデフォルトのままです。
reg = LinearRegression()

# モデルの学習
reg.fit(X, y)

```

ここで最初にエラーが出ました。
エラー内容：
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.

これは単体の特徴量を与えた時に二次元配列でないといけないらしいです。
したがって上記のコードでは[["weight"]]のように2次元配列にしています。
（最初は X = df["weight"] としてました。）

### Attributesの確認
coef_で傾きを見る前に一度グラフでどのような学習をしたのか可視化してみます。
```
plt.plot(X, y, "o")
plt.plot(X, reg.predict(X), linestyle="solid")
plt.show()
```
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491855/4026b68e-637c-36bb-cfc1-ed0ca122b72d.png)

coef_で確認します。
```
reg.coef_
# array([[-0.00780616]])
```
一瞬「小さくね？」と思いましたけどXの範囲的に適切でした。

サクサク行きます。


rank_ , singular_ , intercept_
```
print(reg.rank_)
# 1

print(reg.singular_)
# array([11535.14234218])

print(reg.intercept_)
# array([46.81874664])

```

rank_については独立変数1種類しかないので特に見る意味なかったです。
sungular_はよく分かりません。。すみません。。。
intercept_は先ほどの図の通りでした。


n_features_in_ , feature_names_in_
```
print(reg.n_features_in_)
# 1

print(reg.feature_names_in_)
# ['weight']
```

こちらは説明の通りでした。


### Methodsについて

fitとpredictについては皆さんご存じだと思うので省略。

get_params() , score()
```
print(reg.get_params())
# {'copy_X': True, 'fit_intercept': True, 'n_jobs': None, 'positive': False}

print(reg.score())
# 0.6734827472769156
```

get_params()はインスタンス化した際に何も指定していないのでデフォルトの値です。
reg_score()ではr_2値が算出されました。


他の関数については滅多に目にしないのと、
```
sklearn.set_config(enable_metadata_routing=True)
```
のような設定をしないといけないようなので省略します。
気になる方はドキュメントから確かめてみてください。

次は重回帰について学ぼうと思います。

# 参考
[Pythonで基礎から機械学習 「単回帰分析」](https://qiita.com/karaage0703/items/701367b6c926552fe505)

[sklearn.linear_model.LinearRegression](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression.set_fit_request)

[Signate](https://signate.jp/)