【ラビットチャレンジ】要点のまとめ - 機械学習 その２

# 1. はじめに
本記事はJDLA E資格の認定プログラム「ラビットチャレンジ」における機械学習のレポート記事である。
本記事では機械学習における「非線形回帰モデル」について要点をまとめている。

[【ラビットチャレンジ】要点のまとめ - 機械学習 その１](https://qiita.com/PoppeDwarf/items/92ba5a6ebd35a9f53ae0)
【ラビットチャレンジ】要点のまとめ - 機械学習 その２
[【ラビットチャレンジ】要点のまとめ - 機械学習 その３](https://qiita.com/PoppeDwarf/items/30944bca17d2c7f8c5ee)
[【ラビットチャレンジ】要点のまとめ - 機械学習 その４](https://qiita.com/PoppeDwarf/items/01cc119c707fe3e26f1d)
[【ラビットチャレンジ】要点のまとめ - 機械学習 その５](https://qiita.com/PoppeDwarf/items/6cb3929a4668ecf1c2ab)
[【ラビットチャレンジ】要点のまとめ - 機械学習 その６](https://qiita.com/PoppeDwarf/items/83f7e350e6720e801038)

# 2. 非線形回帰モデル
## 2.1. 非線形回帰モデリング
複雑な非線形構造を内在する現象に対して、実施するモデリング。

## 2.2. 基底展開法
回帰関数に「『基底関数』と呼ばれる既知の非線形関数」と「パラメータベクトル」の線形結合を使用。

- モデル数式：$ y_{i} = f(\boldsymbol{x}\_{i}) + \varepsilon\_{i} = w_{0} + \sum_{j=1}^{m}w_{j}\phi\_{j}(\boldsymbol{x}\_{i}) + \varepsilon_{i} $
$ \qquad y_{i}$：目的変数
$ \qquad w_{0}$：切片
$ \qquad w_{i}$：回帰係数
$ \qquad \phi(\boldsymbol{x}\_{i})$：基底関数
$ \qquad \boldsymbol{x}\_{i} $：説明変数
$ \qquad \varepsilon\_{i}$：誤差

- 説明変数：
$ \qquad \boldsymbol{x}\_{i} = (x_{i1}, x_{i2}, \cdots, x_{im}) \in \mathbb{R}^{m} $

- 非線形関数ベクトル：
$ \qquad \boldsymbol{\phi}(\boldsymbol{x}\_{i}) = (\phi_{1}(\boldsymbol{x}\_{i}), \phi_{2}(\boldsymbol{x}\_{i}), \cdots, \phi_{k}(\boldsymbol{x}\_{i}))^{T} \in \mathbb{R}^k$
$ \qquad k$次元の特徴ベクトル。事前に用意した$\phi_{1}～\phi_{k}$の写像で変換する。

- 非線形関数の計画行列：
$ \qquad \Phi^{(train)} = (\phi(x_{1}), \phi(x_{2}), \cdots , \phi(x_{n})) \in \mathbb{R}^{n \times k} $

- 最尤法による予測値：
$ \qquad \hat{y} = \Phi(\Phi^{(train)T}\Phi^{(train)})^{-1}\Phi^{(train)T} \boldsymbol{y}^{(train)} $

$ \qquad n$：データ数
$ \qquad i$：データの参照インデックス
$ \qquad m$：説明変数（次元）の数
$ \qquad j$：説明変数（次元）の参照インデックス
$ \qquad k$：基底関数の数

- よく使われる基底関数
  - 多項式関数　$ \phi_{j}(x) = x^{j} $

  - ガウス型基底関数　$ \smash{\phi_{j}(x) = exp \biggl\\{ \dfrac{(x - \mu_{j})^{2}}{2h_{j}} \biggr\\} } $  

  - スプライン関数 / Bスプライン関数

## 2.3. 未学習・過学習
- 未学習（Underfitting）  
訓練誤差（学習データに対する誤差）が十分に小さくなっていない状態。  
  - 対策：訓練誤差の小さくなるような表現力の高いモデルを使用する。
- 過学習（Overfitting）  
訓練誤差は十分に小さくなっているが、検証誤差が大きくなっている状態。  
  - 対策１：学習データ数を増やす。
  - 対策２：不要な基底関数を削除する。  
　　　　基底関数をデータ空間上に敷き詰めればデータの表現力が上がるが、それが過学習の原因にもなる。  
　　　　敷き詰めた基底関数から不要なものを間引けば表現力を抑えることができ、過学習対策になる。
  - 対策３：正則化法を利用する。

## 2.4. 正則化法（罰則化法）
「モデルの複雑さに伴って、その値が大きくなる『正則化項（罰則項）』を課した関数」を最小化する方法。
ただMSEなどの損失関数が最小となる点を探すのではなく、原点近辺においてパラメータに制約を与え、その制約下で最小になる点を探す方法。

- 正則化項
モデルの複雑さに伴って値が大きくなる項  
  - なし⇒最小二乗推定量  
  - L2ノルムを利用⇒Ridge推定量（縮小推定）  
パラメータを0に近づけるよう推定する  
  - L1ノルムを利用⇒Lasso推定量（スパース推定）  
いくつかのパラメータを正確に0に推定する  
　→影響の小さい変数を0にするため、変数を選ぶ指標になる。  
  
- ノルムいろいろなものの「大きさ」を表す量
  - L1ノルム：各成分の絶対値の和。マンハッタン距離
  - L2ノルム：通常の意味での距離。ユークリッド距離
  
- 参考
　[正則化の種類と目的 L1正則化 L2正則化について](https://ai-trend.jp/basic-study/neural-network/regularization/)
　[ノルムの意味とL1，L2，L∞ノルム](https://mathtrain.jp/lpnorm)
　[ディープラーニングで用いられる6つの距離計算](https://sitest.jp/blog/?p=6784)

- 数式
$ \qquad S_{\gamma} = (\boldsymbol{y} - \Phi^{n \times k}\boldsymbol{w})^{T}(\boldsymbol{y} - \Phi\boldsymbol{w}) + \gamma\boldsymbol{R}(\boldsymbol{w})$
$ \qquad \qquad S_{\gamma} $：モデルの複雑さに伴って、その値が大きくなる正則化項を課した関数
$ \qquad \qquad \boldsymbol{y} $：目的変数
$ \qquad \qquad \Phi $：非線形関数の計画行列
$ \qquad \qquad n \times k $：データ数×基底関数の数
$ \qquad \qquad \boldsymbol{w}$：回帰係数
$ \qquad \qquad \gamma\boldsymbol{R}(\boldsymbol{w}) $：正規化項

- 正則化（平滑化）パラメータ
モデルの曲線のなめらかさを調節するパラメータ。ハイパーパラメータのため、人が適切に設定する必要がある。

## 2.5. 汎化性能
- 汎化性能
学習に使用した入力だけでなく、未知のデータに対してどの程度正確に判断できるかという予測性能  
  
- 訓練誤差：モデルの学習内で使用する
$ \qquad MSE_{train} = \dfrac{1}{n_{train}}\displaystyle\sum\nolimits_{i=1}^{n_{train}}(\hat{y}\_{i}^{(train)} - y_{i}^{(train)})^{2} $  
  
- テスト誤差（検証誤差）：モデルの性能測定時に使用する
$ \qquad MSE_{test} = \dfrac{1}{n_{test}}\displaystyle\sum\nolimits_{i=1}^{n_{test}}(\hat{y}\_{i}^{(test)} - y_{i}^{(test)})^{2} $  
  
- 学習状況の判断
  - 訓練誤差、検証誤差ともに大きい⇒未学習
  - 訓練誤差は小さいが検証誤差は大きい⇒過学習
  - 訓練誤差、検証誤差ともに小さい⇒汎化しているモデルの可能性が高い
  
## 2.6. モデルの検証
### 2.6.1. ホールドアウト法
有限のデータを学習用と検証用の2種類に分割する方法。
手元に大量のデータがある場合でなければホールドアウト法は適さないことが多い。
また、分割時にはデータに偏りが生まれないよう留意する必要もある。

### 2.6.2. 交差検証（クロスバリデーション, Cross Validation(CV)）
イテレータという単位でホールドアウト法を繰り返し回す方法。

- 手順
  1. データを複数のブロックに分割する。
  2. その中のひとつ以外のブロックを学習データ、残したひとつのブロックを検証データとして学習を行う。  
（これをイテレータという。）
  3. すべてのブロックが必ず1回だけ検証データとして使われるようにイテレータを回す。  
（データ＝5分割の場合、全てのブロックを必ず1度だけ検証データとして扱うために、イテレータは5回回す。）

- 利点
　- データ数が比較的少なくても効率よく学習を行える。
　- 分割時のデータの偏りの影響が出にくい。

# 3. ハンズオン
## 3.1. 課題
以下の回帰モデルの訓練データと予測結果の確認。

  - 線形回帰モデル
  - 非線形回帰モデル
    - カーネル回帰にリッジ推定量を用いたモデル
    - 多項式を基底関数とした非線形回帰モデル
    - カーネル回帰にラッソ推定量を用いたモデル
  - サポートベクター回帰モデル
  - Kerasによる深層学習モデル

## 3.2. 演習結果
### 3.2.1. Googleドライブのマウント
1. 実行後「出力」に表示されるURLにアクセスしてGoogleドライブへのアクセスを許可する。
2. 許可した後の画面に表示されている認証コードをコピーして「出力」の認証コード入力欄に貼り付け、続行する。
![02_skl_nonlinear_regression_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/3ce4b1d3-3320-6006-46b3-181490caf5e7.jpeg)

### 3.2.2. 必要なモジュールのインポート
![02_skl_nonlinear_regression_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/7aa7670b-0b02-222f-47b3-d18d613561dc.jpeg)

### 3.2.3. 真の関数からノイズを伴うデータを生成
真の関数：$ f(x) = 1 - 48x + 218x^{2} - 315x^{3} + 145x^{4} $
加えるノイズ：標準正規分布による乱数に0.5を掛け合わせたものを使用

![02_skl_nonlinear_regression_03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/186a3650-4241-c4af-bbd8-4a971c8c672b.jpeg)

### 3.2.4. 線形回帰モデル
一見して誤差が大きく、モデルが適していないことがわかる。
![02_skl_nonlinear_regression_04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/3b8e00a5-6080-b418-77e2-f1487a1406af.jpeg)

### 3.2.5. カーネル回帰にリッジ推定量を適用したモデル（scikit-learnのKernelRidgeを利用する）
カーネルリッジ回帰モデル：非線形回帰のひとつであるカーネル回帰にリッジ推定量を適用したモデル。
- KernelRidge()：カーネルリッジ回帰モデル
  - alpha：正則化項のハイパーパラメータ
  - kernel：使用するカーネル関数
    - rbf：RBFカーネル
データのプロットに沿っており、比較的適したモデルであることがわかる。
![02_skl_nonlinear_regression_05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/4cae597d-7b99-ebd0-1cec-a08fdc85c5eb.jpeg)

### 3.2.6. カーネル回帰にリッジ推定量を適用したモデル（scikit-learnのKernelRidgeを利用しない）
自分でカーネル関数を設定し、リッジ回帰モデルに学習させている。
- rbf_kernel：RBFカーネル関数
- Ridge：リッジ回帰モデル
データのプロットに沿っており、決定係数も0.7740と高い。比較的適したモデルであることがわかる。
![02_skl_nonlinear_regression_06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/5d683e33-7fb9-d9e5-7908-4eafef2b1941.jpeg)

### 3.2.7. 多項式を基底関数とした非線形回帰モデル
1次式から10次式までの多項式をそれぞれ基底関数にした非線形回帰モデル。
プロット結果から高次の式を使ったものほど表現力が高くなっているのがわかる。
![02_skl_nonlinear_regression_07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/7a7e174b-0c97-46d2-e8a3-5beb6830f46e.jpeg)

### 3.2.8. カーネル回帰にラッソ推定量を適用したモデル
自分でカーネル関数を設定し、ラッソ回帰モデルに学習させている。
- rbf_kernel：RBFカーネル関数
- Lasso：ラッソ回帰モデル

プロットしたグラフのとおり、まったく適していないモデルといえる。
決定係数もほぼ0に近いマイナスになっている。
![02_skl_nonlinear_regression_08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/97c5ccc5-101c-5d34-66af-ce393276af1d.jpeg)

### 3.2.9. サポートベクター回帰モデル
![02_skl_nonlinear_regression_09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/c6e5d2a0-8fe7-425b-751e-e10f9eb0fd8d.jpeg)

### 3.2.10. Kerasによる深層学習モデル
![02_skl_nonlinear_regression_10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/e52430a8-f66f-8bc7-670f-2eddc7bb5c27.jpeg)
![02_skl_nonlinear_regression_11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/cf14965d-f9ff-a4dc-500d-6b9e533887ee.jpeg)
![02_skl_nonlinear_regression_12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/8e8ee398-3976-e425-c3b4-78b3f577dbf6.jpeg)


### 3.2.11. 参考
　[scikit-learnで線形モデルとカーネルモデルの回帰分析をやってみた - イラストで学ぶ機会学習](https://qiita.com/kotaroito/items/4eb29d42d7f8c534332f)
　[カーネル法入門](https://masamunetogetoge.com/kernelpart1)
　[線形な手法とカーネル法（回帰分析）](https://qiita.com/wsuzume/items/09a59036c8944fd563ff)
　[RBFカーネルのハイパーパラメータは何物か？](https://upura.hatenablog.com/entry/2018/01/22/003429)
　[sklearn.kernel_ridge.KernelRidge -- scikit-learn 0.23.1 documentation](https://scikit-learn.org/stable/modules/generated/sklearn.kernel_ridge.KernelRidge.html)
　[Scikit-learnの正則化付き重回帰モデル](https://helve-python.hatenablog.jp/entry/scikitlearn-regularized-regression)
　[scikit-learnのPolynomialFeaturesで多項式と交互作用項の特徴量を作る](https://www.haya-programming.com/entry/2019/07/14/043223)
　[Python: scikit-learn の Pipeline を使ってみる](https://blog.amedama.jp/entry/2018/07/07/223257)
　[PythonでLassoを実装](https://qiita.com/kotamatsuoka/items/d09f09f23308627b42ab)
　[決定係数の定義と相関係数との関係 | 高校数学の美しい物語](https://mathtrain.jp/ketteikeisu)
　[サポートベクター回帰(Support Vector Regression, SVR)～サンプル数10000以下ならこれを使うべし！～](https://datachemeng.com/supportvectorregression/)