LDA CVB0 の C++ 実装

ちょっと C++ で実装したいものがあるのだけど、その前に練習ということで LDA の CVB0 推論を C++ で実装してみた。


VC++2010 でしかビルドしてないが、一応後で gcc でもビルドしてみようかなとか思っているところ。
ビルドには @herumi 謹製 cybozulib が必要。


mmap ででかいファイルを効率的に読み込んだり、トピック単語分布の上位20語を抽出するのに便利なクラスが用意されていたり、とかいったあたりでお世話になっている。


cybozulib は std::string と互換かつ UTF-8 を透過的に扱える文字列クラスもあるんで、本来ならマルチバイト対応したかったんだけど入力テキストは ascii のみ。
今回の実装を始めたときはまだ正規表現まわりで互換性が不足していたので。が、その中で色々要望を出して対応してもらったので、後でマルチバイト対応するかも。


入力コーパスPython 版実装と比較できるように nltk のものをそのまま読める、ようにしようとした。


Brown corpus ならここからダウンロードして、展開、POS のアノテーションが付いているので -p オプションを付けて渡す。
読み込ませたいファイルをすべて指定しないといけないのだが、 cygwin ならこう書ける。

ldacvb0.exe -p brown/????


reuters corpus も同様。こちらは POS 付いてないので -p オプション不要。ただし、コマンドラインが長くなりすぎるので全てのファイルを渡すことはできない。
いろいろ手抜きですまん。


速度的には Python + numpy の20倍強といったところかな。
十分速いっちゃあ速いんだけど、ダブルバッファとか頑張ってしたのに、期待したほど速くはないというのが正直な感想。
うまく使えるアルゴリズムでの numpy は結構速いよってことなんだろうけど。


速度は20倍だけど、実装コストも20倍って感じ。
C/C++ で書くとなるとどうしても無駄なコピーをしてはならないという強迫観念に襲われてしまって、なんか素直な書き方ができなくなるんだよなあ。経験不足なんだろうけど。