1. hiro88hyo

    Posted

    hiro88hyo
Changes in title
+機械学習のアルゴリズム(線形回帰の一般化)
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,76 @@
+# はじめに
+以前、「[機械学習の分類](https://qiita.com/hiro88hyo/items/c00dcf8f083ba3d76af8)」で取り上げたアルゴリズムについて、その理論とpythonでの実装、scikit-learnを使った分析についてステップバイステップで学習していく。個人の学習用として書いてるので間違いなんかは大目に見て欲しいと思います。
+
+これまで、「単回帰」、「重回帰」と見てきたが、どちらも線形回帰という同じ分野の中で話をしてきた。今回は、線形回帰を一般化した「**線形基底回帰モデル**」と損失関数を最適化するための「**勾配降下法**」についてまとめたいと思う。今回参考にしたのは以下のサイトです。
+
+* [PRMLの線形回帰モデル(線形基底関数モデル)](https://www.slideshare.net/yasunoriozaki12/prml-29439402)
+
+
+# 基本
+データ列に対する近似曲線を引くために、単回帰モデルは$$y=Ax+B$$重回帰モデルは
+
+```math
+y=w_0x_0+w_1x_1+\cdots+w_nx_n
+```
+で近似させるものだった。さらにいうと、単回帰については、重回帰の式の2項目までを使ったに過ぎないことがわかる。
+
+さて、各項の重み$(w_0,w_1,\cdots,w_n)$とすると、モデルの関数は実はなんでもよくて、これを$y=\phi(x)$とおくと、
+
+```math
+y(\boldsymbol{x}, \boldsymbol{w}) = \sum_{j=0}^{M-1}w_j\phi_{j}(\boldsymbol{x})
+```
+と表される。$\boldsymbol{w}=(w_0,w_1,\cdots,w_{M-1})^T$、$\boldsymbol{\phi}=(\phi_0,\phi_1,\cdots,\phi_{M-1})^T$、とおく。$\phi_0=1$(切片項)とすると、
+
+```math
+y(\boldsymbol{x}, \boldsymbol{w}) = \boldsymbol{w}^T\phi(x)
+```
+になる。この$\phi(x)$を**基底関数**という。
+
+# 様々な基底関数
+一般化された式の意味するところは、線形回帰というのはつまり、ある基底関数を組み合わせて与えられたデータ列をもっともよく表す係数の列$\boldsymbol{w}$を見つけること、ということです。
+
+* 単回帰、重回帰。回帰直線で近似する際に使う。$$\phi_j(x)=x$$
+* 多項式回帰。多項式で近似。$$\phi_j(x)=x^j$$
+* ガウス基底関数$$\phi_j(x)=\exp\left\\{-\frac{(x-\mu_j)^2}{2s^2}\right\\}$$
+* シグモイド基底関数。ニューラルネットでよく使われる。$$\phi_j(x)=\sigma(\frac{x-\mu_j}{2s})$$
+* フーリエ基底。フーリエ変換で使われる。$$\phi_j(x)=\exp(i\theta)$$
+
+scikit-learnでは回帰に様々な基底関数が使えるようになっています。
+
+* [https://scikit-learn.org/stable/modules/classes.html#sklearn-metrics-metrics](https://scikit-learn.org/stable/modules/classes.html#sklearn-metrics-metrics)
+
+
+# 回帰係数を求める
+単回帰や重回帰では、残差二乗和を最小にするような係数を求めました。単回帰では数学的にwを求めることが可能でしたが、基底関数が複雑な場合や、データの次元が多い場合には解析的に解を求めることが非常に困難な場合が多いです。そういう場合に、近似的に係数を見つける必要があります。その際に用いるのが「**勾配降下法**」です。文字通り、坂(勾配)を下がっていきながら最適な値を見つける手法です。
+
+数学的に解く方法も含め、係数をどう見つけるか考えてみましょう。なお、以下に詳しく書かれています。
+
+* [確率的勾配降下法のメリットについて考えてみた](https://qiita.com/koshian2/items/028c457880c0ec576e27)
+
+## 数学的解法
+
+単回帰や重回帰で述べたような式変形で解を探すやり方です。平方完成や偏微分から連立方程式を解くやり方です。数式が簡単なら問題はありませんが、モデルが複雑な場合は解けないケースが出てきます。
+
+## 勾配降下法
+
+勾配法は、文字通り損失関数の勾配を下っていく方法です。最適なパラメータを求めるためには損失関数の値が小さい必要があるが、小さい値に向かって坂を下っていくイメージです。
+
+よく機械学習のサイトで紹介されるのは最急降下法と確率的勾配降下法だが、ディープラーニングの世界になると、使われる勾配降下法が増えます。ディープラーニングが盛んになってさらに発展している分野と言えるかもしれません。
+
+### 最急降下法
+
+損失関数$f(x,y)$が与えられた場合に、その勾配ベクトルは$x$と$y$それぞれで偏微分すると、$$ \nabla f(x,y) = \biggl(\frac{\partial f}{\partial x},\frac{\partial f}{\partial y}\biggr) $$なので、初期位置$(x_0,y_0)$を適当に決めて$f[(x_0,y_0)-\eta\nabla f(x_0,y_0)]$を次の点にして結果が収束するまで繰り返します。$\eta$は学習率と呼ばれます。
+
+ただ、この方法の弱点は、損失関数は必ずしも一つではないということです。初期値の取り方を帰ると収束する位置も変わります(局所解に収束する)。
+
+### 確率的勾配降下法(Stochastic Gradient Descent:SGD)
+
+最急降下法では、参照する点は1つでしたが、確率的勾配降下法では、複数のサンプルを参照します。任意の数のサンプルを抽出しシャッフルしたものを用い、$$ w := w-\eta\sum_{i=1}^n \nabla Q_i(w)$$を計算していきます。
+
+ほとんどの場合はSGDの方が収束が早いらしいですが、最急降下法の方が計算は早いです。ほとんどの場合はSGDを使っていれば問題ないのではないかと思います([Wikipedia談](https://ja.wikipedia.org/wiki/%E7%A2%BA%E7%8E%87%E7%9A%84%E5%8B%BE%E9%85%8D%E9%99%8D%E4%B8%8B%E6%B3%95))。
+
+# まとめ
+
+単回帰や重回帰を発展させて、一般的な回帰と解法について書きました。これまでの理論を用いることで、いろんなサンプルに対する回帰が求められると思います。
+
+本当はpythonの実装も試してみようと思ったんですが力尽きました。次は、pythonでの実装をいくつか試して見たあとに、過学習(overfitting)や正則化(regularization)についてまとめてみたいと思います。