2

Jurafsky + Martin のSpeech and Language Processing (第 2 版) に示されているように、品詞タガーとして forward-backward/Baum-Welch アルゴリズムを実装しています。私のコードは大まかに次のように構成されています。

#Initialize transition probability matrix A and observation likelihood matrix B
(A,B) = init() #Assume this is correct

#Begin forward-backward/Baum-Welch algorithm
for training_sentence in training_data:
    (A,B) = forward_backward(A,B,training_sentence, vocabulary, hidden_state_set)

#Use new A,B to test
i = 0
for test_sentence in test_data:
    predicted_tag_sequence = viterbi(test_sentence, vocabulary, A,B)
    update_confusion_matrix(predicted_tag_sequence, actual_tag_sequences[i])
    i += 1

私の実装では、forward_backward を呼び出す前に A と B を初期化します。次に、forward_backward の各反復で使用される A、B は、前の反復から計算された A、B です。

私が見ている2つの問題があります:

  1. 最初の反復の後、 A と B は非常にまばらであるため、 forward_backward の将来の反復では、期待値の最大化手順は実行されません。
  2. 最後の A と B は非常にまばらであるため、Viterbi を適用すると、すべての単語に任意のタグが割り当てられます (A と B は非常にまばらであるため、文のほぼすべてのタグのシーケンスの確率は 0 です)。

私は何が間違っているのでしょうか?私の最大の懸念は理論的なものです。前の反復からの A、B で forward_backward を呼び出すのは正しいですか? または、 forward_backward のすべての反復で最初の A、B を使用して、最終的な A、B を結果の平均として使用する必要がありますか? 私のコードが理論的には問題ない場合、他に何が間違っている可能性がありますか?

4

2 に答える 2

3

いいえ、各文の後で A および B マトリックスを更新するべきではありません。A と B は、トレーニング データのパスごとに 1 回だけ更新する必要があります。前の反復の A と B を使用して各文から部分的なカウントを計算し、それらのカウントを合計して、次の次のデータ パスの新しい A と B を取得する必要があります。

手順は次のとおりです。

  1. A と B を初期化する
  2. 各文について、前方後方を使用して期待カウントを計算します
  3. 予想されるカウントを合計して、次の A と B を取得します
  4. 収束するまで手順 2 と 3 を繰り返します。
于 2012-11-15T17:14:02.410 に答える
2

数値の問題である可能性があります。あなたの中で、forward_backwardあなたはおそらくたくさんの小さな数を掛け合わせているでしょう、それは最終的に製品を機械の精度よりも小さくします。その場合は、ログの操作を試すことができます。'raw'確率を乗算するのではなく、確率のログを一緒に追加する必要があります。

于 2012-11-12T20:11:48.903 に答える