音声認識メモ(Julius)その6(連続単語認識(N-gram))

The Julius bookより抜粋。

第1パスでは通常の前向き (left-to-right) の 2-gram,第2パスでは後ろ向きの N-gram がそれぞれ必要となる.

第1パスにおける確率計算の過程をトレースしてみる。
(確率は常用対数での計算になる)

統計の元となるテキストが以下のとおりであったとする。
(音素「i」、「m」、「o」の組み合わせで作成)

<s> IMO MO II </s> 
<s> MOMO MO OMOI </s> 

1行目: 芋 も いい
2行目: 桃 も 重い

統計的言語モデルツールキット「palmkit」を使って、back-off 言語モデルを作成する。

前向き2-gram
\data\
ngram 1=8
ngram 2=9


\1-grams:
-0.25527 <UNK>  0.0000
-1.30643 </s>  -0.2559
-1.00540 <s>  -0.2559
-1.30643 II  -0.2790
-1.30643 IMO  -0.2559
-1.00540 MO  -0.2559
-1.30643 MOMO  -0.2559
-1.30643 OMOI  -0.2790

\2-grams:
-0.30103 </s> <s> 
-0.60206 <s> IMO 
-0.60206 <s> MOMO 
-0.30103 II </s> 
-0.30103 IMO MO 
-0.60206 MO II 
-0.60206 MO OMOI 
-0.30103 MOMO MO 
-0.30103 OMOI </s> 

\end\
後向き3-gram
\data\
ngram 1=8
ngram 2=8
ngram 3=8


\1-grams:
-0.60206 <UNK>  0.0000
-0.90309 </s>  -0.2430
-1.20412 <s>  -0.2430
-1.20412 II  -0.2430
-0.60206 IMO  0.0000
-0.90309 MO  -0.1383
-1.20412 MOMO  -0.2730
-1.20412 OMOI  -0.2430

\2-grams:
-0.60206 </s> II  0.0000
-0.60206 </s> OMOI  0.0000
-0.30103 <s> </s>  -0.1761
-0.30103 II MO  -0.1761
-0.60206 MO IMO  0.0000
-0.60206 MO MOMO  0.0000
-0.30103 MOMO <s>  0.0000
-0.30103 OMOI MO  -0.1761

\3-grams:
-0.30103 </s> II MO 
-0.30103 </s> OMOI MO 
-0.30103 <s> </s> II 
-0.30103 II MO IMO 
-0.30103 MO IMO <s> 
-0.30103 MO MOMO <s> 
-0.30103 MOMO <s> </s> 
-0.30103 OMOI MO MOMO 

\end\

確率の計算は以下のようになる。
f:id:ichou1:20180204214228p:plain

ソースのコメントにあるように、WORD2の条件付き確率は、後向き1-gramのものを使う。

ソースの抜粋(libsent/src/ngram/ngram_access.c)
/** 
 * Get LR bi-gram prob: for RL N-gram with additional LR 2-gram.
 * 
 * @param ndata [in] N-gram data that holds the 2-gram
 * @param w1 [in] left context word
 * @param w2 [in] right target word
 * 
 * @return the log N-gram probability P(w2|w1)
 * 
 */
static LOGPROB
bi_prob_additional(NGRAM_INFO *ndata, WORD_ID w1, WORD_ID w2)
{
    NNID n2;
    LOGPROB prob;

    /* index is RL */
    /* prob is in additional N-gram area */
    if ((n2 = search_bigram(ndata, w2, w1)) != NNID_INVALID) {
        prob = ndata->p_2[n2];
    } else {
        prob = ndata->bo_wt_1[w1] + ndata->d[0].prob[w2];
    }
    if (w2 != ndata->unk_id) {
        return(prob);
    } else {
        return(prob - ndata->unk_num_log);
    }
}