2008-05-22

Ward法のPythonバインディングを作りました。

先日から作っていたクラスタリング(Ward法)のPython用バインディングを作りました。Pythonから一応つないで使えるようになりました。

ソースコードの取得とインストール。


$ svn export http://svn.coderepos.org/share/lang/cplusplus/misc/clustercpp
$ cd clustercpp/python/wardcluster
$ python setup.py build_ext --swig-cpp
$ sudo python setup.py install

サンプル実行。
引き続きディレクトリclustercpp/python/wardcluster内で以下を実行してください。

$ python sample.py
1 + 0 => 4 ( 0.244948974278 )
3 + 2 => 5 ( 0.412310562562 )
5 + 4 => 6 ( 4.80645253132 )
$

ちなみに、今上で動いたsample.pyは以下のようなスクリプトで、4本のベクトルをクラスタリングしています。
from wardcluster import Matrix, DoubleVec, Ward

m = Matrix()
m.append(DoubleVec([1.0, 2.0, 3.0]))
m.append(DoubleVec([1.1, 2.2, 2.9]))
m.append(DoubleVec([0.1, 1.2, 5.0]))
m.append(DoubleVec([0.3, 1.0, 5.3]))

w = Ward()

history = w.cluster(m, 4) #この4ってのは、ベクトルの本数

for h in history:
print h.index1, "+" , h.index2, "=>", h.newindex , "(", h.distance ,")"


メモ--------
* setuptoolsを使ったオシャレなモジュールにするのは断念。(swigの結果ファイルとの調整が難しかった)
* swigのtypemap?とか、そういうのはむずかしくて分からないので、めんどくさいインターフェース。
* あくまで実験的なものですよ。
* 相変わらずswigを理解できていない。
* 今回ベクトルの集合を表すために内部でstd::vector<std::vector<double> >を使うようにしたので、パフォーマンスが落ちています。(将来もとのstd::vector<double>*を使って渡す方式に戻したいものです。。。)