ロジスティック回帰について調べてみた

ロジスティック回帰

いろいろ間違っているところはあると思いますが、ロジスティック回帰について調べた内容をまとめてみました。
数式は分からないけどChainerとかのオープンソースフレームワークでどんなことすれば良いのかイメージが付くぐらいになるのを目指したいと思います。

概要

ベルヌーイ分布に従う変数の統計的回帰モデルの一種である。

ベルヌーイ分布とは

取りうる値が2つであるような確率変数1つで記述する分布、例えばある人が"YES"と答える確率がxで"NO"と答える確率が1-xであるような確率分布を表すのに使われる。この場合に3回質問して3回とも"YES"と答えるならx3で、2回YESで1回NOなら3(1 - x)x2と言ったように表すことができる。自然言語処理等で使われる場合は1つの確率変数で分析を行うには無理があるのでは多変数ベルヌーイモデルが使われているはず。

多変数ベルヌーイモデル

多変数ベルヌーイモデルの場合複数の独立した確率した確率変数で確率分布を表します。例えば語彙にgood, bad, exciting, boringの4つがあり、4つの語彙限定でそれぞれの単語の発言確率をpGood, pBad, pExciting, pBoringとした場合(bGood + bBad + bExciting + bBoring = 1)に"good bad booring exciting boring good boring"の順番で発言する確率を求める場合に以下のようになる。

順番が決まっている場合は
pGood^2 * bBad^1 * bExciting^1 * bBoring^3となる。
単語の順番を気にしないのであれば以下のように求められる。
       7!            
----------------- * pGood^2 * bBad^1 * bExciting^1 * bBoring^3
2! * 1! * 1! * 3!           

ここでポジティブな人の各語彙の発言確率を以下のようになっており
(pGood, pBad, pExciting, pBoring) = (0.4, 0.1, 0.4, 0.1)
でネガティブの各語彙の発言確率が以下になっている場合
(pGood, pBad, pExciting, pBoring) = (0.3, 0.2, 0.3, 0.2)
その場合の"good bad booring exciting boring good boring"と発言した場合その人がポジティブかネガティブかの確率は以下のように求めることができる。

ポジティブな人の場合の確率
        7!            
----------------- * 0.4^2 * 0.1^1 * 0.4^1 * 0.1^3 = 0.002688
2! * 1! * 1! * 3!           

ネガティブな人の場合の確率
        7!            
----------------- * 0.3^2 * 0.1^2 * 0.3^1 * 0.2^3 = 0.018144
2! * 1! * 1! * 3!           

となりネガティブな人が発言する方が確率が高いため、おそらくネガティブな人だろうと判定できます。

改めてロジスティック回帰

ベルヌーイ分布とは何ぞやの部分がなんとなくわかったところでロジスティック回帰の流れを確認してみたいと思います。やりたいこととしては学習用のドキュメントデータとそれに対する分類結果のデータセットをもらった後に各分類ごとの最適な確率変数を求めて、それぞれの分類に対しての確率を求められるようになることです。

機械学習を始めたばかりですと最適化の流れがどうなっているのか把握できないと思うのですが、大体こんな感じになっていると思います。

1.学習データの読み込み

 ↓

2.確率変数のパラメータ初期化

 ↓

3.確率的勾配降下法により最適なパラメータを求める。
 3.1一度の学習で使うデータ数はどうするか?バッチ学習か?ミニバッチか?
 3.2各層の出力を決める活性化関数には何を使うか?ソフトマックス関数か?
 3.3誤差関数には何を使うか?交差エントロピーか?
 3.4誤差逆伝搬によりパラメータを更新する方向を決める?
 3.4更新するパラメータの大きさはどう決めるか?AdaGradか?それとも、、、

 ↓

4.学習にして最適化されたパラメータにより入力データに対して各分類結果ごとの確率を算出して分類を行う

すごいザックリまとめるとこんな感じになると思いまして確率的勾配降下法によるパラメータ最適化の工程について簡単に説明したいと思います。

ミニバッチ

機械学習では大量の学習データを扱います。そのためすべてのデータを読み込んでからパラメータを更新するのであれば計算コストが大きくなってしまいます。それを防ぐために学習データからサンプルを抽出します。抽出したサンプルをミニバッチと呼びそれに対して学習を行っていきます。サンプルの抽出方法についてもランダムに取ったりループの中のインデックスから定数取ってくるかとかいろいろあるようです。

活性化関数

ロジスティック回帰は多クラス分類のためソフトマックス関数が使われます。簡単に説明すると各分類結果に対する数値を合計すると1になるというものです。例えばポジティブ、ネガティブに分類する場合であれば、ポジティブに分類する数値とネガティブに分類する数値の合計がいっつも1になるようにするものです。

誤差関数

多クラス分類で使われる誤差関数は交差エントロピーです。ロジスティック回帰では抽出したミニバッチとその時点でのパラメータで計算(順伝播)し、それと正解データを比較してどれだけづれているか計算するのに交差エントロピーを使います。

誤差逆伝搬

どの方向にパラメータを更新すれば良いのかを求めるために更新パラメータの差分と誤差関数で微分を行います。誤差逆伝搬と言われておりましてどんな計算しているのか気になる場合は以下を参照したら良さそうです。 https://www.slideshare.net/piroyoung/ss-50433746?next_slideshow=1  

パラメータ更新

各パラメータの更新方向は求められたので、最適化アルゴリズムによりどれだけパラメータが更新するかを求められるます。例えばAdagradではまれに現れるパラメータは大きく更新し、よく出るパラメータは小さく更新するなど最適化アルゴリズムごとで更新方法が異なっています。詳しくは以下を見たら良いと思います。
http://postd.cc/optimizing-gradient-descent/#gradientdescentoptimizationalgorithms

回帰分析

確率的勾配効果により各パラメータが最適化されたらそれを使って分類を行います。

Pythonオープンソース機械学習フレームワークのChainerであれば簡単にロジスティック回帰行えます。以前試した時のを以下にまとめています。 http://steavevaivai.hatenablog.com/entry/2017/03/20/232339