about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/CPDs
diff options
context:
space:
mode:
authorziejd22018-09-13 23:59:20 -0500
committerziejd22018-09-13 23:59:20 -0500
commite3f7237ffcb19f19db3b68777b5a94b89e07f66a (patch)
tree554a8013776ebeae3e2976074020c09c2d1af8b0 /sourcecodes/bnt-master/BNT/CPDs
parenta7eb61ff7a09f39bee67014bf24b8919eaccfc19 (diff)
downloadBNW-e3f7237ffcb19f19db3b68777b5a94b89e07f66a.tar.gz
New parameter learning options
The main change here is in the parameter learning methods.  The parameters that are learned at first (i.e., if there is no evidence) are the distributions that are found directly in the data. I had to create or significantly modify several BNT files for this.

If there is evidence, the parameters are learned using a Dirichlet prior. This only required a couple of small changes to the BNW parameter learning files.
Diffstat (limited to 'sourcecodes/bnt-master/BNT/CPDs')
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot_orig.m62
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot_orig.m~62
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table_orig.m15
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table_orig.m~15
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT_orig.m5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT_orig.m~5
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/get_field.m1
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params_orig.m20
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params_orig.m~20
-rw-r--r--sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/tabular_CPD.m3
10 files changed, 208 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot_orig.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot_orig.m
new file mode 100644
index 00000000..dadcb033
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot_orig.m
@@ -0,0 +1,62 @@
+function pot = convert_to_pot_orig(CPD, pot_type, domain, evidence, n, ns_current)
+% CONVERT_TO_POT Convert discrete CPD with original distribution to a potential
+% pot = convert_to_pot_orig(CPD, pot_type, domain, evidence, n, ns_current)
+%
+% pots = CPD evaluated using evidence(domain)
+
+ncases = size(domain,2);
+assert(ncases==1); % not yet vectorized
+
+sz = dom_sizes(CPD);
+ns = zeros(1, max(domain));
+ns(domain) = sz;
+
+CPT1 = CPD_to_CPT(CPD);
+spar = issparse(CPT1);
+odom = domain(~isemptycell(evidence(domain)));
+if spar
+   T = convert_to_sparse_table(CPD, domain, evidence);
+else 
+   T = convert_to_table(CPD, domain, evidence);
+end
+
+switch pot_type
+ case 'u',
+  pot = upot(domain, sz, T, 0*myones(sz));  
+ case 'd',
+  CPT_orig = CPD_to_CPT_orig(CPD);
+  pot = dpot(n, ns_current, CPT_orig);          
+ case {'c','g'},
+  % Since we want the output to be a Gaussian, the whole family must be observed.
+  % In other words, the potential is really just a constant.
+  p = T;
+  %p = prob_node(CPD, evidence(domain(end)), evidence(domain(1:end-1)));
+  ns(domain) = 0;
+  pot = cpot(domain, ns(domain), log(p));       
+
+ case 'cg',
+  T = T(:);
+  ns(odom) = 1;
+  can = cell(1, length(T));
+  for i=1:length(T)
+    if T(i) == 0 
+      can{i} = cpot([], [], -Inf); % bug fix by Bob Welch 20/2/04
+    else
+      can{i} = cpot([], [], log(T(i)));
+    end;
+  end
+  pot = cgpot(domain, [], ns, can); 
+  
+ case 'scg'
+  T = T(:);
+  ns(odom) = 1;
+  pot_array = cell(1, length(T));
+  for i=1:length(T)
+    pot_array{i} = scgcpot([], [], T(i));
+  end
+  pot = scgpot(domain, [], [], ns, pot_array);   
+
+ otherwise,
+  error(['unrecognized pot type ' pot_type])
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot_orig.m~ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot_orig.m~
new file mode 100644
index 00000000..ecc57d49
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_pot_orig.m~
@@ -0,0 +1,62 @@
+function pot = convert_to_pot(CPD, pot_type, domain, evidence)
+% CONVERT_TO_POT Convert a discrete CPD to a potential
+% pot = convert_to_pot(CPD, pot_type, domain, evidence)
+%
+% pots = CPD evaluated using evidence(domain)
+
+ncases = size(domain,2);
+assert(ncases==1); % not yet vectorized
+
+sz = dom_sizes(CPD);
+ns = zeros(1, max(domain));
+ns(domain) = sz;
+
+CPT1 = CPD_to_CPT(CPD);
+spar = issparse(CPT1);
+odom = domain(~isemptycell(evidence(domain)));
+if spar
+   T = convert_to_sparse_table(CPD, domain, evidence);
+else 
+   T = convert_to_table(CPD, domain, evidence);
+end
+
+switch pot_type
+ case 'u',
+  pot = upot(domain, sz, T, 0*myones(sz));  
+ case 'd',
+  ns(odom) = 1;
+  pot = dpot(domain, ns(domain), T);          
+ case {'c','g'},
+  % Since we want the output to be a Gaussian, the whole family must be observed.
+  % In other words, the potential is really just a constant.
+  p = T;
+  %p = prob_node(CPD, evidence(domain(end)), evidence(domain(1:end-1)));
+  ns(domain) = 0;
+  pot = cpot(domain, ns(domain), log(p));       
+
+ case 'cg',
+  T = T(:);
+  ns(odom) = 1;
+  can = cell(1, length(T));
+  for i=1:length(T)
+    if T(i) == 0 
+      can{i} = cpot([], [], -Inf); % bug fix by Bob Welch 20/2/04
+    else
+      can{i} = cpot([], [], log(T(i)));
+    end;
+  end
+  pot = cgpot(domain, [], ns, can); 
+  
+ case 'scg'
+  T = T(:);
+  ns(odom) = 1;
+  pot_array = cell(1, length(T));
+  for i=1:length(T)
+    pot_array{i} = scgcpot([], [], T(i));
+  end
+  pot = scgpot(domain, [], [], ns, pot_array);   
+
+ otherwise,
+  error(['unrecognized pot type ' pot_type])
+end
+
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table_orig.m b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table_orig.m
new file mode 100644
index 00000000..92aacc0d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table_orig.m
@@ -0,0 +1,15 @@
+function T = convert_to_table(CPD, domain, evidence)
+% CONVERT_TO_TABLE Convert a discrete CPD to a table with original distribution
+% T = convert_to_table(CPD, domain, evidence)
+%
+% We convert the CPD to a CPT, and then lookup the evidence on the discrete parents.
+% The resulting table can easily be converted to a potential.
+
+domain = domain(:);
+CPT = CPD_to_CPT_orig(CPD);
+odom = domain(~isemptycell(evidence(domain)));
+vals = cat(1, evidence{odom});
+map = find_equiv_posns(odom, domain);
+index = mk_multi_index(length(domain), map, vals);
+T = CPT(index{:});
+T = T(:);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table_orig.m~ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table_orig.m~
new file mode 100644
index 00000000..dc5bcd40
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@discrete_CPD/convert_to_table_orig.m~
@@ -0,0 +1,15 @@
+function T = convert_to_table(CPD, domain, evidence)
+% CONVERT_TO_TABLE Convert a discrete CPD to a table
+% T = convert_to_table(CPD, domain, evidence)
+%
+% We convert the CPD to a CPT, and then lookup the evidence on the discrete parents.
+% The resulting table can easily be converted to a potential.
+
+domain = domain(:);
+CPT = CPD_to_CPT(CPD);
+odom = domain(~isemptycell(evidence(domain)));
+vals = cat(1, evidence{odom});
+map = find_equiv_posns(odom, domain);
+index = mk_multi_index(length(domain), map, vals);
+T = CPT(index{:});
+T = T(:);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT_orig.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT_orig.m
new file mode 100644
index 00000000..707de900
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT_orig.m
@@ -0,0 +1,5 @@
+function CPT = CPD_to_CPT_orig(CPD)
+% CPD_TO_CPT Convert the discrete CPD to tabular form (tabular)
+% CPT = CPD_to_CPT_orig(CPD)
+
+CPT = CPD.CPT_orig;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT_orig.m~ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT_orig.m~
new file mode 100644
index 00000000..351f103c
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/CPD_to_CPT_orig.m~
@@ -0,0 +1,5 @@
+function CPT = CPD_to_CPT(CPD)
+% CPD_TO_CPT Convert the discrete CPD to tabular form (tabular)
+% CPT = CPD_to_CPT(CPD)
+
+CPT = CPD.CPT;
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/get_field.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/get_field.m
index ba233db9..5812330d 100644
--- a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/get_field.m
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/get_field.m
@@ -10,6 +10,7 @@ function val = get_field(CPD, name)
 
 switch name
  case 'cpt',      val = CPD.CPT;
+ case 'cpt_orig',      val = CPD.CPT_orig;
  case 'counts',      val = CPD.counts;
  otherwise,
   error(['invalid argument name ' name]);
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params_orig.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params_orig.m
new file mode 100644
index 00000000..c0948566
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params_orig.m
@@ -0,0 +1,20 @@
+function CPD = learn_params_orig(CPD,j,data,ns,cnodes)
+% LEARN_PARAMS_ORIG
+% Calculate the original distributions of the data.
+%   The original distributions are just the percentages of states in the 
+%        data file.
+
+local_data = data(j, :); 
+nobs = size(local_data,2);
+if iscell(local_data)
+  local_data = cell2num(local_data);
+end
+counts = compute_counts(local_data,ns(j));
+counts = counts/nobs;
+switch CPD.prior_type
+ case 'none', CPD.CPT_orig = counts; 
+% case 'dirichlet', CPD.CPT = mk_stochastic(counts + CPD.dirichlet); 
+% I will use 'dirichlet' priors incorrectly here.
+ case 'dirichlet', CPD.CPT_orig = counts; 
+ otherwise, error(['unrecognized prior ' CPD.prior_type])
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params_orig.m~ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params_orig.m~
new file mode 100644
index 00000000..7a19a42d
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/learn_params_orig.m~
@@ -0,0 +1,20 @@
+function CPD = learn_params_orig(CPD,j,data,data,ns,cnodes)
+% LEARN_PARAMS_ORIG
+% Calculate the original distributions of the data.
+%   The original distributions are just the percentages of states in the 
+%        data file.
+
+local_data = data(j, :); 
+nobs = size(local_data,2);
+if iscell(local_data)
+  local_data = cell2num(local_data);
+end
+counts = compute_counts(local_data,ns(j));
+counts = counts/nobs;
+switch CPD.prior_type
+ case 'none', CPD.CPT_orig = counts; 
+% case 'dirichlet', CPD.CPT = mk_stochastic(counts + CPD.dirichlet); 
+% I will use 'dirichlet' priors incorrectly here.
+ case 'dirichlet', CPD.CPT_orig = counts; 
+ otherwise, error(['unrecognized prior ' CPD.prior_type])
+end
diff --git a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/tabular_CPD.m b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/tabular_CPD.m
index 728302d4..a41a23d9 100644
--- a/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/tabular_CPD.m
+++ b/sourcecodes/bnt-master/BNT/CPDs/@tabular_CPD/tabular_CPD.m
@@ -9,6 +9,7 @@ function CPD = tabular_CPD(bnet, self, varargin)
 %   - T means use table T; it will be reshaped to the size of node's family.
 %   - 'rnd' creates rnd params (drawn from uniform)
 %   - 'unif' creates a uniform distribution
+% CPT_orig - specifies the distribution based on original data
 % adjustable - 0 means don't adjust the parameters during learning [1]
 % prior_type - defines type of prior ['none']
 %  - 'none' means do ML estimation
@@ -60,6 +61,7 @@ CPD.sparse = 0;
 
 % set defaults
 CPD.CPT = mk_stochastic(myrand(fam_sz));
+CPD.CPT_orig = mk_stochastic(myrand(ns([self])));
 CPD.adjustable = 1;
 CPD.prior_type = 'none';
 dirichlet_type = 'BDeu';
@@ -158,6 +160,7 @@ function CPD = init_fields()
 % or create it from scratch. (Matlab requires this.)
 
 CPD.CPT = [];
+CPD.CPT_orig = [];
 CPD.sizes = [];
 CPD.prior_type = [];
 CPD.dirichlet = [];