Data Science by R and Python

統計学を、広く、深く、わかりやすく。

機械学習とは何か? - 自分なりに説明+具体例:サポートベクターマシン-

機械学習とは?

今日は、機械学習をテーマにしてブログを書いてみます。「機械学習」と言えば、Googleなわけですけど、最近Googleがワールドカップの勝敗予想を機械学習で行って「すげー!」っておそらく一部界隈では盛り上がりました。最近では一般にも「機械学習」という言葉は少しづつ普及しつつあるようです。Google Trendで見ても、右肩上がりです。

f:id:tomoshige_n:20140820230925p:plain

ただ、機械学習という言葉(Machine Learning)という言葉は情報分野で比較的昔からあるようです。アメリカの科学者はトム・M・ミッチェルはこんな定義を与えています。

コンピュータプログラムがある種のタスクTと評価尺度Pにおいて経験Eから学習するとは、タスクTにおけるその性能をPによって評価した際に、経験Eによってそれが改善されている場合である

簡単にいえば、あるタスクをこなして、それを「評価尺度P」で測ったときに、経験「E」(:データ)を与えると、評価尺度の点で改善しまっせという話です。なので、例えば「メールをスパム・スパムじゃない」と判別するタスクがある場合には、「正しく判別できた割合」を評価尺度Pとして、何もない状態でランダムにやらせるよりも、データを与えてそこから何らかの規則性を見つけ出させてタスクを処理する方が効果的だということです。

実際、こんな機械学習は「検索エンジン、医療診断、スパムメールの検出、金融市場の予測、DNA配列の分類、音声認識や文字認識などのパターン認識、ゲーム戦略、ロボット、など幅広い分野で用いられている」とWikipediaにあるように、たくさんの応用例が論文・レポート問わず報告されており、これからも適用分野は広がっていくと思います。

代表例:サポートベクターマシン

統計や機械学習を少しでも知っているビジネス関係の人と少しお話しすると「サポートベクターマシン使えますか?」と聞かれたりすることがあります。「使えますか?」がどのレベルをさすのか、聞かれるたびに(高度だったらどうしよう。。。と)不安にはなるのですが、「どんな問題を解きたいのですか?」と聞くと、「何かの判別をしたい」ということを言われます。例えば、1年後疾患にかかる可能性の予測や、得られているデータを2分する関数を得たいなど内容は色々です。今回は機械学習の1例として、サポートベクターマシンを説明します。

サポートベクターマシン(以下:SVM)とは?

サポートベクターマシンは、データ(x,y):xが説明変数、yが目的変数でグループを指す(1か2だとおもってください)が与えられたときに、yをもっとも良く分離するような「超平面」を探す方法です。図でみるとわかりやすいです。緑色の実践が、「超平面」その両側に緑色の点線がありますが、これが2つのグループをどれだけ分離するかという基準です。この分離する「幅」を最大にするように真ん中の直線を決めましょうということです。

f:id:tomoshige_n:20140820233057p:plain


ですが、単純に「超平面」を決めるだけの時代にはそれほど注目を集めませんでした。実際、SVMが発表されたのは1963年にVapnikが発表しましたが、そんなに注目を集めていません。それがこんなに注目されるようになったのは1992年にVapnikが発表した「再生核理論」に基づく「カーネル法」を用いた方法が生まれたからです。この方法は、特徴空間という空間にデータを射影して、その空間上で「超平面」を構成しましょうというアイデアです。

この方法は、きちんと勉強すると(僕も勉強中ですが)かなりややこしいなぁと思うのですが、簡単に言えばこれまで「平面」で切ってましたが、「曲面」で切る方法を考えたので非常に柔軟な対応ができるようになりましたがどうでしょう?ということです。こんな感じに。


f:id:tomoshige_n:20140820234534g:plain
URL : Support Vector Machine


※ちなみに、サポートベクターマシンをいじってるという意味ではこれが面白い。
2007-04-03 - Cry’s Diary


イメージはこちらで!

SVM with polynomial kernel visualization - YouTube


サポートベクターマシンを使うなら

ちなみに、サポートベクターマシンは、もちろん仕組みを知っておく必要はあるにせよ、Rがちょこっと使えればパッケージで利用可能です。いくつかありますし、有名なのはe1071ですが、今回はkernlabというライブラリを使ってやってみましょう。kernlabの中にはメールのスパム・スパムじゃないという判別をするためのサンプルデータがあります。実際のデータは以下のようになっています。メールの特徴が最初から57行目まで、最後の1行にspam, or notの情報が入っています。ちなみにspamメールは1813, notは2788あります。

> library(kernlab)
> data(spam)
> head(spam)
  make address  all num3d  our over remove internet order mail receive will people report
1 0.00    0.64 0.64     0 0.32 0.00   0.00     0.00  0.00 0.00    0.00 0.64   0.00   0.00
2 0.21    0.28 0.50     0 0.14 0.28   0.21     0.07  0.00 0.94    0.21 0.79   0.65   0.21
3 0.06    0.00 0.71     0 1.23 0.19   0.19     0.12  0.64 0.25    0.38 0.45   0.12   0.00
4 0.00    0.00 0.00     0 0.63 0.00   0.31     0.63  0.31 0.63    0.31 0.31   0.31   0.00
5 0.00    0.00 0.00     0 0.63 0.00   0.31     0.63  0.31 0.63    0.31 0.31   0.31   0.00
6 0.00    0.00 0.00     0 1.85 0.00   0.00     1.85  0.00 0.00    0.00 0.00   0.00   0.00
  addresses free business email  you credit your font num000 money hp hpl george num650 lab
1      0.00 0.32     0.00  1.29 1.93   0.00 0.96    0   0.00  0.00  0   0      0      0   0
2      0.14 0.14     0.07  0.28 3.47   0.00 1.59    0   0.43  0.43  0   0      0      0   0
3      1.75 0.06     0.06  1.03 1.36   0.32 0.51    0   1.16  0.06  0   0      0      0   0
4      0.00 0.31     0.00  0.00 3.18   0.00 0.31    0   0.00  0.00  0   0      0      0   0
5      0.00 0.31     0.00  0.00 3.18   0.00 0.31    0   0.00  0.00  0   0      0      0   0
6      0.00 0.00     0.00  0.00 0.00   0.00 0.00    0   0.00  0.00  0   0      0      0   0
  labs telnet num857 data num415 num85 technology num1999 parts pm direct cs meeting original
1    0      0      0    0      0     0          0    0.00     0  0   0.00  0       0     0.00
2    0      0      0    0      0     0          0    0.07     0  0   0.00  0       0     0.00
3    0      0      0    0      0     0          0    0.00     0  0   0.06  0       0     0.12
4    0      0      0    0      0     0          0    0.00     0  0   0.00  0       0     0.00
5    0      0      0    0      0     0          0    0.00     0  0   0.00  0       0     0.00
6    0      0      0    0      0     0          0    0.00     0  0   0.00  0       0     0.00
  project   re  edu table conference charSemicolon charRoundbracket charSquarebracket
1       0 0.00 0.00     0          0          0.00            0.000                 0
2       0 0.00 0.00     0          0          0.00            0.132                 0
3       0 0.06 0.06     0          0          0.01            0.143                 0
4       0 0.00 0.00     0          0          0.00            0.137                 0
5       0 0.00 0.00     0          0          0.00            0.135                 0
6       0 0.00 0.00     0          0          0.00            0.223                 0
  charExclamation charDollar charHash capitalAve capitalLong capitalTotal type
1           0.778      0.000    0.000      3.756          61          278 spam
2           0.372      0.180    0.048      5.114         101         1028 spam
3           0.276      0.184    0.010      9.821         485         2259 spam
4           0.137      0.000    0.000      3.537          40          191 spam
5           0.135      0.000    0.000      3.537          40          191 spam
6           0.000      0.000    0.000      3.000          15           54 spam

これをsvmを用いて分離するにはどうすればいいのかというとですね。コマンドは非常に簡単です。ksvmがサポートベクターマシンを使うためのコマンドです。ここでkはカーネルを意味していて、どんなカーネルを用いますか?ことを指定しなくてはいけません。今回は引数kernelにrbfdotというコマンドを用いてガウシアンカーネルを使っています。それから、一度のものだけでは意味がないのでクロスバリデーションしたい場合もコマンドを書いておきます。

> result = ksvm(type~.,data=spam,kernel="rbfdot",kpar=list(sigma=0.01))
> predict.svm = predict(result, spam[,-58])
> (error.rate = table(spam[,58], predict.svm))
         predict.svm
          nonspam spam
  nonspam    2690   98
  spam        168 1645
> 1-sum(diag(error.rate))/sum(error.rate)
[1] 0.05781352


#クロスバリデーションをする場合には
> ksvm(type~.,data=spam,kernel="rbfdot",kpar=list(sigma=0.05), C=5,cross=10)
Support Vector Machine object of class "ksvm" 

SV type: C-svc  (classification) 
 parameter : cost C = 5 

Gaussian Radial Basis kernel function. 
 Hyperparameter : sigma =  0.05 

Number of Support Vectors : 1547 

Objective Function Value : -2082.468 
Training error : 0.022169 
Cross validation error : 0.070633 

というように、案外コマンド一発でSVMは使うことができます。今日はこれぐらいにしましょう。本当はカーネルの理論側面も書いてみたいのですが、書くのがなかなかしんどいので。

まとめ

サポートベクターマシンは「意味」や「背景」を知って使うべきかもしれませんが、一方でコマンド一発で簡単に「分離する平面」をつくることができます。なので、ちょっと使ってみたいという場合には専門の人は必要なく、さくっと使えます。Pythonにもライブラリはありますし、他にもあるんじゃないでしょうか?ただ、実際にアルゴリズムを実装するとなるとなかなか難しい気がしますが(笑。

では。