我正在努力了解以下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)).
这是Viterbi算法的一个实现。
我想了解代码中各个位置的数据结构是如何填充的,它们是什么样的。是否有可能散布相当于' print'算法中的语句让我可以看到每一步发生了什么?我在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].