2011年4月26日火曜日

漠然とした不安とmilkモジュール

皆様おはようございます.
今朝の滝沢村は,雨だれの音が音がこだましていて
どんよりとした雲が低く垂れこんでおります.

地震から日が経つに連れ余震の頻度は落ちてきた
はずなのに,正直なところ気持ちは落ち込む一方です.
なにか悪いことが起こるのではないかという,
なんともいえない気持ち悪さが心から離れません.
そんなことは無いさと思ってみても,気を緩める頃には
決まって地震に大地が震え,私は再び悪い予感に
とらわれるという循環になっています.

自分の心に素直に向き合い,本能の声に耳を傾けるならば
「これだけでは済まされない,もう一つ何かが起こるよ」
というささやきが聞こえてくるようです.
その声を無視して日常をやり過ごせばよいのか,それとも
理屈では説明のつかない悪い予感に従えばいいのか,
まだ割り切れずにいながら,時間が過ぎていきます.

ところで,ここまでの話と全く脈略がありませんが,
ここからガラリと話題を変えまして...

先日,少し知的な処理をコンピュータにやらせたいと思いまして,
pythonの機械学習モジュールについて調べてみる機会がありました.
そのとき見つけた「milk」というモジュールについてメモを披露したいと思います.

「milk」は名前の印象とは関係なくって複数の機械学習
アルゴリズムを集めたpythonパッケージのようです.
SVMやboostingなどをお手軽に使えるところが気に入りました.
複数のアルゴリズムを組み合わせて使うことも考慮されています.
残念なことに,milkのドキュメントは2つくらいしか見つかりません.
pypiluispedroです.
インストールは「easy_install milk」でいけました.

使い方ですが,サンプルを引用します.
import numpy as np
import milk
features = np.random.rand(100,10)
labels = np.zeros(100)
features[50:] += .5
labels[50:] = 1
learner = milk.defaultclassifier()
model = learner.train(features, labels)
example = np.random.rand(10)
print model.apply(example)
example2 = np.random.rand(10)
example2 += .5
print model.apply(example2)

milk.defaultclassifier()は,お手軽に使えるように
あらかじめデフォルト設定された学習機となっていて
SVM=Support Vector Machineを使った学習となっています.
教師信号として入力する特徴量(features)と対応するクラスタラベル(label)を
入力してやります.
特徴量の正規化や線形従属な要素の除去なども全自動でやってくれます.
defaultclassifier()では複数のクラスタに分類するためにone-versus-rest手法が
用いられるようになっています.
もちろんこれらの組み合わせを自分で自由に設定することも可能です.
defaultclassifier()の中身は,次のようになっているようです.
defaultclassifier = ctransforms(
   chkfinite(),
   interval_normalise(),
   featureselector(linear_independent_features),
   sda_filter(),
   gridsearch(one_against_one(svm.svm_to_binary(svm.svm_raw())),
   params={
     'C': 2.**np.arange(-9,5),
     'kernel': [svm.rbf_kernel(2.**i) for i in np.arange(-7,4)],
   }
))
ctransforms()というのが複数のフィルタ(学習器)を束ねてくれるmilkのAPIです.
そのなかで1つづつ与えられている引数の要素がそれぞれ別個の学習機や
フィルタとなっています.
・chkfiite()は,特徴量やラベルに無限やNaNなどが含まれていないかチェックするフィルタ.
・interval_normalise()は,特徴量を正規化するフィルタ.
・sda_filter()は,判別分析を行うフィルタ.
・gridsearch()は,多値問題をグリッド検索に基づいて与えられた学習器で学習するフィルタ.
・svm.rbf_kernel()は,Support Vector Machineのradial basis function kernel.

milkのフィルタ(学習器)は,皆 learn_func(features, label)のような引数を持つように
設計されていて,ctransforms()で束ねて与えると,パイプライン処理により1つの
学習機として動作するようになっているようです.

冒頭のサンプルコードに戻りますが,学習器のインスタンスを生成した後,
「train」で特徴量とラベルを与えて学習させます.
learner = milk.defaultclassifier()
model = learner.train(features, labels)
処理には数秒を要します.学習が終わると学習モデルが得られますので,
未知の特徴量を与えれば,学習結果に基づいて分類してくれます.
print model.apply(example)
学習モデルは,pickle化できるのでディスクから読み込むことも可能です.

OpenCVと組み合わせたり,あるいはネットから集めたデータを
自動分類したい時など,お手軽に使えるのではないでしょうか.