線形回帰は「単回帰」、「重回帰」という二つの方法に分けられます。「機械学習の入り口「線形回帰」の実装を Python × NumPy で体験」で説明したものが単回帰です。重回帰は、単回帰よりもさらに複雑なタスクに対応できます。
また、ここでは仮説を定義する際、配列と行列積を使った書き方を説明します。
重回帰とは?
「機械学習の入り口「線形回帰」の実装を Python × NumPy で体験」では、例として”身長から体重を予測”しました。この身長のように、予測するために用いる変数を「説明変数」といい、一つの説明変数で予測することを「単回帰」といいます。
しかし、身長のみから体重を予測するのは適切でしょうか?実際には身長が同じでも体形や食べる量が違えば体重も異なるはずです。
そこで、今回は身長に加えて「一日の摂取カロリー」という別の説明変数を加え、二つの説明変数から体重を予測しようと思います。
このように複数の説明変数を用いるものを、単回帰に対して「重回帰」といいます。
今回は重回帰を説明していきますが、基本的なことは単回帰と変わりません。大きな違いは仮説です。
説明変数をX、予測値をhとして、単回帰では仮説を
と定義しました。すなわち直線です。
対して重回帰では、説明変数の数だけ項を増やすだけです。今回は二変数なので、二つの説明変数をX1とX2として
とします。
これは単回帰の直線に対して、以下のように平面を表す式になります。
線形回帰のゴールは仮説の最適なパラメータ(単回帰ではaとb)を見つけることでした。すなわち、今回の重回帰ではa1、a2、bの三つのパラメータについて最適な値を見つけることになります。
ですが学習の方法などは変わらないので、前回説明した線形回帰の流れをおさえていれば簡単です。
では、まずはデータを準備します。
データの準備
まずは重回帰で使用するデータを用意します。今回は、30人の身長と一日の摂取カロリーと体重のデータをNumPy配列で作成します。
基本は単回帰の時と同じですが、今回はデータが三次元で表されるので、グラフ表示の書き方が少し変わります。
グラフ表示すると、データが三次元上に分布しているのがわかります。
なお、今回の3Dグラフはマウスでドラッグすることで視点を自由に動かすことができるので、様々な方向から見てみてください。
標準化
単回帰の時と同様、データのスケールを揃えるために標準化を行います。
標準化について詳しくは「データの前処理:正規化・標準化のプロセスをプログラムで体験」をご覧ください。
今回はこのデータを用いて重回帰を行います。すなわちこの分布に合う平面を予測し、その平面を使って新しい入力値(身長、接種カロリー)に対しても適切な予測値(体重)を得られることが目標です。
重回帰の実装
線形回帰のゴールはデータに合う仮説を求めることです。基本的な流れは単回帰と同じで以下の通りです。
今回もこの流れに沿って、
1.仮説 → 2.目的関数 → 3.パラメータ更新(学習)
の順に重回帰を実装していきます。
1. 仮説
今回は説明変数が二つあるので、仮説は
です。
単回帰の時と同様にパラメータを一つ一つ定義すると以下のように書くことができます。
a1=1
a2=1
b=1
h=a1*X1+a2*X2+b
ただ、今回は説明変数が二つなのでいいですが、説明変数が多くなるとこのように一つ一つ書くのは大変です。そこで今回は仮説の実装の仕方を少し変えてみます。
具体的には、パラメータa1、a2、bを1つの配列にまとめると、仮説を次のように行列積を用いて表すことができます。
つまり、a1、a2、bをまとめた配列をtheta、X1、X2、1をまとめた配列をXと置くと、実装ではドット積を使って「h=np.dot(X,theta)」と書くだけで仮説を定義できます。
実装は以下のようになりますが、こうすることでパラメータの初期化などが一行ですみ、また関数に渡す際なども1つの変数ですむのでとても便利です。
これで行列積を使って仮説が定義できました。グラフとして表示してみましたが、仮説はあまりデータに重なっていません。単回帰と同様に、これから最適なパラメータを見つけていきます。
以降もパラメータはthetaでまとめた形で扱います。a1、a2、bを単体で扱いたい時は、配列のインデックスを使ってtheta[0]、theta[1]、theta[2]として取り出せます。
2. 目的関数
目的関数は「予測値(仮説による値)と正解値の誤差」なので、単回帰の時と何も変わりません。
なので前回と同様に、次の二乗和誤差で定義します。
Jやhの右下のθは、パラメータがθであることを表しています。また、hとyの右上のiは、i番目のデータを表しています。
実装も単回帰の時と変わりません。
パラメータの初期値を入れた結果、目的関数の値が88くらいになったと思います。ここから、この値が小さくなるようにパラメータthetaを更新していきます。
3. パラメータ更新(学習)
単回帰と同様に以下の式で表される最急降下法(勾配降下法ともいう)を使います。
パラメータが3つに増えたので、更新式も3つになります。勾配部分は、目的関数をそれぞれのパラメータで微分すると
となります。実際に計算して確かめてみてください。
実装も、パラメータが1つ増えただけで単回帰と変わりません。
パラメータの値が更新され、目的関数の値もパラメータを更新するたびにしっかり下がっています。
グラフも表示してみましたが、いい感じにデータにフィットした平面(仮説)が得られていると思います。ぜひマウスで視点を動かして確認してみてください。
未知データの予測
最後に、得られた仮説によって未知のデータに対する予測を行ってみましょう。
※単回帰の時と同様に、予測に使うデータも標準化し、得られた予測値を元のスケールに戻す必要があります。
まとめ
以上で重回帰の説明を終わります。このように、説明変数が増えても仮説を変えることで対応できることがわかったでしょうか。
今回は説明変数が二つでしたが、さらに多くても同様に対応できます。(ただし、データは3次元でなくなるので可視化するのは難しいです。)
今回の例やお店の売上予測など、実際のデータは様々な要因(説明変数)で変化します。なので、単回帰と合わせて重回帰もぜひ覚えておきましょう。