Prolog HMM Tagger,语法错误,程序结构有问题

Prolog HMM Tagger, syntax error, questionable program structure

我正在尝试按照一个看似非常简单的教程在 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 包含的 link 将显示 Viterbi 标注器,它表面上与我要实现的 HMM 非常相似,但确切地说 HMM 位于'More...' 小节下的那个页面,在 link 之后显示 "There is a short paper describing the implementation in more detail".

正如@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]

难不成跟这个有关系?

不确定结果有意义(但似乎有意义)

?- 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)).