1

我正在努力理解以下 Prolog 代码:

most_probable_hmm_path(Words,Path) :-
  probable_paths(Words,[1-[start]],PPaths),
  keymax(PPaths,_P-Path1),
  reverse(Path1,[start|Path]).

probable_paths([],PPaths,PPaths).
probable_paths([Word|Words],PPaths0,PPaths) :-
  findall(PPath,
      (outprob(Word,Tag2,PL),
      findall(P2-[Tag2,Tag1|Tags],
          (member(P1-[Tag1|Tags],PPaths0),
          transprob(Tag1,Tag2,PT), 
          P2 is PL*PT*P1),
      AllPaths),
      keymax(AllPaths,PPath)),
  PPaths1),
  probable_paths(Words,PPaths1,PPaths).

keymax(AllPaths,U-V) :-
    aggregate(max(N,P), member(N-P,AllPaths), max(U,V)).

它是维特比算法的实现。

我想了解不同位置的代码中的数据结构是如何填充的,它们是什么样的。是否可以在算法中散布等效的“打印”语句,以便我可以看到每一步发生了什么?我在用 Java 或 Python 编码时经常这样做,我发现它是一种或多或少有用的机制来“了解”程序的内容。

如果您有兴趣,我一直在以以下概率使用它:

outprob(a,det,0.300).
outprob(can,aux,0.010).
outprob(can,v,0.005).
outprob(can,n,0.001).
outprob(he,pron,0.070).

transprob(start,det,0.30).          transprob(v,det,0.36).
transprob(start,aux,0.20).          transprob(v,aux,0.01).
transprob(start,v,0.10).            transprob(v,v,0.01).
transprob(start,n,0.10).            transprob(v,n,0.26).
transprob(start,pron,0.30).         transprob(v,pron,0.36).
transprob(det,det,0.20).            transprob(n,det,0.01).
transprob(det,aux,0.01).            transprob(n,aux,0.25).
transprob(det,v,0.01).              transprob(n,v,0.39).
transprob(det,n,0.77).              transprob(n,n,0.34).
transprob(det,pron,0.01).           transprob(n,pron,0.01).
transprob(aux,det,0.18).            transprob(pron,det,0.01).
transprob(aux,aux,0.10).            transprob(pron,aux,0.45).
transprob(aux,v,0.50).              transprob(pron,v,0.52).
transprob(aux,n,0.01).              transprob(pron,n,0.01).
transprob(aux,pron,0.21).           transprob(pron,pron,0.01).

并像这样检查结果:

?- most_probable_hmm_path([he,can,can,a,can],Sequence).
Sequence = [pron, aux, v, det, n].
4

0 回答 0