about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/SLP/misc/gener_NMAR_data.m
diff options
context:
space:
mode:
Diffstat (limited to 'sourcecodes/bnt-master/SLP/misc/gener_NMAR_data.m')
-rw-r--r--sourcecodes/bnt-master/SLP/misc/gener_NMAR_data.m290
1 files changed, 290 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/SLP/misc/gener_NMAR_data.m b/sourcecodes/bnt-master/SLP/misc/gener_NMAR_data.m
new file mode 100644
index 00000000..4cff44d6
--- /dev/null
+++ b/sourcecodes/bnt-master/SLP/misc/gener_NMAR_data.m
@@ -0,0 +1,290 @@
+function [data, comp_data, bnet_miss] = gener_NMAR_dataset(bnet_orig, m, bnet_miss, upd)
+% [NMAR_data] = gener_NMAR_data(bnet_miss, length_of_dataset)
+% 
+% this function takes in input a bnet that can be used to generate NMAR data.
+% this bnet bnet_miss can be creating by the function gener_NMAR_bnet.
+%
+% - comp_data (array) is a dataset that was generate by the bnet_orig that you enter in gener_NMAR_bnet
+% - NMAR_data (cell array) is the dataset compdata that was emptyied by the NMAR process encodes in bnet_miss
+%
+% optional :
+% - bnet_miss : an old bnet_miss built by this function
+% - upd==1 if you want to update the bnet_miss
+%
+%  [data, comp_data, bnet_miss] = gener_NMAR_dataset(bnet_orig, m, bnet_miss, upd);
+%
+% version 0.5 : june 8th 2005, olivier.francois@insa-rouen.fr
+%
+% TO DO : 
+%   - allow the combinaison of a missing state of one variable and another state of another variable to have influence
+%   - allow the introduction of new nodes and specify which nodes it influence and which nodes has influence on it (it will also satisfy the first task then)
+%
+
+
+% INIT
+N = size(bnet_orig.dag,2);
+if mod(N,2)~=0, error('The number of nodes must be even'); end
+if nargin<4, upd =0; end
+
+% fisrt rules
+if nargin<3,
+ l1=[]; l2=[]; lp=[]; b=-1;
+ while ~(b==0 | b==1), b = input('Would you like to make a node missing when another one is missing (1 for yes, 0 for no) ?   '); end
+else
+ b=-1;
+ if upd, while ~(b==0 | b==1), b = input('Would you like to add rules (1 for yes, 0 for no) ?   '); end
+   l1=bnet_miss.list{1};
+   l2=bnet_miss.list{2};
+   lp=bnet_miss.list{3}; 
+ else
+   l1=[]; l2=[]; lp=[]; b=-1;
+ end
+end
+ 
+while b==1,
+  n = input('The firts node ?   ');
+  s = input('The node that have to be missing when this one is missing ?   ');
+  p = input('The probability of the second node to be missing ?   ');  
+  l1 = [l1, n]; l2 = [l2, s]; lp=[lp, p]; 
+  b=-1;
+  while ~(b==0 | b==1), b = input('Another one (1 for yes, 0 for no) ?   '); end
+end
+bb = length(l1);
+
+
+if nargin>=3,
+  bnet_miss = gener_NMAR_bnet(upd, bnet_orig, bnet_miss);
+else
+  bnet_miss = gener_NMAR_bnet(1, bnet_orig);
+  bnet_miss.list={l1; l2; lp};
+%%%%%%%%%%% SAVING FILE
+ ss = 1;
+ if nargin == 2 | upd==1, ss = input('Would you like to save the bnet of the NMAR process you have made (1 for yes) ?   '); end
+ if ss == 1,
+  ddd = datestr(now);
+  ddd([12 15 18])='-' ;
+  fnout=['NMAR-bnet-' ddd '.mat'];
+  eval(['save ' fnout ' bnet_miss']); 
+  fprintf(' The bnet for NMAR process was saved as : %s\n',fnout);
+ end
+end %if nargin
+
+% Generation of a complete dataset
+if N>9 & m>2000, disp('  ! It could take a long time...'); end
+data = cell(N,m);
+for l = 1:m, data(:,l) = sample_bnet(bnet_orig); end
+disp('Complete data have been creating.');
+
+% Generation of a NMAR dataset
+miss_array = cell(2*N,m);
+vide = cell(1,N); l= 1;
+while l <= m, 
+  ev(1:N) = data(:,l); ev(N+1:2*N) = vide;
+  miss_array(:,l) = sample_bnet(bnet_miss, 'evidence', ev); 
+  % apply simple rule of missingness
+  ev2 = cell2mat(miss_array(N+1:2*N, l));
+  if bb,
+   missl1 = myintersect(find(ev2==2), l1);
+   if ~isempty(missl1),
+    for i=1:length(l1),
+     if ev2(l1(i))==2, if rand<lp(i), ev2(l2(i))=2; miss_array{N+l2(i),l}=[2]; end, end
+  end, end, end
+  % verification that we have not a completly missing sample
+  ev2 = 3-ev2; 
+  if prod(ev2)==1, fprintf(' - %d, one completly missing sample removed', l); else l=l+1; end 
+  if mod(l,100)==0, fprintf('\n - %d',l); end
+end
+fprintf('\n');
+data = bnt_to_mat(data); comp_data = data;
+miss_array = bnt_to_mat(miss_array(N+1:2*N, :));
+miss_array = 2-miss_array;
+data = data.*miss_array;
+data = mat_to_bnt(data, 0);
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+function bnet_miss = gener_NMAR_bnet(upd, bnet_orig, bnet_miss)
+
+%%%%%%%%%%%% INIT
+dag = bnet_orig.dag;
+N = size(dag,2);
+ns = bnet_orig.node_sizes;
+NN = 0;
+ns_miss = zeros(1,2*N+NN);
+ns_miss(1:N) = ns;
+ns_miss(N+1:2*N) = 2*ones(1,N); % 1= node i-N present, 2= node i-N missing
+  dagm = zeros(2*N,2*N);
+  dagm(1:N,1:N) = dag;
+  dagm(N+1:2*N, N+1:2*N) = dag;
+  dagm(1:N, N+1:2*N) = dag;
+  for i=1:N, dagm(i, i+N)=1; end
+
+%%%%%%%%%%%% NEW NODES
+%  b=-1;
+%  while ~(b==0 | b==1), b = input('Would you like to add new nodes ?   '); end
+%  
+%  if b==1,
+%  NN = -1;
+%  while (NN<0 | round(NN)~=NN), NN = input('How Many ?   '); end
+%  if NN==1, fprintf('New node will be called %d\n',(2*N+1));
+%  else fprintf('New node will be called %d and following numbers\n',(2*N+1)); end
+%  
+%  disp(' !!! Make sur that the dependence you will create will not create cycle in the Bnet used to create NMAR data !!! here is the current DAG');
+%  dagm2 = zeros(2*N+NN, 2*N+NN);
+  dagm2(1:2*N, 1:2*N) = dagm; 
+%  draw_graph(dagm2); drawnow;
+%  clear dagm
+%  
+%  L1={};L2={};
+%  for i=1:NN
+%    fprintf('For the node %d, ',(2*N+i));
+%    L1{i} = input('FROM which nodes will it have influence (sample [3 2]) ?   ');
+%    L2{i} = input('ON which nodes will it have influence (sample [1 4 3]) ?   '); 
+%    ns_miss(2*N+i) = input('What is its size ?   '); 
+%  end
+%  
+%  end
+
+%%%%%%%%%%%% BNET CREATION
+if nargin==2,
+  dag_miss = dagm2;
+  for i=1:NN, dag_miss(L1{i},2*N+i)=1; dag_miss(2*N+i, L2{i})=1; end
+
+  bnet_miss = mk_bnet(dag_miss, ns_miss);
+  CPT = CPT_from_bnet(bnet_orig);
+  for i=1:N
+    bnet_miss.CPD{i} = tabular_CPD (bnet_miss, i, CPT{i}); % error with new nodes
+  end
+elseif nargin==3,
+  ns_miss = bnet_miss.node_sizes;
+  dag_miss = bnet_miss.dag;
+end
+clear dagm2
+order = 1:(2*N+NN);
+
+%%%%%%%%%%%% Base probability of missing value
+if nargin==2, b=1; else b=0; end
+if b==1,
+disp('Probability MUST be between 0 and 1.');
+
+if nargin==2, 
+ p=-1;
+ while p<0 | p>1, p = input('Base probability of a value to be missing ?   '); end
+ for i=1:N
+  fam = find(dag_miss(:,N+i)==1)';
+  semisize = prod(ns_miss(fam)); % as node N+i is binary to say i is present or missing
+  CPT = zeros(1,2*semisize);
+  CPT(1:semisize) = 1-p;
+  CPT(semisize+1:2*semisize) = p;
+  bnet_miss.CPD{N+i} = tabular_CPD (bnet_miss, N+i, CPT);
+ end
+end
+end
+
+b=-1;
+while ~(b==0 | b==1), b = input('Would you like to change a probability of a node to be missing (1 for yes, 0 for no) ?   '); end
+if b, disp(' BE CAREFULL !! New rules can overwrite old ones partialy or fully !! So the order of entries is important'); end
+
+%%%%%%%%%%%% Update CPT with NMAR process
+while b
+  fprintf('Nodes are from 1 to %d. ',N);
+  i=0;
+  while i<1 | i>N | round(i)~=i, i = input('Which node ?   '); end
+  fam = find(dag(:,i)==1)'; 
+  fam_miss = find(dag_miss(:,N+i)==1)';
+  cas = -ones(1, length(fam_miss)+1);
+  familly = [fam_miss, N+i];
+  fprintf('States are from 1 to %d (-1 for any states, -2 to cancel). For which state of the variable %d ?', ns(i), i);
+  state=-3;
+  while state<-2 | state>ns(i) | round(state)~=state | state==0, state  = input('   ');end
+  if isempty(fam),
+    if state==-1,
+      p=-1;
+      while p<0 | p>1, p = input(' - A priori probability for this node to be missing ?   ');end
+      semisize = prod(ns_miss(fam_miss));
+      CPT = zeros(1,2*semisize);
+      CPT(1:semisize) = 1-p;
+      CPT(semisize+1:2*semisize) = p;
+      bnet_miss.CPD{N+i} = tabular_CPD (bnet_miss, N+i, CPT);
+    elseif state~=-2
+      cas = state;
+      CPT = CPT_from_bnet(bnet_miss);
+      CPT = CPT{N+i};
+      p=-1;
+      while p<0 | p>1, p = input(' - A priori probability for this node to be missing in this state ?   ');end
+      ind = subv2ind(ns_miss(familly),[cas, 1]);
+      CPT(ind)=1-p;
+      ind = subv2ind(ns_miss(familly),[cas, 2]);
+      CPT(ind)=p;
+      bnet_miss.CPD{N+i} = tabular_CPD (bnet_miss, N+i, CPT);      
+    end
+  else 
+   if state>-2,
+    siz=length(cas);
+    place = find(fam_miss==i);
+    cas(place) = state;
+    
+    for k = fam, 
+        state=-3;
+        fprintf(' - For the parent named %d, states are from 1 to %d (-1 for any states of this parent). ',k, ns(k));
+        while state<0 | state>ns(k) | round(state)~=state, state  = input('Which state ?   ');end
+        %if state==0,
+        %  place = find(fam_miss==(fam_miss(k)+N));
+        %  cas(place) = 2;                   % Missing
+        %elseif state==-2,                   % a changer ???
+        %  disp(' This case is buggy, taking missing state instand to minimise influence.');
+        %  place = find(fam_miss==(fam_miss(k)+N));
+        %  cas(place) = 2;  
+        %elseif state~=0 & state~=-2, 
+          place = find(fam_miss==(fam_miss(k)));
+          cas(place) = state;               % Present
+          if state~=-1; place = find(fam_miss==(fam_miss(k)+N)); cas(place) = 1; end 
+        %end
+      end
+    
+    p=-1;
+    while p<0 | p>1, p = input('Probability in this case of the value to be missing ?   ');end
+    CPT = CPT_from_bnet(bnet_miss);
+    CPT = CPT{N+i};
+    
+    cas(end) = 1; % i is present
+    subcas_names = find(cas==-1);
+    if isempty(subcas_names),
+      ind = subv2ind(ns_miss(familly),cas);
+      CPT(ind) = 1-p;
+    else
+      subcas = ones(1, length(subcas_names));
+      continu = 1;
+      while continu
+        cas(subcas_names) = subcas;
+        ind = subv2ind(ns_miss(familly),cas);
+        CPT(ind) = 1-p;
+        [subcas, continu] = next_case(subcas, ns_miss(familly(subcas_names)));
+      end
+    end
+      
+    cas(end)=2; % i is missing
+    if isempty(subcas_names),
+      ind = subv2ind(ns_miss(familly),cas);
+      CPT(ind) = p;
+    else
+      subcas = ones(1, length(subcas_names));
+      continu = 1;
+      while continu
+        cas(subcas_names) = subcas;
+        ind = subv2ind(ns_miss(familly),cas);
+        CPT(ind) = p;
+        [subcas, continu] = next_case(subcas, ns_miss(familly(subcas_names)));
+      end
+    end
+    mass = sum(CPT, length(size(CPT)));
+    while length(size(mass))>2, mass = prod(mass, length(size(mass))); end
+    mass = prod(prod(mass));
+    if mass~=1, disp('not a proba...'); end
+    bnet_miss.CPD{N+i} = tabular_CPD (bnet_miss, N+i, CPT);
+   end %if state~=-2 for the node
+  end %if isempty(fam),
+  b=-1;
+  while ~(b==0 | b==1), b = input('Would you like to change a probability of a node to be missing (1 for yes, 0 for no) ?   ');end
+end
+