Debugging 理解Prolog函数,如何间歇打印结果
我正在努力理解以下序言代码:Debugging 理解Prolog函数,如何间歇打印结果,debugging,printing,prolog,nlp,viterbi,Debugging,Printing,Prolog,Nlp,Viterbi,我正在努力理解以下序言代码: 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(PPa
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)).
它是维特比算法的一个实现
我想了解代码中不同位置的数据结构是如何填充的,它们是什么样子的。是否可以在算法中穿插与“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].
在逻辑编程中,使用打印来查看程序中发生了什么是一个坏主意。这主要是因为Prolog回溯到以前创建的选择点,并且可能经过多次相同的打印。在实现Viterbi时,始终使用您将求和的对数概率,而不是相乘时可能变得非常非常小的概率。@TudorBerariu感谢您的见解,我甚至没有考虑它。说到Prolog,我几乎是一个完全的新手。你能建议我用其他方法解构这个程序来理解它的组成部分吗?我建议你把事实简化一点:只保留两个或三个隐藏状态及其相应的跃迁和发射概率分布。然后,您可以使用trace/0查看Prolog如何满足您的目标。@TudorBerariu这绝对是个好主意。我在想,我还可以向Prolog引擎提出一些其他查询,这些查询可以告诉我一些其他信息,例如,我在原始问题中包含的查询告诉我序列,尽管我猜我也可以让Prolog告诉我序列和该序列的确切数字概率,我想它会保存为列表索引的键,不是吗?你知道如何最好地表达这样的疑问吗?或者,您可能知道还有什么可能是向Prolog提出的有用查询。