
初めまして、3月からハカルスにジョインした宇佐見と申します。
データサイエンティストトレーニング枠として入社し、
データミックス様との共同開発プログラムなども受講させて頂いて、日々勉強の毎日です。
その一環として、先日機械学習の勉強会である「機械学習・データ学習スプリングキャンプ」に参加しましたので、その内容と学んだことについて書かせて頂きます。
機械学習・データ学習スプリングキャンプとは
機械学習・データ学習スプリングキャンプとは、大阪大学数理・データ科学教育研究センター(MMDS)主導で企画されたイベントで、研究者のみならず、学生や若手のデータ分析を扱う社会人がデータ科学を学ぶ場として開催されました。イベントは2日構成で、1日目は「ガウス過程と機械学習入門」、2日目は「今流行っているベイズ統計学とは一体なんなのか」という講義と「機械学習の数理: 手を動かしてみる」という講義が同時開催されていました。私は2日目は「機械学習の数理」の方に参加しました。
どちらも大盛況でしたが、特に1日目の「ガウス過程と機械学習入門」は早々に満席になってしまうほどで、同名の書籍が講義の4日前に発刊されたこともあってか、当日の質問用に用意されたSlackチャンネルでは数学的な議論が多くなされていました。リアルタイムに議論を追うのは至難の業でした…
2日目の「機械学習の数理: 手を動かしてみる」では単純な線形回帰から、分類、情報量基準、決定木、SVMなどを1日でこれでもかと詰め込んでいく講義でした。数式での解説もあるのですが、Rでの実装の時間もあり、数式に触れながらも実際に機械学習モデルを使用することに重点を置いた講義でした。
どちらの講義も濃厚なテーマを6時間に詰め込んでいるという点で非常にハイスピード、ハイレベルなのでその場で全部すぐ理解!ということは私には荷が重かったのですが、どちらの講義にも言えることは、我々参加者の理解を深め、扱ったテーマに興味を持って欲しいという気持ちが講談頂いた先生方から強く感じられることでした。Slackで丁寧にご返答頂けることはもちろん、随時質問やリアクションを気にしてらしていて、ご自身の取り扱われているテーマに新たに踏み入れる我々を歓迎してくださっているようでした。
というようにポジティブに捉えたところで、私も未熟ながら「ガウス過程と機械学習」に踏み入って得た理解を少しばかり書いていこうと思います。
ガウス過程回帰のメリット
そもそも単純な線形回帰ではなくガウス過程回帰を用いるメリットはなんなのでしょうか?
一つは、「どれくらいわからないのかわかる」ということです。ガウス過程を用いた回帰モデルというのは、出力が確率分布で得られるので、出力の分散がわかります。つまりどれくらいまでなら自信があるかどうかが見えるということです。通常の線形回帰モデルでは関数が一意に定まるので、データの分散は表現できません。また分散が見えることから、分散の大きいところのデータを増やそう、とか小さいところはもう集めなくても良いか、という風に効率的にデータ探索を行えます。
二つ目は、「モデル選択や特徴選択ができる」ということです。この投稿では詳しく触れませんが、データをフィッティングする上で適切な関数を生成するようなモデル、また重要な特徴をそれぞれ関数の集まりを比較することで適切に選択できます。
具体的な応用例としては、医療検査情報の診断システムが答えを出すとき、データ数が少なくて(珍しい症例や検査情報の不足など)判断に自信がないことをシステムがアナウンスしてくれれば、セカンドオピニオンを求めることなどを適切に考慮することができるのではないか、と参考書(ガウス過程と機械学習)では述べられています。このことを「正直な人工知能」と著者は表現しています。
ガウス過程回帰の実装
続いて実際にガウス過程回帰を用いてデータからモデルを作成してみます。
細かい数式や導出は省きますが、詳しくはMLPシリーズの「ガウス過程と機械学習」をご参考下さい。
また、全ソースコードはこちらまで。
まず以下のようなサンプルデータを考えます。
これは
y = 0.1x +0.3sin(x) + ε
から[-5~5]の範囲で一様乱数xを発生させ、それを用いて30個のデータをサンプリングし、プロットしたものです。εは標準正規分布に従う乱数に0.5をかけたものです。
まず単純な線形回帰を行ってみます。
線形回帰の重みベクトルの解は下記の通りに求められます。
Φは基底関数から成る計画行列です。
※ちなみに損失関数が二乗誤差の場合(最小二乗法)の時に重みベクトルは上記の解になります。
ここでは基底関数をφ0(x)=x, φ1(x)=sin(x)である前提で解くと、以下の様にいい感じの曲線を引いてくれました。
続いてはガウス過程回帰です。
ガウス過程回帰とはなんなのかというと、ざっくりした私の理解としてはカーネル(RBFカーネルなど)の和や積で複雑な形状の関数をフィッティングしてモデル化する、といったものです。
なぜこの様な手法が必要なのかというと、単純な線形回帰モデルで基底関数を配置した場合、次元が増えれば増えるほど倍々に基底関数の個数が増えていってしまい、計算量が莫大なものになってしまうからです(次元の呪いと言います)。
これを回避するために、計画行列と重みベクトルに対して期待値をとると、その結果から出力yが入力の共分散行列に従う多変量ガウス分布になることがわかります。そして共分散行列の要素を与える関数をカーネル関数と言います。ここでカーネル関数は実際には特徴ベクトルの内積なのですが、カーネル関数さえわかればyの分布はわかるので、もはや特徴ベクトルを知る必要は無くなります。一つ一つの基底関数がわからなくてもいいわけです。これをカーネルトリックと言います。また、カーネル関数として利用できるカーネルは様々なものがありますが、カーネル同士の和や積もまたカーネルとして用いることができます。
※ちなみに私は大学2回生のころに初めてカーネルトリックという言葉を聞いたのですが、参考書を読んでやっとその意味と意義を理解することができました。すっきりしました。
話は戻して、ここからはガウス過程回帰を簡単に利用できるGPyというライブラリを利用して実際にモデルを作成してみます。
GPyを用いて、先ほどのデータに対してモデル作成を行ってみます。
カーネルはRBFのみ用いています。
以下の様に実行すると、簡単にガウス過程回帰を行うことができます。
このグラフでは、あらゆるx(ここではx=[-5,5]しか図示していません)に対してのyの期待値が青線であり、薄青の帯の様なところは事後分布の誤差範囲を示しています。
ここで初めに述べた「どれくらい自信があるかわかる」というのが見て取れると思います。予測がずれたとしても、この帯の間には収まりそうだということがわかります。
とはいえ幅が広すぎるのでは?と思われるかと思います。これはガウス過程回帰で用いているカーネルをパラメータを最適化せず用いているからです。GPyには最適化の機能もついているので、パラメータ最適化を行ってみます。
以下の様に簡単にできます。
最適化を行うことで、誤差範囲を小さく収めることができます。最適化手法は選択肢としてはSCG,L-BFGS,TNCの三つがあります。ソースを読むとデフォルトは”preferred optimizer”と書いてあるので適切なやつを選んでくれるのでしょうか…今回はデフォルトパラメータで最適化したのですが、L-BFGSが選ばれていました。
y = 0.1x +0.3sin(x)を黄色線として、線形回帰による予測とガウス過程回帰の結果を同時にプロットしたものがこのグラフになります。線形回帰もガウス過程回帰でもそれなりの予測結果を求められている様に見えますが、双方の大きな違いは、事前にモデルを設定しているかどうかというところです。
例えば事前のモデルの設定に失敗した場合の線形回帰の結果をみてみます。
基底関数をφ0(x)=x^2, φ1(x)=x^3として線形回帰を行ってみます。
すると図の様な予測になってしまいます。
線形回帰の場合、事前に私が設定した関数がわかっていたため、その関数を上手く表せる基底関数(ここではφ0(x)=x, φ1(x)=sin(x))を用意した場合には基底関数の線形和としていい感じに表現できていますが、異なる基底関数を用意した場合には予測が大きくずれてしまうこともあります。ガウス過程回帰ではモデルの設定なしにこれだけの予測ができていて非常に面白いです。
最後に
今回は機械学習スプリングキャンプで学んだガウス過程回帰を用いて、単純な線形回帰と結果を比較してみました。モデルの設定が要らないこともさることながら、出力の平均や分散を求められるので結果の信頼性が目に見えて得られるというのはとても面白い結果でした。とはいえ本投稿では触れられませんでしたが、ガウス過程回帰には逆行列計算の際にO(N^3)の計算時間がかかるという問題があり、それに対する解決策の一つとして補助変数法など挙げられているのですが、そちらは次回以降の投稿で触れていければと思います。
最後に、ここまで拙い説明であったかと思いますが、お読み頂きありがとうございました。
ハカルスでは一緒に働く仲間を募集しています
組み込み、FPGA といった環境で機械学習を動かすことに 興味があるエンジニアの方や、データサイエンティストとして機械学習の研究開発を行いたい!という方を募集しています。ご興味がある方は、ぜひ 採用ページ よりお気軽にご応募ください。