我正在实现前向后/ Baum-Welch算法,如Jurafsky + Martin的语音和语言处理(第2版)中所示,作为词性标注器。我的代码大致结构如下:
#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。
我遇到过两个问题:
我可能做错了什么?我最关心的是理论:我是否正确使用前一次迭代中的A,B调用forward_backward?或者我应该使用我的初始A,B为forward_backward的所有迭代取我的最终A,B作为平均结果?如果我的代码在理论上很好,还有什么可能是错的?
答案 0 :(得分:3)
不,你不应该在每个句子后更新A和B矩阵;每次通过训练数据时,A和B只应更新一次。您应该使用前一个迭代的A和B来计算每个句子的部分计数,然后对这些计数求和,得到新的A和B,以便下次传递数据。
程序应该是:
答案 1 :(得分:2)
可能是一个数字问题。在你的forward_backward
中,你可能会将一大堆小数字相乘,这最终会使产品小于机器精度。如果是这种情况,您可以尝试使用日志。您应该将概率日志加在一起,而不是将“原始”概率相乘。