mots quotidiens.
Daichi Mochihashi (持橋大地) daichi <at> ism.ac.jp by hns, version 2.10-pl1.

先月 2004年11月 来月
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

2004年11月08日(月) [n年日記]

#1 lda, a Latent Dirichlet Allocation package.

というわけで, 公開。 MATLAB版とC言語版があります。

lda のページを修正。ファイルも新しくなっています。今日はちょっとつかれてるみたい なんで続きは後日..。


2004年11月10日(水) [n年日記]

#1 lda, a Latent Dirichlet Allocation package. (2)

Webページに色々書き足し & コードを直して, ほぼ完成。 "A First Step" というセクションを書いたので, 使ってみたい方は試してみてください。
サンプルファイル train が付属しているので, C言語版の場合は
% make
% ./lda -N 20 train model
のようにすれば使えます。 一つだけ注: 工藤君の plsi を使っていた方は, 基本的にそのまま使えますが (ということを意識して作ってある), featureのIDが 1始まり になっています (SVMlightと同じ。MATLAB版との整合性の意味もあります。)
feature.c で id = atoi(lp) - 1; となっている所を直せば使えるかも知れませんが, awk 等を使って1始まりに直すのがお薦めだと思う。

"Note"に書いたけど, 完成してからたまたま Google で検索していて, ほとんど同じ時期に Blei 自身がパッケージ LDA-C を公開しているのに気付いた。
ただ, 試してみると, かなり遅く感じる。具体的には, Cranfield 1397記事に対して, 同じ条件で(iteration の数を揃えているので, 少し速め),

という感じで, lda の方がほぼ10倍くらい速い。lda は必要な内部バッファの最大値 をあらかじめ確保して内部のVB-EMにポインタで渡しているのに対して, LDA-C は 毎回必要なだけ malloc で確保しているみたいなので, その辺が速度に効いている のかも。
もっと大きなデータを扱うことを考えるとこの速度差はかなり致命的になるので, やっぱり自分で実装して良かった模様。 まあ, もともと自分の理解を深める, という意味もあるのでどちらにしても いいんだけど。
もう一つは (Webには書いていないが),
lda-c% ./lda est 0.01 20 mysettings train random logs
lda-c% cat logs/011.other
num_topics 20
num_terms 1325
alpha 4.6451764357
という感じで, どうもトピックの prior を均一な分布にして (Dir(α00,..,α0) ということ)絶対値だけ推定しているような模様。最近の nonparametric Bayes の方向を考えると, これはちょっと?が付く感じ。 (Bleiがそのことを知らないはずはないので, 何か考えがあるのかも知れないけれど。)

#2 inf/nan

digamma(Ψ), trigamma(Ψ')の実装は Minka の書いたものを使わせてもらって いるのだけど, 最初に置いておいたコードをコンパイルした人がいたら わかるように, gamma.c をコンパイルする所で warning が出ます (実際には全く問題ありません)。
この原因は, Ψ関数は負の整数値に対しては∞を返すため (cf. Mathworld/Digamma ), 次のコードが含まれていること。
static const double neginf = - 1.0/0;
調べてみると, このコードは gcc 2.95 では通るが, gcc 3.2以降では warning を吐く 模様。
少し調べた結果, 次のように書くとそのまま通ることがわかった。
static const double neginf = - 1.0/0.0;
0 は自動的に double に型変換されるので上でもいいはずなのだけど, 下のように /0.0 と double で割っている場合は自然な結果として, あるいは意図的に∞を返す のであろうのに対して, 上の場合はコーディングミスであることが多かろう ということではないか, という予想。 Minka が書いた時は gcc 2.95以前だったので, 警告にならなかったのかも。
他でも nan を返す所で, return 0.0/0.0; とすることで warning が出なくなった。

というわけで, Cで数学的な性質上∞や不定値を返さなければいけない場合 (わかりやすい例だと, tan(x) で x = π/2 + nπ の場合など)では,

#define inf  (1.0/0.0)
#define nan  (0.0/0.0)
としておけば使えるようです。


2004年11月21日() [n年日記]

#1 LOO keyword

岡野原さんの日記 で, 「文書を代表する単語をとる」という話があって面白いと思うのだけど,
めきめきと有力候補となってきたのが文書を代表する単語をとる学習器作成と
それによる極少数のfeatureによる文書分類。
ちょっと考えたらとりあえずできることに気付いた。

基本は, 「その単語を外したらどうなるか (Leave-one-out)」を考えること。 その際に, 何らかの評価値を最大化するような語を探す。

classification でやるなら, その語がある文書で出なかった場合, classification error の期待値が最大になるような語を求める, などするのだと思う。

ベイズ的にやるなら, Uber SVM で話した Latent Dirichlet kernel と同じ方法が 使える。ある語 $w$ を外した時に得られるトピックの分布 p(θ|d\w) と, 元のトピック分布 p(θ|d) の KL-divergence が最大になるような語 w を代表語 とすればよい(多分)。
VB-EMをやって得られるトピック分布はその文書の"意味" (という言い方はあまり使いたくないが) のようなものを表しているので, この KL-divergence 最大化は, 「ある語を外した時に文書の"意味"がどれくらい ビット落ちするか」を表していることになる。
技術的に言うと, a とか the のような機能語はどの隠れクラスからも高い確率で 出るので, 外しても事後分布にはほとんど影響しないはず。そういう意味で, このやり方で事後分布を支配するような単語 w がとれる。(回数も事後分布に 関して考慮されるので, salient な語が複数回出現していればそれだけ候補に なりやすいことに注意。)

他にも方法はあるかと思うが, これはかなり自然な方法だと思う。
他にやることがあるので, 僕はやらないけど。


3 days displayed.
タイトル一覧
カテゴリ分類
 なかのひと
Powered by hns-2.10-pl1, HyperNikkiSystem Project