読者です 読者をやめる 読者になる 読者になる

learning.ikeay.net

文系エンジニア、AI勉強中。

機械学習の種類: 教師あり学習編

AI 人工知能

こんにちは、@ikeayです。

機械学習にもいろいろなモデル(アルゴリズム)があります。これらのモデルは優劣だけではなく、得意分野・不得意分野があったりするので、解きたい問題に応じて最適なものを選びます。

f:id:ikeay:20160502153857p:plain
scikit-learnより

どういう時にどういうモデルを使えばいいか、scikit-learnが用意しているチャートを参考にすると分かりやすいですね。

機械学習はまずは大きく、「教師あり学習」「教師なし学習」「強化学習」に分けられます。ざっくり説明すると、「教師あり学習」は問題と答えがセットになって学習する方法、「教師なし学習」は正解不正解のデータが入っていないので、クラスタリングや外れ値検出で傾向をつかむ学習方法、「強化学習」はいいことをしたら報酬を与えていく学習方法です。以下の記事にざっくりとまとめてあります。

learning.ikeay.net

今回はその中でも教師あり学習のモデルにフォーカスしてみたいと思います。

事前準備

今回はscikit-learnを使った各モデルのプログラムも書いていきたいと思うので、事前に分析するデータを準備しておきましょう!
事前準備として、データセットをインポートしたり、そのデータを学習しやすいかたちに整える必要があります。

まずは、scikit-learn上でテスト用に用意されているデータ(irisといわれるあやめの花のデータ)をインポートして、そのインポートしたデータを学習用データとテスト用データに分割します。

from sklearn import datasets
from sklearn import cross_validation
iris = datasets.load_iris()
train_X, test_X, train_y, test_y = cross_validation.train_test_split(iris.data, iris.target, test_size=0.3, random_state=0)

次にデータを標準化します。だいたいデータというものは、カラムごとに値の幅にバラつきがあるので、そのバラつきを抑えていきます!
(平均0、分散1になるようにします)

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(train_X)
train_X = sc.transform(train_X)
test_X = sc.transform(test_X)

こうすることで、こんなデータを

[[ 5. 2. 3.5 1. ] [ 6.5 3. 5.5 1.8] [ 6.7 3.3 5.7 2.5] [ 6. 2.2 5. 1.5]...

こんなデータにすることができます。

[[-1.02366372 -2.37846268 -0.18295039 -0.29145882] [ 0.69517462 -0.10190314 0.93066067 0.73721938] [ 0.92435306 0.58106472 1.04202177 1.6373128 ] [ 0.1222285 -1.92315077 0.6522579 0.35146505]...

下準備完了です!

決定木

まずは決定木というモデルについて触れていきます。
決定木はツリー構造になっている人間にも非常にわかりやすいモデルです!
Yes、No、Yes、Noというかんじでたどっていくかんじ。

f:id:ikeay:20160713102222p:plain
決定木 - Wikipediaより

いいところ
  • ツリー構造になっているので、人間にとって意味がわかりやすいモデル!
  • 決定木の派生モデルで、大量の決定木を作成して、それぞれの決定木が導いた答えから多数決するモデル「RandomForest」も優秀なモデルとして有名。(Kinectの身体部位推定に採用されていたりします)
わるいところ
  • 過学習しやすい。
  • 難しいデータは苦手。
  • X軸やY軸などの軸と平行にざっくざっく切り分けることしか出来ない。

コードにするとこんなかんじ

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
clf = DecisionTreeClassifier()
clf.fit(train_X,train_y)
pred_y = clf.predict(test_X)
accuracy_score(test_y, pred_y)

出力!

0.97777777777777775

accuracy_scoreメソッドは正解率を出してくれます。
決定木でも約97.7%と、けっこういいスコア出ますね!

図を出力してみるとこうなりました。

f:id:ikeay:20160713101916p:plain

パーセプトロン

人のニューロンをモデル化したモデルです。これがいま活躍しているモデルたちのだいたい元祖となっています!ディープラーニングもそうです。

f:id:ikeay:20160713102444p:plain
高卒でもわかる機械学習 (2) 単純パーセプトロン | 頭の中に思い浮かべた時にはより

いいところ
  • モデルがシンプルでわかりやすい。
  • 元祖!!
わるいところ
  • まっすぐ線でしか情報を切り分けれません!!(これを「線形分離」と呼びます)
  • 第一次ブームの立役者でありながら、「線形分離しかできないじゃん!精度悪いじゃん!!」と言われて研究費をがっつり引かれてしまうことになるのであった…
from sklearn.linear_model import Perceptron
from sklearn.metrics import accuracy_score
clf = Perceptron(n_iter=100, eta0=0.1)
clf.fit(train_X, train_y)
pred_y = clf.predict(test_X)
accuracy_score(test_y, pred_y)

こちらも97.7%ほど。

0.97777777777777775

f:id:ikeay:20160713102618p:plain

ロジスティック回帰

ディープラーニングの一層版。ディープラーニングはこのモデルの多層版と考えると分かりやすいかも。

f:id:ikeay:20160719135813p:plain
https://inst.eecs.berkeley.edu/~cs194-26/fa15/upload/files/projFinalUndergrad/cs194-au/より

いいところ
  • どのくらい確信をもてるのか、確信度が分かる(上のグラフでいうとグラデーションの色が濃いところほど確信度が高い)
  • 学習が簡単
わるいところ
  • 通常は線形分離不可能
  • SVMよりは精度低いかも
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
clf = LogisticRegression()
clf.fit(train_X, train_y)
pred_y = clf.predict(test_X)
accuracy_score(test_y,pred_y)

あれれ

0.82222222222222219

82.2%。だいぶ落ちたなあ。データセットとの相性が良くないのかも。

f:id:ikeay:20160713102903p:plain

SVM

区切り(識別超平面)とデータの距離を最大となるようにするモデル。超平面の近くにあるデータ(サポートベクトル)だけをみてどこで区切るかを決めているので、計算量が少なくてすむ。

f:id:ikeay:20160713103901p:plain
OpenCVで遊ぼう!: 年賀はがき当たりチェックアプリとSVMより

いいところ
わるいところ
  • 学習にちょっと時間がかかる
  • 通常はバッチ学習。データを1回で全部学習してしまおうとするので、データ量が多いと学習時間が苦しくなります。
  • 通常は線形分離しかできない…!ただし、カーネルトリックと呼ばれる魔法を使うと非線形にもできたり、パラメーターをなんやかんや調整すると、かなり優秀なモデルになります!scikit-learnではデフォルトで非線形になっている模様。
from sklearn.svm import SVC
clf = SVC()
clf.fit(train_X, train_y)
pred_y = clf.predict(test_X)
accuracy_score(test_y,pred_y)

97.7%ほど。最強なはずなのにこのデータセットだと差が出ませんねw ちなみに上記のプログラムはデフォルト値になってますが、パラメータサーチでパラメーター調整をしても、今回は値は変わりませんでした。

0.97777777777777775

scikit-learnではデフォルトで非線形モデルが採用されています。 ここではカーネルトリックという次元の呪いを解決できる魔法を使っています。これもSVMが最強だといわれる所以のひとつ。

f:id:ikeay:20160713103136p:plain

まとめ

まだまだいろいろなモデルが存在しますが、代表的なモデルについてとりあげてみました。
たとえ決定木のように直線にしか切れなくても一概にダメなアルゴリズムとは言えません。その分、計算がめちゃめちゃ早くて優秀だったりします。
初心者の場合、まずはいろいろなモデルを試して、精度と速度を吟味して決めましょう!


Special Thanks: 松尾研 鈴木さん、PARTY 宮本さん