From 4a2aa23c5ba40b9adf0d40d418ded27c6937d100 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Fri, 31 Oct 2008 15:11:27 +0000 Subject: [PATCH] more CLP(BN) fixes, add softening option when computing MLE estimators. --- CLPBN/clpbn.yap | 6 ++++- CLPBN/clpbn/examples/School/tables.yap | 17 ------------- CLPBN/clpbn/gibbs.yap | 19 ++++----------- CLPBN/clpbn/matrix_cpt_utils.yap | 16 ++++++------- CLPBN/learning/em.yap | 8 ++++--- CLPBN/learning/learn_utils.yap | 31 ++++++++++++++++++++++-- CLPBN/learning/mle.yap | 33 ++++++-------------------- library/matrix.yap | 2 +- library/matrix/matrix.c | 4 ++-- 9 files changed, 62 insertions(+), 74 deletions(-) diff --git a/CLPBN/clpbn.yap b/CLPBN/clpbn.yap index f1a56d87e..adcf21501 100644 --- a/CLPBN/clpbn.yap +++ b/CLPBN/clpbn.yap @@ -78,7 +78,7 @@ influences/4 ]). -:- dynamic solver/1,output/1,use/1,suppress_attribute_display/1. +:- dynamic solver/1,output/1,use/1,suppress_attribute_display/1, parameter_softening/1. solver(jt). @@ -86,6 +86,7 @@ solver(jt). %output(gviz(user_error)). output(no). suppress_attribute_display(false). +parameter_softening(laplace). clpbn_flag(Flag,Option) :- clpbn_flag(Flag, Option, Option). @@ -111,6 +112,9 @@ clpbn_flag(bnt_model,Before,After) :- clpbn_flag(suppress_attribute_display,Before,After) :- retract(suppress_attribute_display(Before)), assert(suppress_attribute_display(After)). +clpbn_flag(parameter_softening,Before,After) :- + retract(parameter_softening(Before)), + assert(parameter_softening(After)). {Var = Key with Dist} :- diff --git a/CLPBN/clpbn/examples/School/tables.yap b/CLPBN/clpbn/examples/School/tables.yap index c3f9b8878..f2c83cf36 100644 --- a/CLPBN/clpbn/examples/School/tables.yap +++ b/CLPBN/clpbn/examples/School/tables.yap @@ -37,29 +37,12 @@ rating_prob_table([0.9,0.05,0.01, 0.09,0.9,0.09, 0.01,0.05,0.9]). -/* -build_sats_table(LSats, Key, Table) :- - cpt_average(LSats, Key, [h,m,l], AggTable), - { V = tmp1(Key) with AggTable}, - rating_prob_table(SatsTable), - Table = p([h,m,l], SatsTable, [V]). -*/ - build_rating_table(LSats, Key, Table) :- cpt_average(LSats, Key, [h,m,l], 1.00, Table). build_grades_table(LGrades, Key, Table) :- cpt_average(LGrades, Key, [a,b,c,d], 1.00, Table). -/* -build_grades_table(LGrades, Key, Table) :- - cpt_average(LGrades, Key, [a,b,c,d], AggTable), - { V = tmp2(Key) with AggTable}, - rating_prob_table(Tab), - Table = p([a,b,c,d], Tab, [V]). -*/ - - abi_table( _, [0.50, 0.40, 0.10]). diff --git a/CLPBN/clpbn/gibbs.yap b/CLPBN/clpbn/gibbs.yap index 9dde42d8c..416743345 100644 --- a/CLPBN/clpbn/gibbs.yap +++ b/CLPBN/clpbn/gibbs.yap @@ -32,7 +32,7 @@ project_from_CPT/3, reorder_CPT/5, multiply_possibly_deterministic_factors/3, - row_from_possibly_deterministic_CPT/3, + column_from_possibly_deterministic_CPT/3, normalise_possibly_deterministic_CPT/2, list_from_CPT/2]). @@ -88,6 +88,7 @@ initialise(LVs, Graph, GVs, OutputVars, VarOrder) :- graph_representation(LVs, Graph, 0, Keys, TGraph), compile_graph(Graph), topsort(TGraph, VarOrder), +%writeln(TGraph:VarOrder), % show_sorted(VarOrder, Graph), add_all_output_vars(GVs, Keys, OutputVars). @@ -108,7 +109,6 @@ graph_representation([V|Vs], Graph, I0, Keys, TGraph) :- clpbn:get_atts(V,[evidence(_)]), !, clpbn:get_atts(V, [dist(Id,Parents)]), get_possibly_deterministic_dist_matrix(Id, Parents, _, Vals, Table), -matrix:matrix_to_list(Table,T),writeln(T), get_sizes(Parents, Szs), length(Vals,Sz), project_evidence_out([V|Parents],[V|Parents],Table,[Sz|Szs],Variables,NewTable), @@ -238,7 +238,6 @@ mult_list([Sz|Sizes],Mult0,Mult) :- % compile node as set of facts, faster execution compile_var(TotSize,I,_Vals,Sz,CPTs,Parents,_Sizes,Graph) :- TotSize < 1024*64, TotSize > 0, !, -writeln(I), (I=55->assert(a); retractall(a)), multiply_all(I,Parents,CPTs,Sz,Graph). % do it dynamically compile_var(_,_,_,_,_,_,_,_). @@ -247,7 +246,6 @@ multiply_all(I,Parents,CPTs,Sz,Graph) :- markov_blanket_instance(Parents,Graph,Values), ( multiply_all(CPTs,Graph,Probs) -, (a->writeln(Probs);true) -> store_mblanket(I,Values,Probs) ; @@ -272,12 +270,9 @@ fetch_val([_|Vals],I0,Pos) :- I is I0+1, fetch_val(Vals,I,Pos). -:- dynamic a/0. - multiply_all([tabular(Table,_,Parents)|CPTs],Graph,Probs) :- fetch_parents(Parents, Graph, Vals), - row_from_possibly_deterministic_CPT(Table,Vals,Probs0), - (a -> list_from_CPT(Probs0,LProbs0), writeln(s:LProbs0) ; true), + column_from_possibly_deterministic_CPT(Table,Vals,Probs0), multiply_more(CPTs,Graph,Probs0,Probs). fetch_parents([], _, []). @@ -288,12 +283,10 @@ fetch_parents([P|Parents], Graph, [Val|Vals]) :- multiply_more([],_,Probs0,LProbs) :- normalise_possibly_deterministic_CPT(Probs0, Probs), list_from_CPT(Probs, LProbs0), - (a -> writeln(e:LProbs0) ; true), accumulate_up_list(LProbs0, 0.0, LProbs). multiply_more([tabular(Table,_,Parents)|CPTs],Graph,Probs0,Probs) :- fetch_parents(Parents, Graph, Vals), - row_from_possibly_deterministic_CPT(Table, Vals, P0), - (a -> list_from_CPT(P0, L0), list_from_CPT(Probs0, LI), writeln(m:LI:L0) ; true), + column_from_possibly_deterministic_CPT(Table, Vals, P0), multiply_possibly_deterministic_factors(Probs0, P0, ProbsI), multiply_more(CPTs,Graph,ProbsI,Probs). @@ -379,7 +372,7 @@ gen_e0(Sz,[0|E0L]) :- process_chains(0,_,F,F,_,_,Est,Est) :- !. process_chains(ToDo,VarOrder,End,Start,Graph,Len,Est0,Estf) :- -format('ToDo = ~d~n',[ToDo]), +%format('ToDo = ~d~n',[ToDo]), process_chains(Start,VarOrder,Int,Graph,Len,Est0,Esti), % (ToDo mod 100 =:= 1 -> statistics,cvt2problist(Esti, Probs), Int =[S|_], format('did ~d: ~w~n ~w~n',[ToDo,Probs,S]) ; true), ToDo1 is ToDo-1, @@ -407,11 +400,9 @@ do_var(I,Sample,Sample0,Graph) :- ; arg(I,Graph,var(_,_,_,_,_,CPTs,Parents,_,_)), fetch_parents(Parents,I,Sample,Sample0,Bindings), -CPTs=[tabular(T,_,_)|_], matrix:matrix_dims(T,Dims), writeln(I:1:Bindings:Dims), multiply_all_in_context(Parents,Bindings,CPTs,Graph,Vals) ), X is random, -writeln(I:X:Vals), pick_new_value(Vals,X,0,Val), arg(I,Sample,Val). diff --git a/CLPBN/clpbn/matrix_cpt_utils.yap b/CLPBN/clpbn/matrix_cpt_utils.yap index c587bc0df..e0dee8727 100644 --- a/CLPBN/clpbn/matrix_cpt_utils.yap +++ b/CLPBN/clpbn/matrix_cpt_utils.yap @@ -11,10 +11,10 @@ unit_CPT/2, sum_out_from_CPT/4, list_from_CPT/2, - row_from_CPT/3, + column_from_CPT/3, multiply_factors/3, normalise_possibly_deterministic_CPT/2, - row_from_possibly_deterministic_CPT/3, + column_from_possibly_deterministic_CPT/3, multiply_possibly_deterministic_factors/3]). :- use_module(dists, @@ -40,7 +40,7 @@ matrix_to_list/2, matrix_agg_lines/3, matrix_op_to_lines/4, - matrix_row/3]). + matrix_column/3]). init_CPT(List, Sizes, TAB) :- matrix_new(floats, Sizes, List, TAB), @@ -212,12 +212,12 @@ zero_map([]). zero_map([0|Zeros]) :- zero_map(Zeros). -row_from_CPT(CPT, Parents, Row) :- - matrix_row(CPT, Parents, Row), - matrix_to_logs(Row). +col_from_CPT(CPT, Parents, Column) :- + matrix_col(CPT, Parents, Column), + matrix_to_logs(Column). -row_from_possibly_deterministic_CPT(CPT, Parents, Row) :- - matrix_row(CPT, Parents, Row). +column_from_possibly_deterministic_CPT(CPT, Parents, Column) :- + matrix_column(CPT, Parents, Column). multiply_factors(F1, F2, F) :- matrix_op(F1,F2,+,F). diff --git a/CLPBN/learning/em.yap b/CLPBN/learning/em.yap index 30d9456dc..b723cf182 100644 --- a/CLPBN/learning/em.yap +++ b/CLPBN/learning/em.yap @@ -23,7 +23,8 @@ [run_all/1, clpbn_vars/2, normalise_counts/2, - compute_likelihood/3]). + compute_likelihood/3, + soften_sample/2]). :- use_module(library(lists), [member/2]). @@ -65,7 +66,7 @@ init_em(Items, state(AllVars, AllDists, AllDistInstances, MargVars)) :- em_loop(Its, Likelihood0, State, MaxError, MaxIts, LikelihoodF, FTables) :- estimate(State, LPs), maximise(State, Tables, LPs, Likelihood), - writeln(Likelihood:Tables), + writeln(Likelihood:Likelihood0:Tables), ( ( (Likelihood - Likelihood0)/Likelihood < MaxError @@ -152,7 +153,8 @@ compute_parameters([], [], [], Lik, Lik). compute_parameters([Id-Samples|Dists], [Id-NewTable|Tables], Ps, Lik0, Lik) :- empty_dist(Id, Table0), add_samples(Samples, Table0, Ps, MorePs), - normalise_counts(Table0, NewTable), + soften_sample(Table0, SoftenedTable), + normalise_counts(SoftenedTable, NewTable), compute_likelihood(Table0, NewTable, DeltaLik), dist_new_table(Id, NewTable), NewLik is Lik0+DeltaLik, diff --git a/CLPBN/learning/learn_utils.yap b/CLPBN/learning/learn_utils.yap index be0fe4306..a6eaf22dc 100644 --- a/CLPBN/learning/learn_utils.yap +++ b/CLPBN/learning/learn_utils.yap @@ -5,15 +5,23 @@ :- module(clpbn_learn_utils, [run_all/1, clpbn_vars/2, normalise_counts/2, - compute_likelihood/3]). + compute_likelihood/3, + soften_sample/2, + soften_sample/3]). + +:- use_module(library(clpbn), + [clpbn_flag/2]). :- use_module(library(matrix), [matrix_agg_lines/3, matrix_op_to_lines/4, + matrix_agg_cols/3, + matrix_op_to_cols/4, matrix_to_logs/2, matrix_op/4, matrix_sum/2, - matrix_to_list/2]). + matrix_to_list/2, + matrix_op_to_all/4]). :- meta_predicate run_all(:). @@ -50,6 +58,25 @@ get_var_has_same_key([K-V|KVs],K,V,KVs0) :- !, get_var_has_same_key(KVs,K,V,KVs0). get_var_has_same_key(KVs,_,_,KVs). +soften_sample(T0,T) :- + clpbn_flag(parameter_softening, Soften), + soften_sample(Soften, T0, T). + +soften_sample(no,T,T). +soften_sample(m_estimate(M), T0, T) :- + matrix_agg_cols(T0,+,Cols),matrix:matrix_to_list(Cols), writeln(Cols), + matrix_op_to_all(Cols, *, M, R), + matrix_op_to_cols(T0,+,R,T). +soften_sample(auto_m, T0,T) :- + matrix_agg_cols(T0,+,Cols),matrix:matrix_to_list(Cols), writeln(Cols), + matrix_sum(Cols,TotM), + M is sqrt(TotM), + matrix_op_to_all(Cols, *, M, R), + matrix_op_to_cols(T0,+,R,T). +soften_sample(laplace,T0,T) :- + matrix_op_to_all(T0, +, 1, T). + + normalise_counts(MAT,NMAT) :- matrix_agg_lines(MAT, +, Sum), matrix_op_to_lines(MAT, Sum, /, NMAT). diff --git a/CLPBN/learning/mle.yap b/CLPBN/learning/mle.yap index 5a95d2fd2..ce6cd0132 100644 --- a/CLPBN/learning/mle.yap +++ b/CLPBN/learning/mle.yap @@ -14,6 +14,8 @@ :- use_module(library('clpbn/learning/learn_utils'), [run_all/1, clpbn_vars/2, + normalise_counts/2, + soften_table/2, normalise_counts/2]). :- use_module(library('clpbn/dists'), @@ -21,8 +23,7 @@ dist_new_table/2]). :- use_module(library(matrix), - [matrix_inc/2, - matrix_op_to_all/4]). + [matrix_inc/2]). learn_parameters(Items, Tables) :- @@ -89,12 +90,14 @@ compute_tables(Parameters, Sample, NewTables) :- add_priors(Parameters, Tables, NewTables). estimator([], []). -estimator([val(Id,Sample)|Samples], [NewTable|Tables]) :- +estimator([val(Id,Sample)|Samples], [NewDist|Tables]) :- empty_dist(Id, NewTable), id_samples(Id, Samples, IdSamples, MoreSamples), mle([Sample|IdSamples], NewTable), + soften_table(NewTable, SoftenedTable), + normalise_counts(SoftenedTable, NewDist), % replace matrix in distribution - dist_new_table(Id, NewTable), + dist_new_table(Id, NewDist), estimator(MoreSamples, Tables). @@ -108,25 +111,3 @@ mle([Sample|IdSamples], Table) :- mle(IdSamples, Table). mle([], _). -add_priors([], Tables, NewTables) :- - normalise(Tables, NewTables). -add_priors([laplace|_], Tables, NewTables) :- !, - laplace(Tables, TablesI), - normalise(TablesI, NewTables). -add_priors([m_estimate(M)|_], Tables, NewTables) :- !, - add_mestimate(Tables, M, TablesI), - normalise(TablesI, NewTables). -add_priors([_|Parms], Tables, NewTables) :- - add_priors(Parms, Tables, NewTables). - -normalise([], []). -normalise([T0|TablesI], [T|NewTables]) :- - normalise_counts(T0, T), - normalise(TablesI, NewTables). - -laplace([], []). -laplace([T0|TablesI], [T|NewTables]) :- - matrix_op_to_all(T0, +, 1, T), - laplace(TablesI, NewTables). - - diff --git a/library/matrix.yap b/library/matrix.yap index 8ff6fb130..c850b6f60 100644 --- a/library/matrix.yap +++ b/library/matrix.yap @@ -82,7 +82,7 @@ typedef enum { matrix_set_all_that_disagree/5, matrix_expand/3, matrix_select/4, - matrix_row/3 + matrix_column/3 ]). :- load_foreign_files([matrix], [], init_matrix). diff --git a/library/matrix/matrix.c b/library/matrix/matrix.c index 4a627f427..ddb904a78 100644 --- a/library/matrix/matrix.c +++ b/library/matrix/matrix.c @@ -2299,7 +2299,7 @@ matrix_select(void) /* given a matrix M and a set of N-1 dims, get the first dimension */ static int -matrix_row(void) +matrix_column(void) { int size, i, ndims, newdims[1]; int indx[MAX_DIMS]; @@ -2956,7 +2956,7 @@ init_matrix(void) YAP_UserCPredicate("matrix_shuffle", matrix_transpose, 3); YAP_UserCPredicate("matrix_expand", matrix_expand, 3); YAP_UserCPredicate("matrix_select", matrix_select, 4); - YAP_UserCPredicate("matrix_row", matrix_row, 3); + YAP_UserCPredicate("matrix_column", matrix_column, 3); YAP_UserCPredicate("matrix_to_logs", matrix_log_all,1); YAP_UserCPredicate("matrix_to_exps", matrix_exp_all, 1); YAP_UserCPredicate("matrix_to_logs", matrix_log_all2,2);