Mercurial > hg > camir-aes2014
comparison toolboxes/FullBNT-1.0.7/bnt/learning/learn_struct_pdag_pc_constrain.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 function [pdag, G] = dn_learn_struct_pdag_pc_constrain(adj, cond_indep, n, k, varargin) | |
2 % LEARN_STRUCT_PDAG_PC Learn a partially oriented DAG (pattern) using the PC algorithm | |
3 % Pdag = learn_struct_pdag_pc_constrain(adj, cond_indep, n, k, ...) | |
4 % | |
5 % adj = adjacency matrix learned from dependency network P(i,j) = 1 => i--j; 0 => i j | |
6 % n is the number of nodes. | |
7 % k is an optional upper bound on the fan-in (default: n) | |
8 % cond_indep is a boolean function that will be called as follows: | |
9 % feval(cond_indep, x, y, S, ...) | |
10 % where x and y are nodes, and S is a set of nodes (positive integers), | |
11 % and ... are any optional parameters passed to this function. | |
12 % | |
13 %Output | |
14 % pdag Partially directed graph | |
15 % G Resulting adjacency graph prior to setting direction arrows | |
16 % | |
17 % The output P is an adjacency matrix, in which | |
18 % P(i,j) = -1 if there is an i->j edge. | |
19 % P(i,j) = P(j,i) = 1 if there is an undirected edge i <-> j | |
20 % | |
21 % The PC algorithm does structure learning assuming all variables are observed. | |
22 % See Spirtes, Glymour and Scheines, "Causation, Prediction and Search", 1993, p117. | |
23 % This algorithm may take O(n^k) time if there are n variables and k is the max fan-in, | |
24 % but this is quicker than the Verma-Pearl IC algorithm, which is always O(n^n). | |
25 % | |
26 %% Example | |
27 %% Given data in a comma separated, filename starting with the variable labels, then the data in rows. | |
28 %% filename test.txt consists of: | |
29 %% | |
30 %% Earthquake,Burglar,Radio,Alarm,Call | |
31 %% 1,2,2,2,1 | |
32 %% 1,1,2,1,2 | |
33 %% . . . | |
34 %[CovMatrix, obs, varfields] = CovMat('test.txt',5); | |
35 % | |
36 %dn = zeros(5,5); | |
37 %dn(1,2) = 1; % This was the known Markov blanket of the system that generated test.txt | |
38 %dn(2,1) = 1; | |
39 %dn(2,4) = 1; | |
40 %dn(4,2) = 1; | |
41 %dn(1,3) = 1; | |
42 %dn(3,1) = 1; | |
43 %dn(1,4) = 1; | |
44 %dn(4,1) = 1; | |
45 %dn(4,5) = 1; | |
46 %dn(5,4) = 1; | |
47 %dn(3,5) = 1; %loop r->c | |
48 %dn(5,3) = 1; %loop c-r | |
49 %dn(3,4) = 1; | |
50 %dn(4,3) = 1; | |
51 % | |
52 %max_fan_in = 4; | |
53 %alpha = 0.05; | |
54 % | |
55 %[pdag G] = learn_struct_pdag_pc_constrain(dn,'cond_indep_fisher_z', 5, max_fan_in, CovMatrix, obs, alpha); | |
56 %% | |
57 %% | |
58 %% Gary Bradski, 7/2002 Modified this to take an adjacency matrix from a dependency network. | |
59 | |
60 | |
61 sep = cell(n,n); | |
62 ord = 0; | |
63 done = 0; | |
64 G = ones(n,n); | |
65 G=setdiag(G,0); | |
66 | |
67 while ~done | |
68 done = 1; | |
69 [X,Y] = find(G); | |
70 for i=1:length(X) | |
71 x = X(i); y = Y(i); | |
72 % nbrs = mysetdiff(myunion(neighbors(G, x), neighbors(G,y)), [x y]);%parents, children, but not self | |
73 nbrs = mysetdiff(myunion(neighbors(adj, x), neighbors(adj,y)), [x y]);%parents, children, but not self | |
74 | |
75 if length(nbrs) >= ord & G(x,y) ~= 0 | |
76 done = 0; | |
77 SS = subsets(nbrs, ord, ord); % all subsets of size ord | |
78 for si=1:length(SS) | |
79 S = SS{si}; | |
80 %if (feval(dsep,x,y,S,adj)) | (feval(cond_indep, x, y, S, varargin{:})) | |
81 if feval(cond_indep, x, y, S, varargin{:}) | |
82 %if isempty(S) | |
83 % fprintf('%d indep of %d ', x, y); | |
84 %else | |
85 % fprintf('%d indep of %d given ', x, y); fprintf('%d ', S); | |
86 %end | |
87 %fprintf('\n'); | |
88 | |
89 % diagnostic | |
90 %[CI, r] = cond_indep_fisher_z(x, y, S, varargin{:}); | |
91 %fprintf(': r = %6.4f\n', r); | |
92 | |
93 G(x,y) = 0; | |
94 G(y,x) = 0; | |
95 adj(x,y) = 0; %make sure found cond. independencies are marked out | |
96 adj(y,x) = 0; | |
97 sep{x,y} = myunion(sep{x,y}, S); | |
98 sep{y,x} = myunion(sep{y,x}, S); | |
99 break; % no need to check any more subsets | |
100 end | |
101 end | |
102 end | |
103 end | |
104 ord = ord + 1; | |
105 end | |
106 | |
107 | |
108 | |
109 | |
110 % Create the minimal pattern, | |
111 % i.e., the only directed edges are V structures. | |
112 | |
113 pdag = G; | |
114 [X, Y] = find(G); | |
115 % We want to generate all unique triples x,y,z | |
116 % This code generates x,y,z and z,y,x. | |
117 for i=1:length(X) | |
118 x = X(i); | |
119 y = Y(i); | |
120 Z = find(G(y,:)); | |
121 Z = mysetdiff(Z, x); | |
122 for z=Z(:)' | |
123 if G(x,z)==0 & ~ismember(y, sep{x,z}) & ~ismember(y, sep{z,x}) | |
124 %fprintf('%d -> %d <- %d\n', x, y, z); | |
125 pdag(x,y) = -1; pdag(y,x) = 0; | |
126 pdag(z,y) = -1; pdag(y,z) = 0; | |
127 end | |
128 end | |
129 end | |
130 | |
131 % Convert the minimal pattern to a complete one, | |
132 % i.e., every directed edge in P is compelled | |
133 % (must be directed in all Markov equivalent models), | |
134 % and every undirected edge in P is reversible. | |
135 % We use the rules of Pearl (2000) p51 (derived in Meek (1995)) | |
136 | |
137 old_pdag = zeros(n); | |
138 iter = 0; | |
139 while ~isequal(pdag, old_pdag) | |
140 iter = iter + 1; | |
141 old_pdag = pdag; | |
142 % rule 1 | |
143 [A,B] = find(pdag==-1); % a -> b | |
144 for i=1:length(A) | |
145 a = A(i); b = B(i); | |
146 C = find(pdag(b,:)==1 & G(a,:)==0); % all nodes adj to b but not a | |
147 if ~isempty(C) | |
148 pdag(b,C) = -1; pdag(C,b) = 0; | |
149 %fprintf('rule 1: a=%d->b=%d and b=%d-c=%d implies %d->%d\n', a, b, b, C, b, C); | |
150 end | |
151 end | |
152 % rule 2 | |
153 [A,B] = find(pdag==1); % unoriented a-b edge | |
154 for i=1:length(A) | |
155 a = A(i); b = B(i); | |
156 if any( (pdag(a,:)==-1) & (pdag(:,b)==-1)' ); | |
157 pdag(a,b) = -1; pdag(b,a) = 0; | |
158 %fprintf('rule 2: %d -> %d\n', a, b); | |
159 end | |
160 end | |
161 % rule 3 | |
162 [A,B] = find(pdag==1); % a-b | |
163 for i=1:length(A) | |
164 a = A(i); b = B(i); | |
165 C = find( (G(a,:)==1) & (pdag(:,b)==-1)' ); | |
166 % C contains nodes c s.t. a-c->ba | |
167 G2 = setdiag(G(C, C), 1); | |
168 if any(G2(:)==0) % there are 2 different non adjacent elements of C | |
169 pdag(a,b) = -1; pdag(b,a) = 0; | |
170 %fprintf('rule 3: %d -> %d\n', a, b); | |
171 end | |
172 end | |
173 end | |
174 | |
175 | |
176 | |
177 |