pHomパッケージでドーナッツの穴を数えてみた

CRANに登録されているpersistent homologyを計算できるpHomパッケージで3次元トーラスの穴を数えてみました。

ソースはこちら

データ生成

まず与える人工データの生成ですが、極座標表示したときの回転パラメータ2つでそれぞれ20間隔にして20x20の400点作り、ドーナッツの直径が50に対して標準偏差1のガウスノイズを各点ごとに独立に乗っけてみました。下で呼ぶpHom関数はデフォルトでは1000以上の点がある場合は1000だけ適当にピックアップして動作するようです。なので400なら特に何も言わなくても全部を考慮してくれる。

実行結果

pHomパッケージに与えるのはフィルトレーション(点たちを見るときの解像度)の最大値と、調べたいホモロジーの次元の最大値で、それぞれ5, 2としています。トーラスにおいては、0次元ホモロジー(点のあつまりを点とみなすときの点)、1次元ホモロジー(点のあつまりを線とみなすときの輪)、2次元ホモロジー(点のあつまりを面とみなすときの球)がそれぞれ1,2,1となるのが自然です。こういう輪っかの数のことを各次元のベッチ数と呼ぶそうです。ベッチ、ベッチ、いそべっち。いやすみません。

その条件でホモロジー計算させた結果。バーコードとパーシステントダイアグラム。

b0の図が0次元ベッチ数のバーコードで、横軸のフィルトレーションが1.5あたりで一気に一個に集約されてます。
b1のほうはその切り替わる1.5あたりで輪っかを一つ認識していて、2.3あたりからもう一つの輪っかがリレー式に出来てます。これは多分解像度の調整がうまくいってないせいで、ドーナツを切り分けた断片に相当するパイプチューブみたいな形の組み合わせが次第に集約されていってると認識してるんじゃないかと思います。

そして残念な事にb2つまりドーナツの中の空洞は認識できませんでした。パラメータ設定を色々変えると、解像度がある一定を超えると一気に計算量が増えるのか、pHomの呼び出しが帰ってこなくなります。この辺りのアルゴリズムの計算量のことをもうちょっと学ばないと。

下のパーシステントダイアグラムのほうは上の各バーコードの両端を2次元にプロットしたものなので意味するところは一緒です。

というわけで

高次元データの分析をやる際に、まずラフな事前集計として形状を大まかに見るのに使えないかなと期待をしているのですが、今のところそう簡単ではなさそうな感じです。もう少し中身の事を良く知った上で使えるなら使っていきたいです。仮にstate of artな実装として限界が存在するのであれば、数学とアルゴリズムを勉強して効率化にチャレンジしてみたい。機械学習のカンファレンスで研究発表とかしてみたいなぁという思いが最近どんどん増している。

ホモロジーとは何か

xiangzeさんのブログ記事に凄く興味をもって、20代の頃に取り組んで挫折した代数トポロジーについてグーグル先生に教わった。

ホモロジー群の嬉しさ(プログラマ目線)

図形が「同じ」であることを数学的に定義する方法として、合同や相似というのは中学校でならうけど、トポロジー的に見て同じかどうかを数学的に厳密に定義するにはそれなりに追加の知識が必要になる。

でも、そういう「同じ」を数学的に定義する事でコンピュータで「同じ」かどうかの判定をさせることが出来るようになるので価値がある。

例えば、合同かどうかの判定が数学的にできるとどんなアプリケーションソフトウェアが実現できるだろうか。例えば3次元の物体の形が2つ与えられたときにその2つの形が同じかどうかを判定するというプログラムを作りたかったら、2つの図形をそれぞれ決められた手順でポリゴンに分割して、ポリゴンに含まれる各三角形が同形かどうかをしらべればもとの2つの形が同じだったかどうかを判定する事が出来る、とか。合同にもとづいて判定すれば図形が回転していたり鏡像反転してたりしても大丈夫だし、さらにポリゴン化する手続きの一貫性しだいではかなりロバストな形状一致判定プログラムが実現可能になる。

同様に、相似が定義できると、そうした形状の拡大縮小に対応できるようになる。

数学的な定式化は主に代数的な手続き、つまり図形を実際に描いてみることなく記号的な演算でそれを代行することによって、図形を描けないような高次元のものとか、関数や集合のように1点ずつプロットできないようなものとかを分析対象とすることが出来るようになる。

ホモロジー群は図形に空いた穴の数や空間の数、図形が何個に切り離されているかという性質を代数的な手続きによって定式化する方法。

もしそれが出来ると、直接図示できないような高次元のデータとか関数そのものとかを対象として、穴の数や空間の数やいくつに分割されているかといった性質を調べる事ができるようになる。xiangzeさんが紹介しているパーシステントホモロジーという手法はコンピュータ上で計算し易いようなホモロジーを定義する方法のようだ。

ホモロジー群の概要

群論を使うけど、群論の基礎的なところは本当に簡単なので箇条書きしておく。

  • 群というのは集合の一種。要素同士の掛け算ができる。正確な定義は群論ググること。
  • 掛け算の左右をひっくり返しても結果が変わらないような群をアーベル群と呼ぶ
  • 2つの群の間で掛け算の性質を変えないような対応付けを準同型と呼ぶ

準同型っていうのは例えば男女の恋愛市場を考えてみるとして、A君とB君がそれぞれCちゃんとDちゃんを好きだとしたらA君とB君を掛け算したようなX君がもしいたら、X君が好きな女性はCちゃんととDちゃんを掛け算したようなYちゃんになっているような、そういう特別な「好き」という対応関係。

つづいて群の核、群の像、正規部分群、商群

  • 女性の側にマドンナが一人いるとする
  • マドンナはすごい。マドンナはどんな女性Zと掛け算してもZにしかならない。
  • つまりマドンナは超絶美女なので掛け算相手にいくらでもあわせられるのだ。
  • そのマドンナのことを好きな男性たちのことを男性全体を群としたときの準同型の核と呼ぶ
  • いっぽうで、女性の中には全くモテない女性というのもいる
  • 少なくとも一人以上の男性に好かれている女性の全体を男性全体を群としたときの準同型の像と呼ぶ
  • 直感で予想されるとおり、核は男性全体の群の部分群だし、像は女性全体の群の部分群になる
  • さて、マドンナというのは何も3次元だけとは限らない
  • 2次元の女性全体の群について同様にマドンナというのがいる
  • 2次元のマドンナの事を好きな男性も核と呼ぶ
  • それは先ほど挙げた核とはまた違った男性陣だろう
  • さて生身の女性、2次元と2つ例を挙げたが、他にも色んな「好きの対象となる群」はありえる
  • そういう対象となる群にはかならずマドンナ的存在がある。例えば好きな動物ならパンダとか
  • そういうなにかしらマドンナ的存在を好いている男性グループのことを正規部分群とよぶ
  • 不思議な事に正規部分群のメンバーは実は男性の中でもリーダー的存在だという性質がある
  • つまり、正規部分群のメンバーはコミュニティの代表者だということが証明できる
  • 例えば2次元好きという準同型ではマドンナ好きの男性はそれぞれコミュニティを持っている
  • ちなみにコミュニティ同士での掛け算というのが定義できて、商群と呼ぶ
  • なぜかアーベル群の部分群は必ず正規部分群になるという性質がある

続いて単体と複体

  • 点、線分、三角形、三角すい、...と各次元におけるプリミティブな図形を単体と呼ぶ
  • プリミティブな図形である単体をうまくつないだものを単体複体と呼ぶ
  • 単体複体を使うと、任意の図形をプリミティブな図形の組み合わせで写し取れる
  • いってみればPhotoshopみたいなラスタじゃなくてイラレみたいなベクタで考える
  • 形が一つあっても、ベクタの取り方は無限にありうる
  • そこで、上で説明した商群の概念を応用する。ベクタのコミュニティを考えよう。
  • それができれば形の違いはベクタのコミュニティの違いで表現できるはずだ
  • 穴がどうなっているかの判断プログラムは、ベクタの境界を取り出すという操作を考えるとうまくいく。
  • 例えば、円(円周じゃなくて中身が詰まったもの)について考えてみよう
  • 円の境界は円周だ。円周の境界は、、なにもないの空だ。
  • これを逆手に取って、「境界があるならば中身がある」「境界がないなら穴がある」と定義する
  • そう定義するとうまくいく事が確かめられる
  • さて、ベクタと言ってるのは単体複体のことであった。
  • 単体複体はアーベル群で表す事ができる。ちょっと試せばそれはわかる。
  • 境界を取り出す操作はそのアーベル群の準同型として定義できる
  • ただし準同型であれば何でもいいというわけではなくて、上の「境界を取り出す」性質が必要だ
  • それは、任意のベクタに「境界の境界」という風に境界を取り出す操作を2回連続でやったら何も残らないという性質だ
  • しかしそんな適当な性質でいいのだろうか。
  • つまり「二回連続で適用したら何も残らない」ような準同型を境界と呼んじゃっていいのだろうか。
  • しかしそういう風に定義しておくと数学的に色々うまくらしいので、我慢して受け入れよう。
  • ちょっと上で述べた恋愛準同型で考えてみよう
  • 男性を俳優とそれ以外に分けて考えてみる
  • 女性の方は女性全体じゃなくて女優全体で考えてみる
  • つまり「俳優以外の男性全体」-好き->「女優全体」-好き->「俳優全体」を考える
  • このとき、好きという準同型が「境界を取り出す操作」になるとはいかなることなのだろうか
  • 境界の定義とは、境界の境界が空っぽということであった。
  • それは「少なくとも一人以上のファンを持つ女優」は実はみんな「たったの一人の俳優」ファンだったということだ
  • つまり、境界というのは「像が核に含まれる」という性質を持つ
  • 核のメンバーはリーダー的存在なのであった。
  • つまりたった一人の俳優のファンになっている女優は実は女優内の各派閥の長なのだ。
  • 像が核だということなので、世の男性たちは派閥のトップたちのさらにその一部に好みが集中しているということになる
  • つまり女優内の派閥のトップであってもファンが一人もいない女優もいっぱいいるということだ
  • さて、ここで考えたいのはもともと単体複体だからアーベル群なのであった。
  • アーベル群の部分群は正規部分群になるのだった。
  • つまり、派閥のトップをつとめる女優たちの中で、ファンを一人以上持つ女優はリーダーオブリーダーなのだ。
  • なので、そのリーダーオブリーダを穴の代表とすればそれを調べる事によって穴がどうなっているかを詳しく分類できるのだ
  • つまり、なんの図形もなしに一般的に「境界を取ると何も残らないようなベクタ」はいっぱいあるけど、
  • 「なんらかの図形の境界になるようなベクタ」はそいつらの正規部分群になるので、
  • それで商群を取ってやれば穴の数が同じものを同一視できるってことが数学的に言える
  • そういう商群をホモロジー群と呼ぶ

まぁ、ちょっとあれですけど、そういう事だと思います。

起業家と開発者と研究者

僕は、その3つを同時にやりたがっている。

社名を変更しました

アドファイブ株式会社は、4/1日付けでAD5(エーディーファイブ)株式会社に社名を変更致しましたのでお知らせいたします。

近年、データに基づいたマーケティングがますます重要になってきており、当社は設立来約1年半にわたってWeb広告関連事業に特化して取り組んで参りました。

その中で、データに基づくマーケティングは業界として深刻な人材不足及びノウハウの断片化といった課題を抱えていることを実感して参りました。

当社の設立目的は、複雑化を極めるアドテクノロジーの世界において、高度なアルゴリズムやシステムテクノロジを簡単に使えるユーザーインターフェースと共に提供することで、業界の発展に寄与するというものです。

そうした背景から、当社役員会議において以下を決議いたしました。

  • 事業対象領域を企業マーケティング全般に広げる
  • 「データに基づいて顧客のことをより広く深く知る」という価値を追求する
  • 人材不足の解決にはシステムが自動的にそうしたタスクを行える必要がある
  • そこでコア技術を「オートマチック データサイエンス」とする

そしてコア技術のオートマチック データサイエンス (Automatic DataScience)における以下の5つの技術開発に注力します。

  • 予測:顧客の行動や購買心理を予測する
  • 可視化:分析結果をグラフィックと自然言語で可視化する
  • 推薦:分析結果に基づいて各種のレコメンドを行う
  • 教示:製品を使うことでユーザに自然に技術が身に付く
  • 感動:難解さを打破し感動的なユーザ体験を提供する

こうしたことを踏まえ、Automatic、Datascience、5つの価値、のそれぞれの頭文字をとって新しい社名をAD5(エーディーファイブ)とすることとなりました。

なお、社名変更会議において役員の一人から

「Automatic Data Scienceだから、ADじゃなくてADSじゃないのか?」

という指摘がありましたが、

「ADSだとしても、AD5って紙に書いてみて遠くから見たら5がSに見えてくるから大丈夫だ」

という代表の強い意向がありましたことを添えておきます。

今後ともAD5株式会社をよろしくお願いいたします*1

*1:4/1はエイプリルフールです

RBM in Julia

一昨日Rで書いたRBMを使ってdeep learning tutorialで紹介されているMNIST手書き文字画像(観測ノード数はピクセル数と同じ784、訓練データが60000画像)のデータを食わせてみたら激しく遅いのでC++より書きやすくて実行効率もいいとうたっているJuliaで書き直してみました。

元のRのコードが動けばいいレベルだったこともあって2000倍以上速くなりました。Rのコードにも改善を少し反映し、ソース一式がGistに置いてあります。(元のコードに少しバグがあったのでそれも直して一昨日のブログエントリ中のコードも更新)

Julia版のダミーデータでの実行結果

init OK.
step 1 : err=0.48333333333333334
step 2 : err=0.4777777777777778
step 3 : err=0.4722222222222222
step 5 : err=0.4722222222222222
step 8 : err=0.4527777777777778
step 37 : err=0.44722222222222224
step 50 : err=0.4444444444444444
step 65 : err=0.4222222222222222
step 138 : err=0.4166666666666667
step 248 : err=0.4166666666666667
step 336 : err=0.4
["theta"=>Theta(4x3 Array{Float64,2}:
  0.0431936   0.0366259   0.0158433
 -0.0263127  -0.0249457  -0.0318039
 -0.0396297  -0.0404271  -0.0259556
  0.0352671   0.0358384   0.0274096,[0.7931471805599453,-0.27314355131420986,-0.27314355131420986,-0.12314355131420984],[-0.013569603640624033,-0.013700729830354374,-0.014453002676093538]),
"learn_info"=>"step 336 : err=0.4","reconstruct"=>reconstruct]

0	0	1	1
0	1	0	1
1	0	0	1
1	0	1	0
1	0	1	1
1	1	1	1
1	0	1	0
1	0	0	1
1	1	1	0

R版と同様に動いてます。

MNIST手書き文字画像データの実行結果

サンプルが動いたのでMNISTのほうもやってみたところ、自分のサブマシン(Core i3 2.4GHz, 8GB mem Win7 x64)で隠れノード100で訓練データ60000画像に対してCD1の1ステップを計算するのに12分くらいです。並列化を実装して、性能のいいマシンを使えばさらに速くなりそう。もろもろ完成したらAWSのHPCインスタンスを1時間くらい使ってやろうと思います。

以下、まとめなど

高速化関連メモ

  • なるべく添え字を消して行列演算で済ませてネイティブライブラリが使われるようにする
  • 同じ計算は2度やらない。数式だと良く見てないと気付かないことが結構ある感じ

Julia関連メモ

  • Juliaのベクトルは縦ベクトルなことに注意
  • テンソルスカラーは別扱い。ベクトルの要素数が1のときにスカラーにならないのに注意。
    • というかこれはRのほうが特別扱いなだけなんだけど
  • 要素どうしの演算なときはドット付きの演算子を使うこと
  • 配列を内包表現で作ると要素の型がAnyになるの注意(かなりハマった)
  • serialize/desializeで変数ダンプできるのが便利
  • JuliaStudio IDEとかもあって便利なんだけど起動がもうちょっと速くなってほしい。。

Juliaも慣れてきたのか、なかなか可愛くなってきました。

ピュアRと比較してアルゴリズム実装言語としては開発効率が変わらないように思うので、今後はこの手のアルゴリズムは最初からJuliaで書こうと思います。

今日はRBMの高速化に作業時間を使って多層化DBNまではたどり着けず。近日中にまた続きをやるつもり。

「私がJuliaを推す理由」(翻訳)

Juliaについて書かれた海外のブログ記事でとても共感したものがあったのでブログ主に無断で翻訳したものを掲載します。(もし問題ありましたらご連絡ください。)

このブログの著者はEvan Miller氏というソフトウェア開発者でWizardというかなりイケてそうな統計分析パッケージソフトを専業で開発している人みたいです。フリーランスなのかな。考え方も環境もそしてもしかしたら年齢も僕と似ている人なのかもしれない。

私がJuliaを推す理由」(2014/1/23)

殆どのプログラミング言語の問題はそれらが言語ギークによってつくられていることだ。彼らは私ならほとんど気にしないようことに傾注しがちだ。安全性、型システム、同図像性、などなど。私はそういうものが確かに素晴らしいと思ってはいるが、新しい(訳注:そういう新プログラミング言語とかの)プロジェクトを興味本位で漁ってみる際に関心があるのは(1)役に立つか(2)速いか の2点だ。私にとってはコードは車みたいなものだ。つまりそれは目的値への手段なのだ。コード片が持つ”expressiveness(表現力)”はいわば排気ガスの三元触媒がもつ"expressiveness(訳注:一石三鳥的な意味合い)"みたいな重要さだ。

このアプローチでのプログラミング(訳注:一行のコードの表現力が高いことを重視してコードのかさを減らすようなスタイルのことだと思われる)はしばしばカウボーイスタイルだなんていわれたりする。カウボーイってのは私は正確なイメージじゃないと思うんだ。だってカウボーイは馬を相手にするから馬の都合で時々休んだりしなければならないじゃないか(訳注:こういうウィット好き)。もっと向上心を感じさせるイメージ、それは精巧につくられた機械装置、それも出来たばっかりで最初に使った人が火を被るようなもの、それに数週間も取りつかれちゃった研究者がラボの中で目が充血し疲れ果てて青白くなっているような感じかな。

まぁ私の好みについての話はもういい。普段私は何かを作る言語を第一言語として、それと作ったものを高速化する言語を第二言語として、そしてちょっとそれを悲鳴を上げるほど面白くするための言語を第三言語として使っている。そういう使い分けは、なかなか良くあるパターンだ。多くのプログラマにとってプロトタイピング用の言語はPython,Ruby,もしくはRだ。いったんコードが動いたら、こんどは遅いところをCやC++で書き直す。おかしい人になるとCのループをアセンブラやCUDAやOpenCLで書き直しちゃったりする。

しかし好ましくないことに、プロトタイピング用の言語とC/C++の間には大きな壁があるそしてC言語アセンブラの間にもまた大きな壁がある。職を得るために3つ言語を習得した上に、それらの壁を超える時に意識のスイッチが必要になる。もっと身近なケースでいうと、壁を超えるためにグル―コード(訳注:複数のプログラミング言語のコードをつなぐためだけに使うコード)をたくさん書く必要があるし、ソースファイルやエディタやデバッガもそれぞれ別で切り替えなければならなかったりする。

私が少し前にJuliaについて読んで、これはクールだと思ったんだけど、すぐに使わなければいけないものでもないと思った。Juliaはパフォーマンスがグレートな動的言語だ。それはいいと思ったが、既に私はフォルクスワーゲンのビートルみたいな車にフェラーリのエンジンを搭載するようなことをさんざんやってきているから、なぜ新車が必要なんだ?みたいなことを思った。それに今は色んなプラットフォーム いくつか挙げるならJava HotSpot, PyPy, asm.js、そういうのがC言語と同等のパフォーマンスを他の言語でも実現するとうたっている。

そのちょっと後で、私はJuliaが他の言語と決定的に違う点に気づいた。Juliaは2番目の壁を打ち破る、つまり高い抽象度のコードとネイティブアセンブリの間の壁を超えるものだということだ。C言語と同等のパフォーマンスを出すコードをJuliaで書けるだけじゃなく、どんな関数でもLLVM中間言語コードとさらにそれがアセンブリコードにどう翻訳されるかを見れるのだ。しかもREPL(インタプリタの対話環境)。ちょっと試してみよう。

emiller ~/Code/julia (master) ./julia
               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "help()" to list help topics
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.3.0-prerelease+261 (2013-11-30 12:55 UTC)
 _/ |\__'_|_|_|\__'_|  |  Commit 97b5983 (0 days old master)
|__/                   |  x86_64-apple-darwin12.5.0

julia> f(x) = x * x
f (generic function with 1 method)

julia> f(2.0)
4.0

julia> code_llvm(f, (Float64,))

define double @julia_f662(double) {
top:
  %1 = fmul double %0, %0, !dbg !3553
  ret double %1, !dbg !3553
}


julia> code_native(f, (Float64,))
     .section        __TEXT,__text,regular,pure_instructions
Filename: none
Source line: 1
        push    RBP
        mov     RBP, RSP
Source line: 1
        vmulsd  XMM0, XMM0, XMM0
        pop     RBP
        ret

うぉ、1行の関数を書いてからLLVMで最適化されたx86アセンブラコードを確かめるまで20秒もかからずに出来てしまった。

なのでJuliaについて調べると出てくる型システムや多重ディスパッチや同図像性などの特徴のことは忘れちゃっていい。そういうのはクールだと私も思ってるけど、私と似たタイプの人にとっては最初にプロトタイプを作ってからマルチコアやSIMDでパフォーマンスを最適化するまでをJuliaだけで出来ちゃうのが現実的なベネフィットなのだ。

端的に言えば、私がJulia推しなのはそういうわけだ。この話を他と対比させるのはあんまり気が進まないのだけど、いってみればこれはNode.jsがWebシステム開発でやっていること、つまり全然違うグループのプログラマが同じ言語を使ってるということ、それと同じことを科学技術計算でやるということだ。Node.jsのおかげでフロントエンドのデザイナとバックエンドの開発者が一緒に仕事できる。Juliaがあればドメインエキスパートと実行速度厨が一緒に仕事できる。それは大きなことだ。

そういう点ではJuliaの欠点はライブラリが不足していることだろう。けどこの言語は他とは違って圧倒的に簡単にCのライブラリを呼び出すことができる。他の言語にあるネイティブインタフェースとは違って、C側にそれ用のコードを全く書かずにJuliaからCのコードを呼び出せる。なのでJulia対応ライブラリはかなり早く揃っていくんじゃないかとふんでいる。個人的に使ってみた感じだと5千行のCのコードを、C側のコードを全く改変せずにJulia側で150行書くだけでJulia用のライブラリにすることができた。

もし貴方がPython,C,C++,Fortran,Rをつなぐような眩暈がする類の技術グループで仕事してたり、私のように「shoot-from-the-hip Lone Ranger」に出てくるはやてのカウボーイみたいな速度厨だったら、Juliaをダウンロードしてちょっと転がしてみることをお勧めする。仮に貴方が知らないプログラミング言語なんかで職業生活を複雑化したくない人だとしても、Juliaを使えたら最終的には貴方がかかわることになるプロジェクトで必要になってくるプログラミング言語が少なくて済むようになるんだってことを考えてほしいのだ。

あとここまで敢えていわなかったんだけど、パフォーマンスのことを抜きにしてもJuliaは実際にいい言語だ。私はプログラミング言語を見る目が肥えてるわけじゃないが、学ぶにあたって頭を悩ますようなリスクは殆どないといえる。今現在、私の中でJuliaはお気に入りトップ3の言語だ。

最後に、活発でサポート手厚いJuliaコミュニティがあることについて。私がこのコミュニティで好きな部分は頭が良くでフレンドリーな数学・科学タイプの人たちであふれていること。それはJuliaが言語オタクによってつくられた言語じゃなく、MITの数学や科学や技術に携わる学生たちがCやFORTRANに代わる速くて実践的な言語が欲しくて作ったものだからだ。なので言語自体の美しさではなく答えを速く出すことのために設計されている。私にとってそれはまさにコンピューティングの本質なんだ。

最近の興味

ありすぎるのでまとめておく

アドテクへの機械学習の応用

これは会社を作ったのだからなんとか製品化できるものを見いだしたいと思っている。カルマンフィルタや粒子フィルタ、LDAやDeeplearnig等を研究している。バンディットアルゴリズムベイジアンネットも有力だと思う。
メディア分析、マーケティングデータからのナレッジ自動生成といったところも断片的にアルゴリズムを作っているという段階。早く製品リリースせねば。。
昨年やりかけたDSP/RTBとスマホネイティブのクロスプロモーションアドサーバはオープンソースにしちゃおうか迷い中。前者はOpenRTB(C++LuaとPyton)と簡単なキャンペーン情報から入札ロジックへの変換プログラムと簡単な管理画面(Node.js)、後者はリワードで良くあるインテント戻しでユーザ識別する機能とかオフラインキャッシュとか諸々実装したAndroidアプリ向けのシンプルなアドサーバ(Node.jsとPerl)。

O2O/リアルイベントに特化した情報キュレーションアプリ

これはWebクローラが必要で、ぼちぼち作っている。なるべく「イベント情報ポータル業者」から情報をパクるという方法は避けたいと思っていて、きちんと情報元から情報を取ってこられるような作りを試行錯誤している。マークアップの違いをうまく吸収してイベント情報の意味的なタグを付与してDBに登録するまでが大変。
アプリ側のキュレーションやソーシャル機能は考えるまでもなく実装すれば済むところなのであまり心配はないのだが、僕一人でやっているのでそうしたアプリ開発はさっと済ませるようになっておかねば。あと現状、Webアプリを作るときにさっと使えるのがNode.js+expressしかないので、Play2.0とdjangoのいずれかはもう少しさくさく使えるようになっておきたい。

証明駆動開発と型システムの述語論理的拡張

プログラムの動作を保証しながらコードを書けるCoqというプログラミング言語が面白そう。業務で実践活用するわけではないけど、自己啓蒙として。あとHaskellを含め現在普及してる型システムはいわば命題論理的なクラスであってCoqのそれは述語論理的な拡張を施したものと見なせるんだとか。そういうテーマにも興味ある。あと圏論コンピュータサイエンスに関わるところだけでも学びたい。Haskellプログラムの圏とか。

WebWorkerを使ったグリッド余剰計算資源の仲介サービスとビットコイン採掘によるマネタイズ

HTML5対応ブラウザに実装されているWebWorkerを使ってグリッドコンピューティング的な事が可能だと思う。従来の計算グリッドは専用の計算クライアントをインストールする方式(Folding@HOMEとか)だがWebWorkerを使えばブラウザでWebサイトにアクセスするだけで計算リソースの寄付が可能になるはず。計算処理をJS上で行うのは非効率な気もするがV8エンジンはマジで速い。Javaの2/3くらいのスピードで動作するし。
あとビジネスモデルとしては、そのWebサイトをアカウントでログインできるようにして余剰計算リソースの提供した分だけあとでグリッドを使えるようにして、計算資源の時間差取引の仲介サービスを運営するというのを考えた。クレジットポイントみたいのをやり取りする感じ。でサイト運営者は全計算リソースの2〜3割程度を仲介手数料的に徴収し、ビットコインの採掘を行ってマネタイズするというものだ。どうですか、面白そうじゃないです?

FreeFem++を使ったオレオレPDEソルバー

コンピュータ上でいろんなモノ作りを支援するCAEの分野では対象物の形状を3次元CADデータとして物理法則を偏微分方程式(PDE)としてモデル化し、その方程式を解く事で性質を分析するが、その際に有限要素法(FEM)というのが良く使われている。FEMはいわば計算のフレームワークを提供するものでPDEのタイプによって色んな工夫が必要になる。FreeFEM++はそういう部分で実装支援してくれるC++フレームワーク。流体や熱伝導や衝突変形等のシミュレーションと可視化をやってみたい。微分方程式というのは要は局所的な構造がマクロな性質を決定するようなメカニズムを記述するテクニックだと思うので、統計処理にもそういう知識が転用できるんじゃないかという期待もある。
FEMは方程式の解を物理空間上の関数とみなすオイラー法というカテゴリに含まれる手法で他に差分法や有限体積法というのがあるが、いっぽうで解を質点上の関数として解くラグランジュ法というカテゴリもあって粒子法というのが最近出てきていてそれも面白そう。

MD法を使った分子シミュレーション

昨年のノーベル化学賞はこのMD法の開発者に授与された。上で述べたFEMや粒子法は物理対象を連続体とみなしてモデル化するものなので、分子レベルのミクロな性質を直接分析することが出来ない。それには原子や分子の振る舞いをモデル化する必要があって量子化学という理論はあるがそのままでは状態数が多すぎて計算出来ないので精度よく近似する工夫が色々必要になる。原子間レベルではMO法(分子軌道法)、分子間レベルではMD法(分子動力学法)というのが使われる。そこでは微分方程式を立てるのではなく分子や原子に相当するオブジェクトをたくさん(アンサンブルと呼ぶ)作って、それらを一連の法則に従って動かす事で全体的な性質を見るという使い方をする。解きたい物理系に応じてアンサンブルに課す性質やポテンシャルエネルギー(力場という地図みたいなデータをプログラムに与えて動かす)を変える事で色んなシミュレーションが出来る。簡単な所から始めて例えば希ガスの沸点とかが分かったりすると面白そう。コードはJuliaで書くのがいいんじゃないかと思っている。
システムバイオロジー、ナノテクノロジー、新材料といった21世紀に飛躍的に進歩しそうなところの基本的な技術なのでぜひ習得して何らか関われたらいいな。

ProcessingやClojureを使ったアルゴリズムアート

絵を描いたり曲を作曲したりしてみたいってずっと思ってるのだけど、ちょっと試しては挫折するのを繰り返している。数年前に作曲をしてみようと思ったときにまず音楽理論を勉強して、大変面白かったのだがそれで良い曲が作れたわけではなかった。なのでプログラミングの延長線上で出来ないかなと思う。
Processingという言語があって、メディアアート向けの機能がそろっている。最近だとprocessing.jsなんてのも。この手の動きのあるデータを自動生成するときはLISPを使うのがいいという印象があって、ClojureでProcessingのコードやデータを生成するようなものを作ってみたいなと思う。フラクタルと現実世界の風景を組み合わせたような作品をプログラム的に作れたら面白いだろうな。
あとは既存の作品から特徴抽出して模倣するようなプログラムも面白そうだ。例えば音源のwavファイルを与えると内部で信号処理等を諸々行って楽譜と楽器構成を出力してくれるとか。使われてるボコーダやエフェクタの認識とか。

教示的プログラミング言語トランスレータ

あるプログラミング言語を学んで、それが手になじむようになってくると多くの人は他の言語に移行しずらくなったりすることが多いように思う。そこで自分のお気に入りの言語で書いたソースコードを入力すると、他の興味ある言語のソースに自動変換してくれて同じ処理をどう書けるか教えてくれるシステムがあったら面白いだろうなと思う。
もちろん言語を使い分けるメリットはそれぞれの言語がもつ特長を生かしてこそ生まれる。そこでシステムにはそれぞれのプログラミング言語における有効なコーディング方法などの知識をあらかじめ搭載しておいて、トランスレートの際にそれが適用出来そうならばユーザにその旨を教示するという機能が考えられる。そうすれば自分が慣れた言語でのコーディングが他の言語だと書き易くなるケースに遭遇することが増えて、適材適所でプログラミング言語を使い分けるようになるんじゃないかと。そういうシステムを作る事は、僕がいままで貯めた知識をかなりいかせそうなタスクだと思う。

テキサスホールデムポーカーの思考エンジンの開発

ホールデムはルールは単純なのにとても複雑で面白く世界中にプレイヤがたくさんいるので、コンピュータ思考エンジンを作るのにもってこいの題材だと思う。カナダのアルバータ大を始めとして世界では研究開発している人たちはいるけれど、機械学習の実験台としても魅力的なのででやってみたい。既にHaskellでゲームルールの処理を書いたりはしてみてるのだが、ちょっと全てをHaskellで組むのはあまりよろしくなさそうだと思い始めてる。

バンディットアルゴリズムの実装とライブラリ化

割と色んなアルゴリズムOSSのライブラリとして公開されている中で、バンディット問題だけはまだそんなに出そろってないように思う。研究レベルで色んなアルゴリズムが考案されているがプロダクションレベルのものはあまり見かけない。でもバンディット問題はビジネスの世界のありとあらゆる場面に適用可能な汎用的な問題であり、アルゴリズムの性能さえよければすぐに活用されうる類のものだと思う。上のポーカーの思考エンジンと合わせてバンディットアルゴリズムの実装とライブラリ化をしてみたいなって思う。

計算代数・グレブナー基底を使ったロボットのアームや姿勢の制御

5年くらい前からやろうやろうと思ているので早くやること。

イミュータブルなデータの並列処理をHaskell/Clojure/F#で

関数型言語は並列処理に向いている」とお題目のように耳にするのだけど、実際のところJavaC++でスレッド書いた方が速い気がするのでちゃんとその本質的なところを実践して身につけたい。software transaction memoryとかevaluation strategyとかdataflow DSLとかそういうところを使いこなせるように。Kindleで3冊洋書を買って読んでバックグラウンドの知識は得たところ。例題があるといいのだが、いいタスクはないだろうか。もう始めから時系列処理とか機械学習とかをやっちゃうべきか。

TopCoderでハイレートの人なら常識的に知ってるアルゴリズム網羅的習得

TopCoderは才能の面も大きいとは思うが、ハイレートの人と比べてまだ自分はアルゴリズムの知識が不足していると感じる。特にグラフ関連と数学関連のアルゴリズムが弱い。レッドコーダーになる目標を立てたものの相対的に興味が落ちてきてるので毎日強制的に30分とか時間をとるべきか。

C++をもっとちゃんとやる

C++は将棋ソフトの開発して以来しばらく使ってないので、eigenやアルマジロといった最近のライブラリを使って高効率なプログラムを書くスキルを身につけたい。何か題材を見つける必要があるけど何がいいんだろう。他の言語で書いてアルゴリズムの理解が出来たものをどんどんC++化していくという形にすべきか。

BUGSとStanを使ったベイズモデリングの実践演習

BUGSは教科書通りに3つくらいやってみただけでまだまだ。Stanはインストールすらしてない。最新のデータ分析スキルを身につけておきたいのでコンスタントに練習しないといけない。BUGS Book買ってやるかなぁ。

Deep Learningの実践的スキルの習得

Deeplearningはいわゆる次元削減をシステマティックに自動的にやる技術だと思うので、これを習得する事はかなり汎用性のあるスキルになると思われる。色んなメディアデータに合わせてネットワークを構築したりチューニングしたりっていうのを少しずつやっていきたい。

機械学習の包括的な理論的背景の勉強

甘利先生の情報幾何学や渡辺先生の特異モデルの理論のような、機械学習を包括的に見渡せる理論を習得して普段の開発における手法選択やパラメータチューニングにおける理論的な裏付けを強めたい。多様体や代数幾何や関数解析の知識が必要になると思われるので簡単じゃないだろうけど、40歳くらいまでにはこういうところはきちんと分かる人になっておきたいなって思う。

論文や教科書に載ってる数式変形をMathematicaで出来るようにする

Mathematica Home 8というのを数年前に買ったがあまり使っていない。RやMatlabと違ってMathematicaMapleは数式そのものの処理が出来るところが特徴なので、特にPRMLに乗っているような数式をMathematicaを使って自由自在に変形できるスキルを身につけたい。
いわば「かな漢字変換」を使う事で漢字を覚えておかなくてもよくなったように、Mathematicaを使う事で理論的な式変形を簡単にトレースできるようになりたい。

他にも

まだまだあるかも。思い出したら追加していく。

  • MCMCの実装。GSやHMC・NUTSなど実際に書いて理解する。CUDAやHadoop上の高速化とか。
  • 自然言語文章生成。データジャーナリズムというのが流行りつつある。ナレッジ自動生成結果を文章化。
  • Active Learning試す
  • 計算代数統計試す。研究が進められているものの一つ、分割表におけるp値を漸近的にカイ自乗値として推定するのではなく正確検定で網羅的に計算するとき計算量が爆発するのをグレブナー基底を求めてそいつの上をMCMCすることで真のp値の分布からのサンプリングで推定可能になるという手法。