簡體   English   中英

了解維特比算法

[英]Understanding the Viterbi algorithm

我一直在尋找Viterbi算法的精確分步示例。

考慮將輸入的句子標記為:

The cat saw the angry dog jump

從這個我想產生最可能的輸出為:

D N V T A N V

我們如何使用維特比算法通過Trigram-HMM獲得以上輸出?

(PS:我正在尋找一個精確的逐步說明,而不是一段代碼或數學表示形式。將所有概率都假定為數字。)

萬分感謝!

對於維特比算法和隱馬爾可夫模型,首先需要轉移概率和發射概率。

在您的示例中,過渡概率為P(D-> N),P(N-> V),發射概率(假設雙鏈模型)為P(D | the),P(N | cat)。

當然,在實際示例中,單詞比貓,鋸等要多得多。您必須遍歷所有訓練數據才能估算出P(D | the),P(N | cat), P(N | car)。 然后,我們使用Viterbi算法查找最可能的標簽序列,例如

D N V T A N V

給出您的觀察。

這是我對Viterbi的實現。

def viterbi(vocab, vocab_tag, words, tags, t_bigram_count, t_unigram_count, e_bigram_count, e_unigram_count, ADD_K):
    vocab_size = len(vocab)
    V = [{}]

    for t in vocab_tag:
        # Prob of very first word
        prob = np.log2(float(e_bigram_count.get((words[0],t),0)+ADD_K))-np.log2(float(e_unigram_count[t]+vocab_size*ADD_K))
        # trigram V[0][0]
        V[0][t] = {"prob": prob, "prev": None}

    for i in range(1,len(words)):
        V.append({})
        for t in vocab_tag:
            V[i][t] =  {"prob": np.log2(0), "prev": None}
        for t in vocab_tag:
            max_trans_prob = np.log2(0);
            for prev_tag in vocab_tag:
                trans_prob = np.log2(float(t_bigram_count.get((t, prev_tag),0)+ADD_K))-np.log2(float(t_unigram_count[prev_tag]+vocab_size*ADD_K))   
                if V[i-1][prev_tag]["prob"]+trans_prob > max_trans_prob:
                    max_trans_prob = V[i-1][prev_tag]["prob"]+trans_prob 
                    max_prob = max_trans_prob+np.log2(e_bigram_count.get((words[i],t),0)+ADD_K)-np.log2(float(e_unigram_count[t]+vocab_size*ADD_K))
                    V[i][t] = {"prob": max_prob, "prev": prev_tag}
    opt = []
    previous = None 
    max_prob = max(value["prob"] for value in V[-1].values())
    # Get most probable state and its backtrack
    for st, data in V[-1].items():
        if data["prob"] == max_prob:
            opt.append(st)
            previous = st
            break
    for t in range(len(V) - 2, -1, -1):
        opt.insert(0, V[t + 1][previous]["prev"])
        previous = V[t][previous]["prev"]
    return opt

我建議您在其中一本可用的書中進行查找,例如Chris Bishop的“模式識別和機器學習”。 維特比算法是一個非常基本的東西,並且在文獻中已經詳細描述了各個級別。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM