This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/prism/exs/noisy_or/alarm_nor_basic.psm

161 lines
5.2 KiB
Plaintext

%%%%
%%%% Bayesian networks using noisy OR (1) -- alarm_nor_basic.psm
%%%%
%%%% Copyright (C) 2004,2006,2007,2008
%%%% Sato Laboratory, Dept. of Computer Science,
%%%% Tokyo Institute of Technology
%% This example is borrowed from:
%% Poole, D., Probabilistic Horn abduction and Bayesian networks,
%% In Proc. of Artificial Intelligence 64, pp.81-129, 1993.
%%
%% (Fire) (Tampering)
%% / \ /
%% ((Smoke)) (Alarm)
%% |
%% (Leaving) (( )) -- observable node
%% | ( ) -- hidden node
%% ((Report))
%%
%% In this network, we assume that all rvs (random variables) take on
%% {yes,no} and also assume that only two nodes, `Smoke' and `Report', are
%% observable.
%%
%% Furthermore, in this program, we consider that the Alarm variable's CPT
%% (conditional probability table) given through the noisy-OR rule. That is,
%% let us assume that we have the following inhibition probabilities:
%%
%% P(Alarm=no | Fire=yes, Tampering=no) = 0.3
%% P(Alarm=no | Fire=no, Tampering=yes) = 0.2
%%
%% The CPT for the Alarm variable is then constructed from these inhibition
%% probabilities and the noisy-OR rule:
%%
%% +------+-----------+--------------------+----------------+
%% | Fire | Tampering | P(Alarm=yes) | P(Alarm=no) |
%% +------+-----------+--------------------+----------------+
%% | yes | yes | 0.94 = 1 - 0.3*0.2 | 0.06 = 0.3*0.2 |
%% | yes | no | 0.7 = 1 - 0.3 | 0.3 |
%% | no | yes | 0.8 = 1 - 0.2 | 0.2 |
%% | no | no | 0 | 1.0 |
%% +------+-----------+--------------------+----------------+
%%
%% cpt_al/3 in this program implements the above CPT with random switches.
%% The key step is to consider the generation process underlying the noisy-OR
%% rule. One may notice that this program is written in a network-specific
%% form, but a more generic, network-independent program is given in
%% alarm_nor_generic.psm.
%%
%% Please note that this program shares a considerably large part with
%% ../alarm.psm, so some comments are omitted for simplicity.
%%-------------------------------------
%% Quick start:
%%
%% ?- prism(alarm_nor_basic).
%%
%% Print the CPT of the Alarm variable constructed from the noisy OR rule:
%% ?- print_dist_al.
%%
%% Print logical formulas that express the probabilistic behavior of
%% the noisy OR rule for Alarm:
%% ?- print_expl_al.
%%
%% Get the probability and the explanation graph:
%% ?- prob(world(yes,no)).
%% ?- probf(world(yes,no)).
%%
%% Get the most likely explanation and its probability:
%% ?- viterbif(world(yes,no)).
%% ?- viterbi(world(yes,no)).
%%
%% Compute conditional hindsight probabilities:
%% ?- chindsight(world(yes,no),world(_,_,_,_,_,_)).
%% ?- chindsight_agg(world(yes,no),world(_,_,query,yes,_,no)).
%%
%% Learn parameters from randomly generated 100 samples
%% ?- alarm_learn(100).
go:- alarm_learn(100).
%%-------------------------------------
%% Declarations:
values(_,[yes,no]).
%%------------------------------------
%% Modeling part:
world(Sm,Re):- world(_,_,_,Sm,_,Re).
world(Fi,Ta,Al,Sm,Le,Re) :-
cpt_fi(Fi), % P(Fire)
cpt_ta(Ta), % P(Tampering)
cpt_sm(Fi,Sm), % CPT P(Smoke | Fire)
cpt_al(Fi,Ta,Al), % CPT P(Alarm | Fire,Tampering)
cpt_le(Al,Le), % CPT P(Leaving | Alarm)
cpt_re(Le,Re). % CPT P(Report | Leaving)
cpt_fi(Fi):- msw(fi,Fi).
cpt_ta(Ta):- msw(ta,Ta).
cpt_sm(Fi,Sm):- msw(sm(Fi),Sm).
cpt_al(Fi,Ta,Al):- % implementation of noisy OR:
( Fi = yes, Ta = yes ->
msw(cause_al_fi,N_Al_Fi),
msw(cause_al_ta,N_Al_Ta),
( N_Al_Fi = no, N_Al_Ta = no -> Al = no
; Al = yes
)
; Fi = yes, Ta = no -> msw(cause_al_fi,Al)
; Fi = no, Ta = yes -> msw(cause_al_ta,Al)
; Fi = no, Ta = no -> Al = no
).
cpt_le(Al,Le):- msw(le(Al),Le).
cpt_re(Le,Re):- msw(re(Le),Re).
%%------------------------------------
%% Utility part:
alarm_learn(N) :-
unfix_sw(_), % Make all parameters changeable
set_params, % Set parameters as you specified
get_samples(N,world(_,_),Gs), % Get N samples
fix_sw(fi), % Preserve the parameter values
learn(Gs). % for {msw(fi,yes), msw(fi,no)}
set_params :-
set_sw(fi,[0.1,0.9]),
set_sw(ta,[0.15,0.85]),
set_sw(sm(yes),[0.95,0.05]),
set_sw(sm(no),[0.05,0.95]),
set_sw(le(yes),[0.88,0.12]),
set_sw(le(no),[0.01,0.99]),
set_sw(re(yes),[0.75,0.25]),
set_sw(re(no),[0.10,0.90]),
set_sw(cause_al_fi,[0.7,0.3]), % switch for an inhibition prob
set_sw(cause_al_ta,[0.8,0.2]). % switch for an inhibition prob
:- set_params.
%% Check routine for Noisy-OR
print_dist_al:-
set_params,
( member(Fi,[yes,no]),
member(Ta,[yes,no]),
member(Al,[yes,no]),
prob(cpt_al(Fi,Ta,Al),P),
format("P(al=~w | fi=~w, ta=~w):~t~6f~n",[Al,Fi,Ta,P]),
fail
; true
).
print_expl_al:-
set_params,
( member(Fi,[yes,no]),
member(Ta,[yes,no]),
member(Al,[yes,no]),
probf(cpt_al(Fi,Ta,Al)),
fail
; true
).