教師あり学習

jhozumi 執筆者 Jun Hozumi

 この章では教師あり学習の例として「サポートベクターマシン(SVM)」という素性とラベルの組を渡すことで分類を行う機械学習の手法を取り上げます。
 SVMによる分類をライブラリを用いながら実践できるようになることを目標とします。

この節では下記のことを学習します。

教師あり学習とは

 教師付き学習(Supervised Learning)は、入力(X)と出力(y)の組からなる教師事例をもとに学習を行い、出力が未知である入力事例に対して正しい出力を予測させることを目的とします。流れとしては、人間が過去問(教師事例の入力)とその解答(教師事例の出力)を学習した後、その経験をもとに未知の問題(入力事例)を解くことに似ていると言えるでしょう。

 また教師付き学習には、入力事例から出力を直接予測する回帰(例:明日の日経平均株価はいくら?、明日の最高気温は何度?)と、クラスと呼ばれるグループに分ける分類(例:このメールは迷惑メールか?、このチームは明日の試合に勝てるか?)があります。この章で習得を目指すSVMは分類を行います。

 そして教師あり学習には、本章で扱うSVMの他にニューラルネットワークや隠れマルコフモデルなど様々な手法があります。この章で使用してもらうpythonのscikit-learnというライブラリを用いればこれらの手法も簡単に実装できるので、この章を終えた後にやってみるといいでしょう。

サポートベクターマシン

サポートベクターマシン(SVM)とは

 サポートベクターマシン(Support Vector Machine、以下SVM)は、教師付き学習においてクラスの数が2つである問題に用いられる線形分類器です。(多クラスSVMなど変種も存在しますが本章では扱いません)

 まず教師事例を正クラス負クラスの2クラスに分けます。「未成年と成年」や「課金するユーザと課金しないユーザ」など、目的に応じて2つに分けましょう。そして正クラスである事例を正例、負クラスである事例を負例と呼びます。

 次に、SVMの学習に用いられる教師事例を(X,y) (XR^n, y={1,−1})の形式で用意します。(例:([0,3,7],1))Xは入力となる素性ベクトルであり、素性(分類に用いるデータ)を構成する情報を実数として与えておきます。yは出力となるクラスラベルであり、正例には1、負例には-1としておきます。
 分類をうまく行うにはXに何を用意するかが重要になります。「迷惑メールの分類のために『お買い得』や『人妻』という単語の出現回数を素性に入れよう」「式場予約をしてくれるかどうか当てるために、配偶者の有無を1か0かのラベルにして素性に加えよう」「ユーザの性別分類に年齢は関係なさそうだから、それは素性から外そう」など、分類に効果的である情報は何かを考えて素性に加えていきましょう。ただし、すべての教師事例Xの次元は揃えておいてください。

 この教師事例を用いて、分類器の学習を行います。そしてクラスが不定である入力事例を学習した分類器で分類して、出力が正となれば正例、負となれば負例と判断します。

 SVMにおける分類器の学習について簡単に解説しておきます。SVMの学習では、入力事例をもとに正例と負例を分ける分離平面の決定をマージン最大化という戦略のもとに行います。学習で分離平面を決めた後、入力事例が分離平面を境界面として正例側と負例側のどちら側になるかを見ることで、それが正例か負例かを判定します。また正例と負例とを全て正しく分けられる分離平面を設定するハードマージンSVMでは分離平面を決定できないことが多々あるので、ソフトマージンSVMという一部制約を緩めたSVMが一般に用いられます。この辺の詳しい説明をするにはスペースが足りないので、最後にあげた参考書籍を読んでおいて学んでおいてください。章末課題で出ます。

svm

カーネル法

 一般に使われるSVMでは、分類の精度を高めるためにカーネル関数を用いたカーネル法が使われます。ライブラリに予め実装されている多項式カーネルや動径基底カーネル(RBFカーネル)などのカーネル関数をSVMで分類する際に使用してみましょう。またカーネル関数にはパラメータが設定ができ、これもうまく設定することで分類精度を向上させることができます。

 カーネル法の大まかなイメージを説明しておきます。カーネル法では入力事例がカーネル関数によって特徴空間へ写像され、その特徴空間において分離平面を設定します。そしてその分離平面は写像される前の入力空間では平面ではなくなります(超平面と呼びます)。分離平面が曲面になって、よりよい境界面が設定できるイメージでしょうか。これもさらに詳しい説明をするにはスペースが足りないので、参考書籍を読んでイメージを掴んでおいてください。

SVMの実装

 pythonのライブラリであるscikit-learnを用いて、SVMを実装してみましょう。まず準備としてscikit-learnを導入しておきます。
例 (pipを使用する場合):

pip install scikit-learn

 準備ができたらpythonでSVMをやってみましょう。入力事例のXとyを適切なリスト型になるよう用意することがポイントです。また、scikit-learn.svmでは負例のラベルは0とするので注意してください。(他のライブラリであるlibsvmは負例のラベルを-1とします)

例:
教師事例: (X,y) = ([-4,-4,-1],1),([-2,-2,0],1),([1,1,2],0),([3,3,5],0)
入力事例: X = [2,2,4]

from sklearn import svm
X = [[-4,-4,-1],[-2,-2,0],[1,1,2],[3,3,5]] #入力事例
y = [1,1,0,0] #クラスラベル
clf = svm.SVC(kernel='rbf') #Support Vector Classification(分類)、RBFカーネルを使用
clf.fit(X, y) #学習
clf.predict([2,2,4]) #予測

clf.predict([2,2,4])の返り値はarray([0])となり、入力事例は負例に分類されたことが確認できるでしょう。
また、ここに載せた例は非常に簡単なもので、他にも様々な設定ができるので、このリファレンスを読んで色々試してみましょう。

リサンプリング法

過学習を避ける

 SVMの学習では、学習に用いた教師事例には高い精度で分類できてもその他の入力事例に対する分類の精度が大幅に低下している分類器ができてしまうことがあります。この現象は過学習と呼ばれ、分類器の実用性を高める上では避けるべき問題です。

 このような過学習を防ぐための手法としてリサンプリング法があります。リサンプリング法では、教師事例の一部だけを用いて分類器の学習を行い、その後に残りの事例を入力事例として分類を行い、その精度で評価します。どのリサンプリング手法にしても、教師事例と入力事例に同じ事例を用いないことがポイントです。勉強法の評価を行うときに、勉強に使う問題とテスト用の問題が同じだと勉強法に良し悪しに関わらずテスト問題にだいたい正解してしまうので、よりよい評価を行うためにはテスト用の問題は変えておくのと同じような原理です。

K-fold法

 リサンプリング法の1種であるK-fold法では、学習のために与えられた教師事例を近い大きさのK個の群に分割します。そのうちの(K−1)個を教師用の事例、1個をテスト用の事例とし、(K−1)個の群に含まれる教師用の事例で分類器の学習を行い、残されたテスト用の事例を未知の事例として分類器で分類します。そして実際の出力と分類器での出力とを比較し、精度評価を行います。すべての群がテスト用事例になるよう合計K回の学習・予測・精度評価を繰り返して、精度評価値の平均値をその分類器の精度とします。K個の群の分割の仕方次第で分類器の精度評価が大きく変動する可能性がありますが、評価値の平均を評価に採用することで変動差を平均化させることができ、より正確なモデルの精度評価を行うことができます。Kの値は大きいほうがよい精度評価が行えますが、大きくなるとその分時間がかかります。

 また、K-fold法は分類精度を最も高めるパラメータを見つける際にも使われます。例えば、RBFカーネルを用いたソフトマージンSVMではCostとγ(ガンマ)という2つのパラメータを設定しますが、最適なパラメータを探し出す際に、用意したCostの値(M個とする)とγの値(N個とする)のすべての組み合わせ計M*N組のパラメータ設定でSVMを実行し、K-fold法によって出た分類の精度が最も高いパラメータの組を採用する、という方法がよく用いられます。この方法は交差検定と呼ばれています。

 K-fold法は自分で実装してもよいですが、一応scikit-learnにも用意されています。
3.1. Cross-validation: evaluating estimator performance

精度評価

正解率、適合率、再現率、F値

 例えば、90%が負例である入力に対し全ての入力事例を負例に分類する分類器を使えば90%の正解率を示せますが、残る10%の正例を全く当てられないので、その分類器は実用的とは言えません。SVMの精度を正解率だけで評価していると、このような分類器を高く評価してしまう可能性があります。それを防ぐためにも、SVMの分類精度を評価する際の尺度として正解率(Accuracy)の他に、適合率(Precision)再現率(Recall)F値(F-measure)も使えるようになりましょう。

 分類器による予測結果を以下のように分けておきます。統計学の用語では、False Positiveは第一種過誤(α過誤)、False Negativeは第二種過誤(β過誤)とも言います。
class_matrix

 この内容を踏まえて、以下の式で計算します。
accuracy to f-measure
 「必要なメールが迷惑メールとして破棄されるのは非常にマズいから、フィルタは適合率で評価しよう」「正規ユーザを間違えてブロックしてでも不正アクセスユーザは絶対に止めなければならないから、再現率を高めよう」など、自分の行いたい分類の目的に応じて適切な評価尺度を選んで使えるようになりましょう。

課題

課題 1

SVMを語る際に用いられる以下の用語について簡潔に分かりやすく説明してください。
図を使っても構いません(むしろ積極的に使いましょう)。

  • マージン最大化
  • ソフトマージンSVM
  • カーネルトリック

わからない部分がある人は、下の参考文献を読んでみてください。

課題 2

好きなデータを用いてSVMを用いた分類を(まずはそのまま)実行してください。
次に、カーネル関数を使用したり、交差検定で最適なパラメータを設定したりして、分類の精度(F値)を高めてください。
分類の精度はどれくらい上がりましたか?

参考書籍

  • データマイニングの基礎
    ― 前処理から知識発見まで、データマイニング全体の流れがザッとつかめる。
  • 言語処理のための機械学習入門
    ― SVMなどの機械学習の仕組みがとても丁寧に記載されている。
  • データサイエンティスト養成読本
    ― Rやpythonで実際に手を動かして分析してみたい人向け。
  • 多変量解析入門
    ― SVMも記載されているがパラメトリックな統計手法がメイン。中級者向け。
  • 初めてのパターン認識
    ― 下の本を少し簡単にした本。SVMの変種の紹介もある。中級者向け。
  • パターン認識と機械学習
    ― 多くの大学院生が果敢に挑む機械学習の本。通称PRML。上級者向け。