僕が去年出した無限木構造HMMや教師なし形態素解析が
こちらのページ
で実装されているのを知りました。
iTHMMは自然言語処理の人でも詳しい内容を理解できている人はほとんどいないと
思われるので, 驚き。
iTHMMについて,
こちらで
図入りでものすごく詳しく解説してくれています。嬉しいですね。
実装には前提知識がないと半年以上, 上の記事を書くにも一週間以上かかっている
とのことで, そうだろうなと思います。
途中で出されている2つの疑問について,
- 式(20)と(21)が誤記ではないか?というのは, その通りです。 実装(英語論文を書くまでは公開していない)では, 実際以下のようになっています。
Stickの値を再帰的に減らしているので, 棒の残りが負になることはありません。
#define cons make_pair
double
Node::nu ()
{
pair<double,double> beta;
double a, b, decay = pow (param->lambda, level);
if (!tssb->parent)
{
/* Be(1, gamma) */
a = 1;
b = param->eta * decay;
}
else {
beta = tssb->parent->vsplit (code());
a = tssb->param->alpha * beta.first;
b = tssb->param->alpha * beta.second * decay;
}
return (a + stop) / (a + b + stop + through);
}
pair<double, double>
TSSB::vsplit (vector<int> code)
{
vector<int> here;
return vsplit_ (tree, code, here, 1);
}
pair<double, double>
TSSB::vsplit_ (Node *node, vector<int> &code, vector<int> &here, double stick)
{
int k;
double p = node ? node->nu() : empty->nu (here);
if (code.empty())
{
return cons (stick * p, stick * (1 - p));
}
else {
k = shift (code);
here.push_back (k);
if (node && k < node->children.size())
return vsplit_ (node->children[k],
code, here, stick * (1 - p));
else
return vsplit_ (NULL,
code, here, stick * (1 - p));
}
}
- 式(30)と(31)については, これはStick-breakingをあえてHDPのCRPだと思っている ので, 基底測度の項が必要で, 論文が正しいはずです。
論文には「に比例する」Bernoulli試行と書いてあるのがポイントで,
この二つの値の和が直接1になる必要はありません。
ちょうどiTHMMをガウス分布に対応させるコードを書いていたところだったので
(TACL等でこれまで時間がなかった), 非常に驚きました。
他にも多数の実装が公開されているようで, 素晴らしいですね。