今日会社で多次元のデータを2次元にクールでベストプラクティスな感じでプロットするにはどうしたらいいんだろうね、やっぱ多次元尺度構成法じゃない?的な会話をしていたのだけれども、2次元にデータを落とし込むと人間にもわかるデータになって本当におもしろいですよね。今日はその一例というか、いくつかの分類器の分類精度を2次元に
プロットした結果を示した実験結果を解説したページを紹介します。おおーこうゆうのみたかったんだよなー!と個人的にはかなりエキサイティングな感じでした。

要約というか意訳になってしまうのですが、ページに以下のように説明されています。(細かいところは訳してません)

http://home.comcast.net/~tom.fawcett/public_html/ML-gallery/pages/index.html

分類タスクの機械学習の研究では定量的な評価が重要です(精度とかACUとかね。)、で、これは分類器のアルゴリズムの振る舞いの「見える化(最近はやってますよね)」にも役立つ訳ですね。

このページでは「機械学習の分類器ギャラリー」と題して、2次元における機械学習アルゴリズムの多数の実験結果を説明します。以下に示した列ではそれぞれ違ったパターン(またはパターンセット)を示しています。使用しているデータは2次元上にランダムに
生成したポイントでX軸は0から4、Y軸は0から4の幅で、6561個のデータで構成されています。

図の右側にはアルゴリズムの種類が書いてあります。アルゴリズムの名前のところはリンクになっていて、サンプルデータが50から1000の間での分類した結果を示してあります。

このページで使用している図はgnuplotを使っていて、学習器はwekaを使っています。glue code(コーパスを作成したりするスクリプトのこと)はperlとpythonを使っています。

データセット

個人的に興味深かったものを紹介。

  • DISJUNCTIVE
  • 上記のページにDISJUNCTIVEというデータセットでの実験結果が示されています。とても分類が難しそうなデータですね!まさにSVMの出番って感じのデータセットですよね!

    1253333934-dataset

    Bayes

    bayesの各種分類器を使って分類した結果です。本当に名前通りの性格が分類結果に出ていますね、Naive! NBTreeというのはNaive Bayes + decision treeのアルゴリズムでの分類結果らしいのですが、これは比較的良さそうですね。重そうですけどね。

    1253333946-bayes

    大きい図はこちら

    SVM

    そこで、SVMですよ。カーネルトリックですよ。マージン最大化ですよ。って、あれあれあれ?あんまりよくなさそうですね。SVMRBF-100というのは、radial basis functionを使ったもので、これは結構良さそうなんですけど。SVMpoly-xというのは多項式カーネルを用いたものらしいのですが、全然だめですね!まったくうまくいってないですね!たぶん僕の個人的な予想なんです
    が、このデータのサンプル数が1000個ってうのが少なすぎる可能性があるか、うーん2次元データなのが問題なのかな。。。わからないけど、なんか特徴出ていますね。

    1253333959-svm

    大きい図はこちら

    decision tree

    なぜ、ここで決定木を例に出すの?と思われる方もいるかもしれませんが、それは僕が決定木が大好きだからです。決定木は一般的にはそんなに分類
    精度も良くないし、スピードも遅いともいわれていますが、なんといっても木を生成してくれるので人間にわかりやすいし、データマイニングに有用だから、僕は好きなのですね。なんといっても「なんでこうゆう分類結果になったの?」という非分類マニアな方
    にビジュアル的に説明できるのはとても便利。百聞は一見にしかずで、こうゆう理由で分類されたんですよ!と木を見せれば一言で説明がつく。情報利得がうんちゃらとかそういう話はしなくていいですけどね。ややこしくなるし。ちなみにSVMでの説明は地獄。

    1253333967-tree

    大きい図はこちら

    結構決定木もがんばっているではないですか!!特にRandom Forestは健闘していますね。これだけきれいに分離できるならば、やっぱりtreeも有用だなあと
    思う反面、おそらくこれはサンプルデータが少ないからだろうなあとも思う。このまま1000, 5000, 10000, 50000って続けていったらそれはそれで各分類器の特徴が如実に現れてくることだと思います。

    まとめる

    ユースケースにあわせて分類器を選択することはとても大事だと思います。

    • サンプル数の規模はどれぐらいか
    • 分類するクラスは何種類か
    • 分類に要求されるスピード
    • 学習に要求されるスピード(リアルタイムで更新してほしいならば、オンライン学習)
    • 分類結果を使う人は、専門家か、それとも非専門家か(上記で説明したように、分類結果の説明が大変)
    • メンテナンスできる人がどれほどいるか(あまりメンテナンスできる人がいない場合はnaive bayesなどの単純なアルゴリズムを選択した方が良い)

    などなど、仕事で分類器を使う場合は様々な分類器を検討しなければなりません。そのためにはそれぞれの分類器アルゴリズムの特徴を見極めていなければならないし、実験した経験も必要となります。どの分類器が一番いい!というのは無くて、それぞれいいと
    ころと悪いところがあります。このページは、そのような知識を手助けてしくれる大変有用なページだと思いました。

    エンジョイ ユア 分類ライフ
    今日から大型連休。


    勉強する時間があまりとれていないのでコネタが続いています。というよりも僕のブログのスタンスは基本的に有用なものメモするだけ、気軽にやる!って感じなのでこれで良いと思っています。時間ができたときに時々本気のエントリー!
    みたいな。あるのかな、そんなこと。

    前置きが長くなりましたが、今日は人工知能の教科書についてです。人工知能の授業でよく使われる教科書で最も有名なものの一つに「エージェントアプローチ人工知能」というものがあります。


    17800円とばか高いのですが、すごく網羅的に解説してあって僕は好きです。大学院時代の人工知能の授業はこの教科書でした。

    それで、たいしたことではないのですが、上記の教科書で解説しているアルゴリズムをpythonでひたすら実装しているプロジェクトがgoogle codeにあったので紹介しておきます。

    http://code.google.com/p/aima-python/
    上記のプログラムを熟読した訳ではないのですが、エージェントアプローチ人工知能を読むときにはすごく理解の手助けになるかと思います。

    またいつか人工知能全般も復習しないとならない時がくると思うで(だいぶ忘れている。。。)その時には利用してみようかと思います。


    身内の不幸などでどたばたしてしまい、ブログの更新ができていないのです。ということで、今日もどたばたなので小ネタで軽く更新しておきます。

    情報検索の教科書で有名なIntroduction to Information Retrieval(略してIIR)は、


    情報検索の基礎から、有名な機械学習のアルゴリズムまで幅広く解説されてあり、いろいろ忘れるたびにお世話になっています。どうお世話になっているかというと、これは結構有名な話なのですが、上記の本が実はPDFで公開されているんですね。すてき。

    http://www-csli.stanford.edu/~hinrich/information-retrieval-book.html
    これは、本当によく使う手法がわかりやすく書かれているのでおすすめです。

    で、今回紹介したいのは、これまた機械学習の教科書として有名な本で、Introduction to Machine Learningという本があるんですね。

    まだ、すべては読破はしていないんですが、僕がいた研究室にもあって時々ちらちら読んでいたんです。これは、タイトルの通り機械学習の教科書なので、IIRのようにさくっと情報検索に使えるといったようには解説されていません。しかし、機械学習をちゃんと勉強するには網羅的に説明されているので、個人的はとても良い本だと思っています。

    で、実はこれも授業用のスライドがPDF形式とPPT形式で公開されているんですね!

    http://www.cmpe.boun.edu.tr/~ethem/i2ml/

    上記のリンクの先のページの一番下の方に、

    Lecture Slides: The following lecture slides (pdf and ppt) are made available for instructors using the book.
    
        * Chapter 1. Introduction (ppt)
        * Chapter 2. Supervised Learning (ppt)
        * Chapter 3. Bayesian Decision Theory (ppt)
        * Chapter 4. Parametric Methods (ppt)
        * Chapter 5. Multivariate Methods (ppt)
        * Chapter 6. Dimensionality Reduction (ppt)
        * Chapter 7. Clustering (ppt)
        * Chapter 8. Nonparametric Methods (ppt)
        * Chapter 9. Decision Trees (ppt)
        * Chapter 10. Linear Discrimination (ppt)
        * Chapter 11. Multilayer Perceptrons (ppt)
        * Chapter 12. Local Models (ppt)
        * Chapter 13. Hidden Markov Models (ppt)
        * Chapter 14. Assessing and Comparing Classification Algorithms (ppt)
        * Chapter 15. Combining Multiple Learners (ppt)
        * Chapter 16. Reinforcement Learning (ppt)
    

    というところがあるので、ちょろっとみてください。数式ばっかりで難しそうですね!でも、すでに理解されている方だったら忘れたときとかに参照するにはとても良いと思います。また、勉強会で説明しないといけない時とかに参考すると良いと思います。

    また、上記のページにはこの本を教科書として機械学習のレクチャーをしている、世界中の大学のページにもリンクされていて、そこにも各々のレクチャー用のスライドがあったりして、いろんな角度からみれておもしろいです。この際に私ももう一度この教科書
    を読み直してみようと思います。

    amazonでIntroduction Machine Learningを探していたら、なんと2010年にセカンドエディションが出るんですね!要チェックですね!
    http://www.amazon.co.jp/Introduction-Machine-Learning-Adaptive-Computation/dp/026201243X/ref=sr_1_1?ie=UTF8&s=english-books&qid=1252901537&sr=1-1


    ハイクオリティの最新の機械学習の論文って入手するのが大変ですよね。僕はよくACM系のちょっと前の論文をあさったりするのですが、やっぱり最新の機械学習ライフをエンジョイするには最新の論文が読みたいですよね。そんな、サイトがありました!ってこれってもしかして常識?

    Journal of Machine Learning Research

    これはすごい。最新の機械学習に関する論文が読めまくります。こんなポータルが欲しかったんです。RSS機能もあるようですし、ちょくちょく目を向けたいと思います。おもしろい論文があったら紹介したいですね。


    すごい、有名なアルゴリズムのサンプルプログラムがたくさんあります!

    http://www.yom-tov.info/Uploads/

    #  Parent Directory
    # Ada_Boost.m
    # Bottom_Up_Parsing.m# C4_5.m
    # DHSchapter2_fixed.mat
    # Grammatical_Inference.m
    # Marginalization.m
    # PPT.m
    # SVM.m
    # Sequential_Feature_Selection.m
    # calculate_region.m
    

    だけどmatlabわからない。。。
    いつか解読してみせる。


    突然なのですが、よく分類器などを実装して、その精度をチェックするためにコーパスが必要になることってよくありますよね。
    そこで、よく論文などで評価で使われているデータセットを使おうと考える訳ですが、そうゆう時に限ってデータセットの名前が出てこなかったりします。
    あと、いつも同じデータセットだとあんまり面白みもかけてきちゃったりして、よーし自分で作っちゃおうぞー!ってなってがんばってクローラーを書いたりして、ウェブコーパスを作ったりしようとするんですが、だいたい途中で飽きちゃったりするんですよね。

    さて、前置きが長くなりましたが、machine learningの評価で使われるデータセットがまとめてあるページを見つけたので紹介させていただきます。

    UCI Machine Learning Repository: Data Sets

    ぱぱーっと見た感じで、すごい色々な種類があってぜひ色々試してみたいですね。ダウンロードもできるみたいだし、さくっと使えそうです。
    今日は寝る時間なので試せないですが、今度時間があるときにいくつか実際に試したレポートを書きたいと思います!その日まで待っていてください。


    Algorithms of the Intelligent Webという情報検索の本がございまして、ずっと読みたいなあと思っていたら、本の内容のサンプルがありました。

    http://www.manning.com/marmanis/SampleChapter2.pdf

    これが、実はサンプルってレベルではなくて2章と3章がまるごとPDFで公開されているんですね。それで軽く読んでみたんですが、すごいわかりやすくて、普通に読み物としておもしろかったのでメモっておきます。

    上記のリンクは2章で「searching」という題で、つまり検索エンジンの話がまとめてあります。

    さらっと全部読んだんですけど、大雑把に感想を述べるとかなり基礎的な内容ですが、本当にわかりやすく解説してあるので、例えば、あまりこの分野に詳しくない人に説明する時や、自分でさらっと検索エンジンの要素を整理したい時とかには超便利だと思いま
    す。
    全体的な流れとしては

    • Luceneを使って検索エンジンの実装の仕方を説明
    • PageRankの説明
      • PageRankとindexのスコアリングの組あせ方の説明
    • Naive Bayesを使った分類の説明
    • Word document, PDFなどHTML以外の文書のスコアリング
    • Precision Recallなどの評価方法の話

    といった感じ。上記以外にもクエリ拡張や、クリックログの話など、検索エンジンで必要とする要素技術の話が幅広く、優しく説明してあります。なんで、これが初心者にいいかって、これらはLuceneに実装してあるんですね。だから、使いながら勉強できるので
    身に付きやすいと思うし、Luceneのコードの説明までしているのがすごい。僕はJavaは書かないのですが、コードに書いてあるコメントがわかりやすくてとてもよくわかりました。Luceneは実装が奇麗って話を聞いていたのですが、その再確認もなったなあ。図も
    豊富。情報検索とインデキシングのスコアリングに興味がある人はぜひ一読をお勧めします。


    普段僕はプログラムを書くことが多いのですが,

    use strict;
    use warnings;
    

    を頭に書くのは当然として,それでもちゃんとできているか心配になることが多々あります.

    そこで,というプログラムでperlのプログラムを厳密にチェックできるということなので,最近これを使っています.perlではB::Lintというのがあります.

    詳しくはB::ListのPODを読むとして,とりあえず使い方としては以下のように使います.

    perl -MO=Lint,all program.pl
    

    allというキーワードはLintにあるチェック機構をすべて適用します.つまり厳しくwarningsを吐き出すようにしています.結構,-w だけでは気づかなかったwarningsを吐き出してくれるの重宝しています.


    すごくいまさらなんですが.
    もう1年以上も前になるかな,GoogleのC++のスタイルガイドというのが公開されて,なかなか読む暇が無くてずっとあとで読む上体だったんだけど,昨日ちらっと読んでみたらなかなかおもしろくて寝不足なのです.

    いくつか個人的におもしろかったところをピックアップするというか,忘れないためにメモっておこうと思う.

    ちなみに参照したサイトは以下です.
    Google C++スタイルガイド 日本語訳

    インライン関数
    
    インライン関数を定義するのは関数が小さいときのみ(10行以下)にする。
    

    個人的にはinline関数はほとんど使わないから,このキモチがよくわからないんだよなあ.inlineにしなくてもコンパイラが結構最適化してくれることが多くて,経験上ほとんどスピードが変わらないということが多い.inlineがどういうときにもっとも有効なの
    かって,まだ僕には結論を言うほどC++に詳しくないのだけれども,この件に関しては賛否両論ありそうだよなあ.僕は依然inlineは相当最適化しなけばならない時以外考えません.

    コンストラクタでやるべきこと
    
    コンストラクタでやることは簡単な初期化だけにする。もし簡単でなければ、できる限り Init() メソッドを使うこと。
    
    定義:  コンストラクタ本体で初期化をすることができる。
    
    賛成: 入力に好都合。クラスが初期化されているかどうかを気にする必要がなくなる。
    
    反対: コンストラクタで初期化をするのには、いくつか問題がある。
    
        * 例外以外にコンストラクタがエラーになったことを知る簡単な方法がない(外を使うことは禁止されている)。
        * もし処理に失敗すると、初期化が完了していないオブジェクトが得られてしまう。このオブジェクトは不定状態になるおそれがある。
        * もしコンストラクタで仮想関数を呼び出していると、この呼び出しはサブクラス実装に対してディスパッチされない。 たとえ今のところはサブクラス化されていなくても、後になってサブクラス化したときにこの問題が入り込んでしまい、大きな問題になるおそれがある。
        * 誰かがクラス型のグローバル変数を作ってしまうと(これはルールに反しているが、それでも作ってしまった場合)、コンストラクタのコードは main() 関数よりも前に呼び出されることになる。おそらくこれは、コンストラクタのコードにとっては想定外
    のことだろう。 例えば gflags はまだ初期化されていない。
    
    結論: オブジェクトの初期化が簡単なものでなければ、明示的な Init() メソッドを用意したり、オブジェクトの初期化が成功したかどうかを示すフラグをメンバに追加するなどを検討すること。 
    

    これはいつも悩むところ.反対派の意見にも出ているのだけれど,コンストラクタではboolを返すことができない.だから,ちょっとでも込み入ったことをするとエラーが発生する可能性があって,かつそれを検知することができない.これは正直C++のいけてないところだと思っている.僕は,結論に書いてあるように,基本的にはエラーハンドラをコンストラクタにも持たせるようにしている.複雑ならばInit()関数に任せるというのも同意だし,そうしている.基本的にはコンストラクタでやらせるのは変数の初期化のみ
    ですね.

    明示的なコンストラクタ
    ▽ 引数が1つのコンストラクタには、C++の explicit キーワードを付ける。
    

    れは単純にやってなかったらこれからはやるようにしよう...

    宣言の順序
    ▽ クラスにおける宣言は、次に指定した順序にする。public: は private: の前に置く、メソッドはデータメンバ(変数)の前に置くなど。
    link
    
    クラスの定義は public: セクションから始めて、protected: セクション、private: セクションという順にするべきだ。セクションが空であれば省略する。
    
    各セクション内では通常、次の順序で宣言するべきだ。
    
        * typedef と enum
        * 定数
        * コンストラクタ
        * デストラクタ
        * メソッド。スタティックメソッドも含む
        * データメンバ。スタティックデータメンバも含む
    

    気をつけないといけないのだけど,いつも手を抜いて一貫性がとれていなかった.特にこれ,という決まりはないのだけど,この際この順番で統一させるようにしようと思う.

    例外
    ▽ C++の例外を使わない。
    

    同意.例外だとエラーがトレースできない場合はある.独自にエラーハンドラを書いたほうが確実だと思う.

    Boost
    ▽ Boostライブラリ群のうち許可されているライブラリだけを使う。
    

    同意.確かにBoostは便利だし,すごく使いたくなるんだけど,移植性を考えると使わないほうが良いと思っている.個人的には公開したプログラムではBoostを使ったものは無い.ただし,googleでは以下のライブラリは許可しているらしい.要調査.

        *    Compressed Pair(boost/compressed_pair.hpp)
        * Pointer Container(boost/ptr_container)ただしシリアライゼーションを除く。
        * Array(boost/array.hpp)
        * Boost Graph Library(BGL)(boost/graph)ただしシリアライゼーションを除く。
        * Property Map(boost/property_map.hpp)
        * Iterator の一部。次のイテレータの定義に対応するもの。 boost/iterator/iterator_adaptor.hpp、 boost/iterator/iterator_facade.hpp、 boost/function_output_iterator.hpp
    私たちはこの他のBoost機能をリストに追加することを積極的に検討している。そのため、このルールは将来緩和されるかもしれない。 
    
    型名
    ▽ 型名は大文字で始めて、単語の頭文字を大文字にする。アンダースコアは使わない。MyExcitingClass、MyExcitingEnumなどとする。
    link
    
    あらゆる型、— クラス、構造体、typedef、enum — の名前には同じ命名規約を使う。型名は大文字で始めて、単語の先頭を大文字にするべきだ。アンダースコアは使わない。例: 
    

    大文字で初めてキャメルケースでということですね.同意.

    変数名
    ▽ 変数名はすべて小文字にして、単語と単語の間にはアンダースコアを入れる。クラスメンバ変数はアンダースコアで終わるようにする。例えば、my_exciting_local_variable、my_exciting_member_variable_。
    link
    
    よく使う変数名
    
    例:
    
    string table_name;  // OK - アンダースコアを使っている。
    string tablename;   // OK - すべて小文字だ。
    
    string tableName;   // よくない - 大文字小文字が混ざっている。
    

    僕は変数名もキャメルケースで書いてたんだけど,確かに見分けをつけるにはアンダースコアにしたほうがいいかも.今後取り入れよう.

    定数名
    ▽ kで始まり、大文字小文字で続ける。kDaysInAWeek
    link
    
    コンパイル時定数は、それがローカルであろうとグローバルであろうと、クラスの一部としてであろうと、どう宣言されていても、他の変数とは全然違う命名規約に従うこと。k の後に単語の先頭を大文字にして続けること。
    
    const int kDaysInAWeek = 7;
    

    C風に全部大文字のほうがわかりやすい気がする.目立つし.

    うーん,なかなかおもしろい.結構自分は一過性を持って書いていると思っていても実は一貫性が取れていない部分が結構多い.オープンソースで開発する場合は他人に読んでもらうことが多いから一貫性に関しては特に気をはらわなければならないし,はらって
    いるつもりなのだけれども.


    おかしくなったというのは冗談で。というか語弊があって。
    実は今日macにsnow leopardを入れたんですね。そんで、ちょっと調子に乗ってplaggerとかでぷらぷらしようと思ったんです。そこでいつもようにcpanコマンドで依存性と悪戦苦闘しようと思ったんですわ。そしたらびっくりcpanコマンドでモジュールを入れよう
    とすると全部エラーなんですね。makeとかずっこけまくりで一つもモジュールが入れられないんですわ。どんなOSでもステーブルしか使わない主義だったのに主義を曲げたから罰が当たったのかなあなんて思いながらも悪戦苦闘していたんですわ。

    そんで色々google先生とぐるぐるぐぐると情報を探していたらどうやらsnow leopardでは、perlのヴァージョンが5.1.0らしいんですね。そこでヴァージョンをチェックしてみたんです。

    macbook:~ shunya$ perl --version
    
    This is perl, v5.8.8 built for darwin-2level
    
    Copyright 1987-2006, Larry Wall
    
    Perl may be copied only under the terms of either the Artistic License or the
    GNU General Public License, which may be found in the Perl 5 source kit.
    
    Complete documentation for Perl, including FAQ lists, should be found on
    this system using "man perl" or "perldoc perl".  If you have access to the
    Internet, point your browser at http://www.perl.org/, the Perl Home Page.
    
    

    あれ!全然違うではありませんか。ヴァージョンは確かに5.8.8と示しておりますぜ、旦那。よくわからなくて、perlコマンドのありかを探してみた。

    macbook:~ shunya$ which perl
    /opt/local/bin/perl
    

    むむ。なんか怪しいよ。当方macを使ってまだ2年ぐらいであまり詳しくないんですが。optってなんぞ!僕が普段使っているlinuxマシンでは/usr/bin/perlを使ってるんだよ!ってことで/usr/bin/perlのヴァージョンをチェックしてみた。

    macbook:~ shunya$ /usr/bin/perl --version
    
    This is perl, v5.10.0 built for darwin-thread-multi-2level
    (with 2 registered patches, see perl -V for more detail)
    
    Copyright 1987-2007, Larry Wall
    
    Perl may be copied only under the terms of either the Artistic License or the
    GNU General Public License, which may be found in the Perl 5 source kit.
    
    Complete documentation for Perl, including FAQ lists, should be found on
    this system using "man perl" or "perldoc perl".  If you have access to the
    Internet, point your browser at http://www.perl.org/, the Perl Home Page.
    
    

    ktkr。実行しているperlコマンドは古かったというわけですね。ということで、5.1.0のperlでcpanを起動したらちゃんとmakeがとおるようになったし、無事plaggerでらぷらぷできるようになりました。

    それでついでなので、macportも動かなかったのですね。もうね、絶望しかけたし、正直アップグレードしなければ良かった。って思ったんだけど、macportのサイト行ったら普通にsnow leopard版のmacportがリリースされていて無事に動きました。安心した!