我试图在Prolog中实现一个HMM标记器,并附带一个看似非常简单的教程,找到here。
作为Prolog的完全新手,我无法获得其中描述的结果。
到目前为止,我已经写过数据,即所有数据
outprob(a,det,0.300).
和transprob(start,det,0.30).
到一个文件,此外我还在同一个文件中包含了HMM功能,即
most_probable_sequence(Words,Ss) :-
findall(PS,sequence(Words,1-[start],PS)PSs),
max_key(PSs,P-Ss1),
reverse(Ss1,[start|Ss]).
sequence([],PSs,PSs).
sequence([Word|Words],P1-[S1|Ss],PSs) :-
outprob(Word,S2,Po),
transprob(S1,S2,Pt),
P2 is Po*Pt*P1,
sequence(Words,P2-[S2,S1|Ss],PSs).
我使用['filename.pl'].
命令将文件加载到Prolog中,并收到以下错误消息:
:40:42: Syntax error: Operator expected
是否参考第40和42行?
如果是,那将对应于指定findall(PS,sequence(Words,1-[start],PS)PSs),
和reverse(Ss1,[start|Ss]).
我的直觉是我需要自己定义findall()
和reverse()
的函数,也许再一次在同一个文件中。这是对的吗?
一旦解决了这个问题,我是否可以通过在Prolog界面输入以下命令来找到结果:
?- most_probable_sequence([he,can,can,a,can],Sequence).
PS附带的链接将显示Viterbi标记,表面上非常类似于我试图实现的HMM,但确切地说,HMM位于该页面底部的#3小节下。 ;更多...'按照说&#34的链接;有一篇简短的文章更详细地描述了实施情况"。
答案 0 :(得分:1)
正如@CapelliC指出的那样,错误是一个错字,但事实上,该代码的问题比我最初想象的更加阴险。
现在,在运行代码时,使用更正的拼写错误,会生成一个错误,表示:
ERROR: most_probable_sequence/2: Undefined procedure: max_key/2
接下来是
Exception: (7) max_key([5.103000000002e-13-[aux, det, aux, aux, pron
依此类推,有一系列非常大的数字,然后是一个相关的标签列表。
说第一个错误与输入到most_probable_sequence()函数的输入量有关是否正确?
异常可能是什么原因?这些数字的大小?
*首次加载文件时还会生成警告,其中显示:
:39:
Singleton variables: [P]
这可能与麻烦有关吗?
答案 1 :(得分:1)
不确定结果是否有意义(但似乎确实如此)
?- most_probable_hmm_path([he,can,can,a,can],Sequence).
Sequence = [pron, aux, v, det, n].
这是
的结果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(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)).