基于prolog的信念网络推理
我在最后一个项目的Prolog中有一个问题。我尝试使用贝叶斯网络和prolog对列车系统中断模式进行推理。我的贝叶斯网络如下图所示: 我阅读了Ivan Bratko为Articial Intellegent第三版添加的Prolog编程书籍,发现了如何在Prolog中表示贝叶斯网络。 您可以看到Prolog代码,如下所示:基于prolog的信念网络推理,prolog,bayesian-networks,reasoning,Prolog,Bayesian Networks,Reasoning,我在最后一个项目的Prolog中有一个问题。我尝试使用贝叶斯网络和prolog对列车系统中断模式进行推理。我的贝叶斯网络如下图所示: 我阅读了Ivan Bratko为Articial Intellegent第三版添加的Prolog编程书籍,发现了如何在Prolog中表示贝叶斯网络。 您可以看到Prolog代码,如下所示: %here is the rule for reasoning in bayesian network from the book : prob([X|Xs],Cond,P)
%here is the rule for reasoning in bayesian network from the book :
prob([X|Xs],Cond,P) :- !,
prob(X, Cond, Px),
prob(Xs, [X|Cond], PRest),
P is Px * PRest.
prob([],_,1):- !.
prob(X, Cond, 1) :-
member(X, Cond),!.
prob(X, Cond, 0) :-
member(\+ X, Cond), !.
prob(\+ X, Cond, P) :- !,
prob(X, Cond, P0),
P is 1-P0.
%Use Bayes rule if condition involves a descendant of X
prob(X, Cond0, P):-
delete(Y, Cond0, Cond),
predecessor(X,Y),!, %Y is a descendant of X
prob(X, Cond, Px),
prob(Y, [X|Cond], PyGivenX),
prob(Y, Cond, Py),
P is Px * PyGivenX / Py. %Assuming Py > 0
%Cases when condition does not involves a descendant
prob(X, Cond, P) :-
p(X, P),!. % X a root cause - its probability given
prob(X, Cond, P) :- !,
findall((CONDi, Pi), p(X,CONDi,Pi), CPlist), %Condition on parents
sum_probs(CPlist, Cond, P).
sum_probs([],_,0).
sum_probs([(COND1,P1) | CondsProbs], COND, P) :-
prob(COND1, COND, PC1),
sum_probs(CondsProbs, COND, PRest),
P is P1 * PC1 + PRest.
predecessor(X, \+ Y) :- !, %Negated variable Y
predecessor(X,Y).
predecessor(X,Y) :-
parent(X,Y).
predecessor(X,Z) :-
parent(X,Y),
predecessor(Y,Z).
member(X, [X|_]).
member(X, [_|L]) :-
member(X,L).
delete(X, [X|L], L).
delete(X, [Y|L], [Y|L2]) :-
delete(X, L, L2).
这里还有一些关于在prolog中实现贝叶斯网络信息的例子(我只添加了一些,因为它太长了):
有关完整代码,请参见
不幸的是,当我试图推理一些概率时,我遇到了一个问题,比如:
?- prob(series, [horn], P).
?- prob(series, [brake], P).
?- prob(pantograph, [overhead_line], P).
据说错误是这样的:
ERROR: Arithmetic: evaluation error: `zero_divisor'
ERROR: In:
ERROR: [27] _43124 is 0.045454539961694*0/0
ERROR: [25] prob([compressor],[\+brake,traction|...],_43166) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:2
ERROR: [24] sum_probs([(...,0.026315789),...],[\+brake,traction|...],_43216) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:37
ERROR: [22] prob([horn,door|...],[\+brake,traction|...],_43278) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:2
ERROR: [21] prob([\+brake,horn|...],[traction,wiper|...],_43334) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:3
ERROR: [20] prob([traction,...|...],[wiper,speedometer|...],_43390) at d:/kuliah/tugas/semester 8/for ta/[2] ta program/reasoningtraindisruptionwithprolog/rules.pl:3
有人能帮我纠正这个错误吗?提前感谢。在介绍安全测试之后
...
prob(Y, Cond, Py),
Py > 0,
P is Px * PyGivenX / Py. %Assuming Py > 0
并更正了github代码中的一个输入错误和几个错误,我得到以下结果:
?- prob(series, [horn], P).
false.
?- prob(series, [brake], P).
P = 0.086661842800551.
?- prob(pantograph, [overhead_line], P).
false.
因此,您现在可以试着理解为什么代码会产生
false
而不是p=0.0
。我意识到为什么IntrMeter会产生零除数错误的答案,这是因为当我用:
?- prob(series, [horn], P).
?- prob(series, [brake], P).
?- prob(pantograph, [overhead_line], P)
所有这些都按照规则处理:
prob(X, Cond0, P):-
delete(Y, Cond0, Cond),
predecessor(X,Y),!, %Y is a descendant of X
prob(X, Cond, Px),
prob(Y, [X|Cond], PyGivenX),
prob(Y, Cond, Py),
P is Px * PyGivenX / Py. %Assuming Py > 0
然而,应使用下面的规则处理它们:
prob(X, Cond, P) :-
p(X, P),!. % X a root cause - its probability given
prob(X, Cond, P) :- !,
findall((CONDi, Pi), p(X,CONDi,Pi), CPlist), %Condition on parents
sum_probs(CPlist, Cond, P).
因为查询不涉及X的后代
有没有办法区分这两条规则?因为我以后仍然递归地使用这两个规则
我已经尝试在
prob(X,Cond0,p)
中添加条件parent(X,Cond0)
,但是当我查询条件时涉及到X的后代,答案是错误的您需要检查您的数学。你在除以零。我不认为有人会通过你所有的离线代码为你找到原因。你做了什么调试?我已经用trace来调试了,但是仍然没有找到代码中哪一部分被零除。没有跟踪结果表明它除以零。如果您只是尝试用测试修补有问题的行,会发生什么Py>0,P是Px*PyGivenX/Py。
我还没有看过所有的代码,但也许你可以在调用prob/4
后添加Py>0
,在那里你计算Py
。是的,我添加了Py 0,并创建了一个新的谓词prob/4,它可以工作,非常感谢:)非常感谢你的回答,现在我知道我必须在哪里修复代码:)
prob(X, Cond, P) :-
p(X, P),!. % X a root cause - its probability given
prob(X, Cond, P) :- !,
findall((CONDi, Pi), p(X,CONDi,Pi), CPlist), %Condition on parents
sum_probs(CPlist, Cond, P).