aGrUM 3.2.0
a C++ library for (probabilistic) graphical models
BNLearner_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
41#pragma once
42
43
52#include <fstream>
53
54#include <agrum/BN/learning/BNLearner.h> // to ease IDE parser
55
56#ifndef DOXYGEN_SHOULD_SKIP_THIS
57
58// to help IDE parser
61
62namespace gum {
63
64 namespace learning {
65 template < GUM_Numeric GUM_SCALAR >
66 BNLearner< GUM_SCALAR >::BNLearner(std::string_view filename,
67 const std::vector< std::string >& missingSymbols,
68 const bool induceTypes) :
69 IBNLearner(filename, missingSymbols, induceTypes) {
70 GUM_CONSTRUCTOR(BNLearner);
71 }
72
73 template < GUM_Numeric GUM_SCALAR >
74 BNLearner< GUM_SCALAR >::BNLearner(const DatabaseTable& db) : IBNLearner(db) {
75 GUM_CONSTRUCTOR(BNLearner);
76 }
77
78 template < GUM_Numeric GUM_SCALAR >
79 BNLearner< GUM_SCALAR >::BNLearner(std::string_view filename,
81 const std::vector< std::string >& missing_symbols) :
82 IBNLearner(filename, bn, missing_symbols) {
83 GUM_CONSTRUCTOR(BNLearner);
84 }
85
87 template < GUM_Numeric GUM_SCALAR >
88 BNLearner< GUM_SCALAR >::BNLearner(const BNLearner< GUM_SCALAR >& src) : IBNLearner(src) {
89 GUM_CONSTRUCTOR(BNLearner);
90 }
91
93 template < GUM_Numeric GUM_SCALAR >
94 BNLearner< GUM_SCALAR >::BNLearner(BNLearner< GUM_SCALAR >&& src) : IBNLearner(src) {
95 GUM_CONSTRUCTOR(BNLearner);
96 }
97
99 template < GUM_Numeric GUM_SCALAR >
100 BNLearner< GUM_SCALAR >::~BNLearner() {
101 GUM_DESTRUCTOR(BNLearner);
102 }
103
105
106 // ##########################################################################
108 // ##########################################################################
110
112 template < GUM_Numeric GUM_SCALAR >
116 return *this;
117 }
118
120 template < GUM_Numeric GUM_SCALAR >
123 IBNLearner::operator=(std::move(src));
124 return *this;
125 }
126
128 template < GUM_Numeric GUM_SCALAR >
129 BayesNet< GUM_SCALAR > BNLearner< GUM_SCALAR >::learnBN() {
130 // create the score, the prior and the estimator
131 auto notification = checkScorePriorCompatibility();
132 if (notification != "") { std::cout << "[aGrUM notification] " << notification << std::endl; }
133 createPrior_();
134 createScore_();
135
136 std::unique_ptr< ParamEstimator > param_estimator(
137 createParamEstimator_(scoreDatabase_.parser(), true));
138
139 return dag2BN_.createBN< GUM_SCALAR >(*(param_estimator.get()), learnDag_());
140 }
141
142 // check that the database contains the nodes of the dag, else raise an exception
143 template < GUM_Numeric GUM_SCALAR >
145 // if the dag contains no node, this is compatible with the database
146 if (dag.size() == 0) return;
147
148 // check that the dag corresponds to the database
149 std::vector< NodeId > ids;
150 ids.reserve(dag.sizeNodes());
151 for (const auto node: dag)
152 ids.push_back(node);
153 std::sort(ids.begin(), ids.end());
154
155 if (ids.back() >= scoreDatabase_.names().size()) {
156 std::string str = "Learning parameters corresponding to the dag is impossible "
157 "because the database does not contain the following nodeID";
158 std::vector< NodeId > bad_ids;
159 for (const auto node: ids) {
160 if (node >= scoreDatabase_.names().size()) bad_ids.push_back(node);
161 }
162 if (bad_ids.size() > 1) str += 's';
163 str += ": ";
164 bool deja = false;
165 for (const auto node: bad_ids) {
166 if (deja) str += ", ";
167 else deja = true;
168 str += std::to_string(node);
169 }
170 GUM_ERROR(MissingVariableInDatabase, str)
171 }
172 }
173
174 // learns a BN (its parameters) using a basic learning when its structure is known
175 template < GUM_Numeric GUM_SCALAR >
176 BayesNet< GUM_SCALAR > BNLearner< GUM_SCALAR >::_learnParameters_(const DAG& dag,
177 bool takeIntoAccountScore) {
178 // if the dag contains no node, return an empty BN
179 if (dag.size() == 0) return BayesNet< GUM_SCALAR >();
180
181 // be sure that the database contains dag's node ids
182 _checkDAGCompatibility_(dag);
183
184 // create the prior
185 createPrior_();
186
187 // check that the database does not contain any missing value
188 if (scoreDatabase_.databaseTable().hasMissingValues()
189 || ((priorDatabase_ != nullptr)
190 && (priorType_ == BNLearnerPriorType::DIRICHLET_FROM_DATABASE)
191 && priorDatabase_->databaseTable().hasMissingValues())) {
192 GUM_ERROR(MissingValueInDatabase,
193 "In general, the BNLearner is unable to cope with "
194 << "missing values in databases. To learn parameters in "
195 << "such situations, you should first use method " << "useEM()");
196 }
197
198 // create the usual estimator
199 DBRowGeneratorParser parser(scoreDatabase_.databaseTable().handler(), DBRowGeneratorSet());
200 std::unique_ptr< ParamEstimator > param_estimator(
201 createParamEstimator_(parser, takeIntoAccountScore));
202
203 return dag2BN_.createBN< GUM_SCALAR >(*(param_estimator.get()), dag);
204 }
205
206 // initialize the parameter learning by EM
207 // GCC 16 false positive: VRP inlines shared_ptr<ParamEstimator> control block and
208 // incorrectly reports -Warray-bounds on the mutex; #pragma GCC diagnostic cannot
209 // suppress warnings whose primary location is in system headers (stl_construct.h),
210 // so we disable VRP for this function via optimize pragma instead
211# if defined(__GNUC__) && !defined(__clang__)
212# pragma GCC push_options
213# pragma GCC optimize("no-tree-vrp")
214# endif
215
216 template < GUM_Numeric GUM_SCALAR >
217 std::pair< std::shared_ptr< ParamEstimator >, std::shared_ptr< ParamEstimator > >
219 bool takeIntoAccountScore) {
220 // be sure that the database contains dag's node ids
221 _checkDAGCompatibility_(dag);
222
223 // create the prior
224 createPrior_();
225
226 // propagate the messages of dag2BN_ to the BNLearner so that the objects that listen
227 // to the BNLearner can be informed of the progress of the EM's execution by dag2BN_
228 // BNLearnerListener listener(this, dag2BN_);
229
230 // get the column types
231 const auto& database = scoreDatabase_.databaseTable();
232 const std::size_t nb_vars = database.nbVariables();
233 const std::vector< gum::learning::DBTranslatedValueType > col_types(
234 nb_vars,
236
237 // create the bootstrap estimator
238 DBRowGenerator4CompleteRows generator_bootstrap(col_types);
239 DBRowGeneratorSet genset_bootstrap;
240 genset_bootstrap.insertGenerator(generator_bootstrap);
241 DBRowGeneratorParser parser_bootstrap(database.handler(), genset_bootstrap);
242 std::shared_ptr< ParamEstimator > param_estimator_bootstrap(
243 createParamEstimator_(parser_bootstrap, takeIntoAccountScore));
244
245 // create the EM estimator
246 BayesNet< GUM_SCALAR > dummy_bn;
247 DBRowGeneratorEM< GUM_SCALAR > generator_EM(col_types, dummy_bn);
248 DBRowGenerator& gen_EM = generator_EM; // fix for g++-4.8
249 DBRowGeneratorSet genset_EM;
250 genset_EM.insertGenerator(gen_EM);
251 DBRowGeneratorParser parser_EM(database.handler(), genset_EM);
252 std::shared_ptr< ParamEstimator > param_estimator_EM(
253 createParamEstimator_(parser_EM, takeIntoAccountScore));
254
255 return {param_estimator_bootstrap, param_estimator_EM};
256 }
257
258# if defined(__GNUC__) && !defined(__clang__)
259# pragma GCC pop_options
260# endif
261
262 // learns a BN (its parameters) with EM when its structure is known
263 template < GUM_Numeric GUM_SCALAR >
264 BayesNet< GUM_SCALAR >
266 bool takeIntoAccountScore) {
267 // if the dag contains no node, return an empty BN
268 if (dag.size() == 0) return BayesNet< GUM_SCALAR >();
269
270 // get a pair containing the bootstrap and the EM estimators
271 auto estimators = _initializeEMParameterLearning_(dag, takeIntoAccountScore);
272
273 // perform the EM algorithm
274 return dag2BN_.createBNwithEM< GUM_SCALAR >(*(estimators.first.get()),
275 *(estimators.second.get()),
276 dag);
277 }
278
280 template < GUM_Numeric GUM_SCALAR >
281 BayesNet< GUM_SCALAR >
282 BNLearner< GUM_SCALAR >::_learnParametersWithEM_(const BayesNet< GUM_SCALAR >& bn,
283 bool takeIntoAccountScore) {
284 // if the dag contains no node, return an empty BN
285 if (bn.internalDag().size() == 0) return BayesNet< GUM_SCALAR >();
286
287 // get a pair containing the bootstrap and the EM estimators
288 auto estimators = _initializeEMParameterLearning_(bn.internalDag(), takeIntoAccountScore);
289
290 return dag2BN_.createBNwithEM< GUM_SCALAR >(*(estimators.first.get()),
291 *(estimators.second.get()),
292 bn);
293 }
294
296 template < GUM_Numeric GUM_SCALAR >
297 BayesNet< GUM_SCALAR > BNLearner< GUM_SCALAR >::learnParameters(const DAG& dag,
298 bool takeIntoAccountScore) {
299 if (!scoreDatabase_.databaseTable().hasMissingValues() || !useEM_) {
300 // here, we learn without EM
301 return _learnParameters_(dag, takeIntoAccountScore);
302 } else {
303 // here we learn with EM
304 return _learnParametersWithEM_(dag, takeIntoAccountScore);
305 }
306 }
307
309 template < GUM_Numeric GUM_SCALAR >
310 BayesNet< GUM_SCALAR >
311 BNLearner< GUM_SCALAR >::learnParameters(const BayesNet< GUM_SCALAR >& bn,
312 bool takeIntoAccountScore) {
313 if (!scoreDatabase_.databaseTable().hasMissingValues() || !useEM_) {
314 DAG dag;
315 const auto& db = scoreDatabase_.databaseTable();
316 for (const auto n: bn.nodes()) {
317 dag.addNodeWithId(db.columnFromVariableName(bn.variable(n).name()));
318 }
319 for (const auto& arc: bn.arcs()) {
320 dag.addArc(db.columnFromVariableName(bn.variable(arc.tail()).name()),
321 db.columnFromVariableName(bn.variable(arc.head()).name()));
322 }
323
324 // create le DAG en fonction des
325 return _learnParameters_(dag, takeIntoAccountScore);
326 } else {
327 return _learnParametersWithEM_(bn, takeIntoAccountScore);
328 }
329 }
330
332 template < GUM_Numeric GUM_SCALAR >
333 BayesNet< GUM_SCALAR > BNLearner< GUM_SCALAR >::learnParameters(bool take_into_account_score) {
334 return learnParameters(initialDag_, take_into_account_score);
335 }
336
337 template < GUM_Numeric GUM_SCALAR >
339 BNLearner< GUM_SCALAR >::_labelsFromBN_(std::string_view filename,
340 const BayesNet< GUM_SCALAR >& src) {
341 std::ifstream in(std::string(filename), std::ifstream::in);
342
343 if ((in.rdstate() & std::ifstream::failbit) != 0) {
344 GUM_ERROR(gum::IOError, "File " << filename << " not found")
345 }
346
347 CSVParser parser(in, std::string(filename));
348 parser.next();
349 auto names = parser.current();
350
352
353 for (gum::Idx col = 0; col < names.size(); col++) {
354 if (src.exists(names[col])) {
355 gum::NodeId graphId = src.idFromName(names[col]);
356 modals.insert(col, gum::Sequence< std::string >());
357
358 for (gum::Size i = 0; i < src.variable(graphId).domainSize(); ++i)
359 modals[col].insert(src.variable(graphId).label(i));
360 }
361 // else: no problem, a column not in the BN...
362 }
363
364 return modals;
365 }
366
367 template < GUM_Numeric GUM_SCALAR >
368 std::string BNLearner< GUM_SCALAR >::toString() const {
369 const auto st = state();
370
371 Size maxkey = 0;
372 for (const auto& tuple: st)
373 if (std::get< 0 >(tuple).length() > maxkey) maxkey = std::get< 0 >(tuple).length();
374
375 std::string s;
376 for (const auto& tuple: st) {
377 s += std::format("{:<{}} : {}", std::get< 0 >(tuple), maxkey, std::get< 1 >(tuple));
378 if (std::get< 2 >(tuple) != "") s += std::format(" ({})", std::get< 2 >(tuple));
379 s += '\n';
380 }
381 return s;
382 }
383
384 template < GUM_Numeric GUM_SCALAR >
385 std::vector< std::tuple< std::string, std::string, std::string > >
387 std::vector< std::tuple< std::string, std::string, std::string > > vals;
388
389 std::string key;
390 std::string comment;
391 const auto& db = database();
392
393 vals.emplace_back("Filename", filename_, "");
394 vals.emplace_back("Size",
395 "(" + std::to_string(nbRows()) + "," + std::to_string(nbCols()) + ")",
396 "");
397
398 std::string vars = "";
399 for (NodeId i = 0; i < db.nbVariables(); i++) {
400 if (i > 0) vars += ", ";
401 vars += nameFromId(i) + "[" + std::to_string(db.domainSize(i)) + "]";
402 }
403 vals.emplace_back("Variables", vars, "");
404 vals.emplace_back("Induced types", inducedTypes_ ? "True" : "False", "");
405 vals.emplace_back("Missing values", hasMissingValues() ? "True" : "False", "");
406
407 key = "Algorithm";
408 switch (selectedAlgo_) {
409 case AlgoType::GREEDY_HILL_CLIMBING :
410 vals.emplace_back(key, "Greedy Hill Climbing", "");
411 break;
412 case AlgoType::EXTENDED_GREEDY_HILL_CLIMBING :
413 vals.emplace_back(key, "Extended Greedy Hill Climbing", "");
414 break;
415 case AlgoType::K2 : {
416 vals.emplace_back(key, "K2", "");
417 const auto& k2order = algoK2_.order();
418 vars = "";
419 for (NodeId i = 0; i < k2order.size(); i++) {
420 if (i > 0) vars += ", ";
421 vars += nameFromId(k2order.atPos(i));
422 }
423 vals.emplace_back("K2 order", vars, "");
424 } break;
425 case AlgoType::LOCAL_SEARCH_WITH_TABU_LIST :
426 vals.emplace_back(key, "Local Search with Tabu List", "");
427 vals.emplace_back("Tabu list size", std::to_string(nbDecreasingChanges_), "");
428 break;
429 case AlgoType::MIIC : vals.emplace_back(key, "MIIC", ""); break;
430 case AlgoType::PC : vals.emplace_back(key, "PC", ""); break;
431 case AlgoType::FCI : vals.emplace_back(key, "FCI", ""); break;
432 case AlgoType::GREEDY_THICK_THINNING :
433 vals.emplace_back(key, "Greedy Thick Thinning", "");
434 break;
435 default : vals.emplace_back(key, "(unknown)", "?"); break;
436 }
437
438 key = "Score";
439
440 if (isScoreBased()) {
441 switch (scoreType_) {
442 case ScoreType::AIC : vals.emplace_back(key, "AIC", ""); break;
443 case ScoreType::BIC : vals.emplace_back(key, "BIC", ""); break;
444 case ScoreType::BD : vals.emplace_back(key, "BD", ""); break;
445 case ScoreType::BDeu : vals.emplace_back(key, "BDeu", ""); break;
446 case ScoreType::fNML : vals.emplace_back(key, "fNML", ""); break;
447 case ScoreType::K2 : vals.emplace_back(key, "K2", ""); break;
448 case ScoreType::LOG2LIKELIHOOD : vals.emplace_back(key, "Log2Likelihood", ""); break;
449 case ScoreType::MDL : vals.emplace_back(key, "MDL", ""); break;
450 default : vals.emplace_back(key, "(unknown)", "?"); break;
451 }
452 }
453
454 if (isConstraintBased()) {
455 key = "Correction";
456 switch (kmodeMiic_) {
458 vals.emplace_back(key, "MDL", "");
459 break;
461 vals.emplace_back(key, "NML", "");
462 break;
464 vals.emplace_back(key, "No correction", "");
465 break;
466 default : vals.emplace_back(key, "(unknown)", "?"); break;
467 }
468 }
469
470 key = "Prior";
471 comment = checkScorePriorCompatibility();
472 switch (priorType_) {
473 case BNLearnerPriorType::NO_prior : vals.emplace_back(key, "-", comment); break;
474 case BNLearnerPriorType::DIRICHLET_FROM_DATABASE :
475 vals.emplace_back(key, "Dirichlet", comment);
476 vals.emplace_back("Dirichlet from database", priorDbname_, "");
477 break;
478 case BNLearnerPriorType::DIRICHLET_FROM_BAYESNET :
479 vals.emplace_back(key, "Dirichlet", comment);
480 vals.emplace_back("Dirichlet from Bayesian network : ", _prior_bn_.toString(), "");
481 break;
482 case BNLearnerPriorType::BDEU : vals.emplace_back(key, "BDEU", comment); break;
483 case BNLearnerPriorType::SMOOTHING : vals.emplace_back(key, "Smoothing", comment); break;
484 default : vals.emplace_back(key, "(unknown)", "?"); break;
485 }
486
487 if (priorType_ != BNLearnerPriorType::NO_prior)
488 vals.emplace_back("Prior weight", std::to_string(priorWeight_), "");
489
490 if (databaseWeight() != double(nbRows())) {
491 vals.emplace_back("Database weight", std::to_string(databaseWeight()), "");
492 }
493
494 if (useEM_) {
495 comment = "";
496 if (!hasMissingValues()) comment = "But no missing values in this database";
497 vals.emplace_back("use EM", "True", "");
498 std::string s = "[";
499 bool first = true;
500 if (dag2BN_.isEnabledMinEpsilonRate()) {
501 s += std::format("MinRate: {}", dag2BN_.minEpsilonRate());
502 first = false;
503 }
504 if (dag2BN_.isEnabledEpsilon()) {
505 if (!first) s += ", ";
506 first = false;
507 s += std::format("MinDiff: {}", dag2BN_.epsilon());
508 }
509 if (dag2BN_.isEnabledMaxIter()) {
510 if (!first) s += ", ";
511 first = false;
512 s += std::format("MaxIter: {}", dag2BN_.maxIter());
513 }
514 if (dag2BN_.isEnabledMaxTime()) {
515 if (!first) s += ", ";
516 first = false;
517 s += std::format("MaxTime: {}", dag2BN_.maxTime());
518 }
519 s += "]";
520 vals.emplace_back("EM stopping criteria", s, comment);
521 }
522
523 std::string res;
524 bool nofirst;
525 if (constraintIndegree_.maxIndegree() < std::numeric_limits< Size >::max()) {
526 vals.emplace_back("Constraint Max InDegree",
527 std::to_string(constraintIndegree_.maxIndegree()),
528 "");
529 }
530 if (!constraintForbiddenArcs_.arcs().empty()) {
531 res = "{";
532 nofirst = false;
533 for (const auto& arc: constraintForbiddenArcs_.arcs()) {
534 if (nofirst) res += ", ";
535 else nofirst = true;
536 res += nameFromId(arc.tail()) + "->" + nameFromId(arc.head());
537 }
538 res += "}";
539 vals.emplace_back("Constraint Forbidden Arcs", res, "");
540 }
541 if (!constraintMandatoryArcs_.arcs().empty()) {
542 res = "{";
543 nofirst = false;
544 for (const auto& arc: constraintMandatoryArcs_.arcs()) {
545 if (nofirst) res += ", ";
546 else nofirst = true;
547 res += nameFromId(arc.tail()) + "->" + nameFromId(arc.head());
548 }
549 res += "}";
550 vals.emplace_back("Constraint Mandatory Arcs", res, "");
551 }
552 if (!constraintPossibleEdges_.edges().empty()) {
553 res = "{";
554 nofirst = false;
555 for (const auto& edge: constraintPossibleEdges_.edges()) {
556 if (nofirst) res += ", ";
557 else nofirst = true;
558 res += nameFromId(edge.first()) + "--" + nameFromId(edge.second());
559 }
560 res += "}";
561 vals.emplace_back("Constraint Possible Edges", res, "");
562 }
563 if (!constraintSliceOrder_.sliceOrder().empty()) {
564 res = "{";
565 nofirst = false;
566 const auto& order = constraintSliceOrder_.sliceOrder();
567 for (const auto& p: order) {
568 if (nofirst) res += ", ";
569 else nofirst = true;
570 res += nameFromId(p.first) + ":" + std::to_string(p.second);
571 }
572 res += "}";
573 vals.emplace_back("Constraint Slice Order", res, "");
574 }
575 if (!constraintNoParentNodes_.nodes().empty()) {
576 res = "{";
577 nofirst = false;
578 for (const auto& node: constraintNoParentNodes_.nodes()) {
579 if (nofirst) res += ", ";
580 else nofirst = true;
581 res += nameFromId(node);
582 }
583 res += "}";
584 vals.emplace_back("Constraint No Parent Nodes", res, "");
585 }
586 if (!constraintNoChildrenNodes_.nodes().empty()) {
587 res = "{";
588 nofirst = false;
589 for (const auto& node: constraintNoChildrenNodes_.nodes()) {
590 if (nofirst) res += ", ";
591 else nofirst = true;
592 res += nameFromId(node);
593 }
594 res += "}";
595 vals.emplace_back("Constraint No Children Nodes", res, "");
596 }
597 if (initialDag_.size() != 0) {
598 vals.emplace_back("Initial DAG", "True", initialDag_.toDot());
599 }
600
601 return vals;
602 }
603
604 template < GUM_Numeric GUM_SCALAR >
606 switch (learner.selectedAlgo_) {
607 case AlgoType::EXTENDED_GREEDY_HILL_CLIMBING : useExtendedGreedyHillClimbing(); break;
608 case AlgoType::GREEDY_HILL_CLIMBING : useGreedyHillClimbing(); break;
609 case AlgoType::GREEDY_THICK_THINNING :
610 useGreedyThickThinning();
611 setGreedyThickThinningReversals(learner.greedyThickThinningReversals());
612 break;
613 case AlgoType::K2 : useK2(learner.algoK2_.order()); break;
614 case AlgoType::LOCAL_SEARCH_WITH_TABU_LIST :
615 useLocalSearchWithTabuList(learner.nbDecreasingChanges_);
616 break;
617 case AlgoType::MIIC : useMIIC(); break;
618 case AlgoType::PC : usePC(); break;
619 case AlgoType::FCI : useFCI(); break;
620 }
621
622 switch (learner.scoreType_) {
623 case ScoreType::K2 : useScoreK2(); break;
624 case ScoreType::AIC : useScoreAIC(); break;
625 case ScoreType::BIC : useScoreBIC(); break;
626 case ScoreType::BD : useScoreBD(); break;
627 case ScoreType::BDeu : useScoreBDeu(); break;
628 case ScoreType::fNML : useScorefNML(); break;
629 case ScoreType::MDL : useScoreMDL(); break;
630 case ScoreType::LOG2LIKELIHOOD : useScoreLog2Likelihood(); break;
631 }
632
633 switch (learner.kmodeMiic_) {
634 case CorrectedMutualInformation::KModeTypes::MDL : useMDLCorrection(); break;
635 case CorrectedMutualInformation::KModeTypes::NML : useNMLCorrection(); break;
636 case CorrectedMutualInformation::KModeTypes::NoCorr : useNoCorrection(); break;
637 }
638
639 switch (learner.priorType_) {
640 case BNLearnerPriorType::NO_prior : useNoPrior(); break;
641 case BNLearnerPriorType::DIRICHLET_FROM_DATABASE :
642 useDirichletPrior(learner.priorDbname_, learner.priorWeight_);
643 break;
644 case BNLearnerPriorType::DIRICHLET_FROM_BAYESNET :
645 useDirichletPrior(learner._prior_bn_);
646 break;
647 case BNLearnerPriorType::BDEU : useBDeuPrior(learner.priorWeight_); break;
648 case BNLearnerPriorType::SMOOTHING : useSmoothingPrior(learner.priorWeight_); break;
649 }
650
651 useEM_ = learner.useEM_;
652 noiseEM_ = learner.noiseEM_;
653 dag2BN_ = learner.dag2BN_;
654
655 setMaxIndegree(learner.constraintIndegree_.maxIndegree());
656 for (const auto src: learner.constraintNoParentNodes_.nodes()) {
657 try {
658 const auto dst = idFromName(learner.nameFromId(src));
659 addNoParentNode(dst);
660 } catch (const MissingVariableInDatabase&) {
661 // nothing to do
662 }
663 }
664 for (const auto src: learner.constraintNoChildrenNodes_.nodes()) {
665 try {
666 const auto dst = idFromName(learner.nameFromId(src));
667 addNoChildrenNode(dst);
668 } catch (const MissingVariableInDatabase&) {
669 // nothing to do
670 }
671 }
672 for (const auto& arc: learner.constraintForbiddenArcs_.arcs()) {
673 try {
674 const auto src = idFromName(learner.nameFromId(arc.tail()));
675 const auto dst = idFromName(learner.nameFromId(arc.head()));
676 addForbiddenArc(src, dst);
677 } catch (const MissingVariableInDatabase&) {
678 // nothing to do
679 }
680 }
681 for (const auto& arc: learner.constraintMandatoryArcs_.arcs()) {
682 try {
683 const auto src = idFromName(learner.nameFromId(arc.tail()));
684 const auto dst = idFromName(learner.nameFromId(arc.head()));
685 addMandatoryArc(src, dst);
686 } catch (const MissingVariableInDatabase&) {
687 // nothing to do
688 }
689 }
690 for (const auto& edge: learner.constraintPossibleEdges_.edges()) {
691 try {
692 const auto src = idFromName(learner.nameFromId(edge.first()));
693 const auto dst = idFromName(learner.nameFromId(edge.second()));
694 addPossibleEdge(src, dst);
695 } catch (const MissingVariableInDatabase&) {
696 // nothing to do
697 }
698 }
699 if (!learner.constraintSliceOrder_.sliceOrder().empty()) {
700 NodeProperty< NodeId > slice_order;
701 for (const auto& p: learner.constraintSliceOrder_.sliceOrder()) {
702 try {
703 slice_order.insert(idFromName(learner.nameFromId(p.first)), p.second);
704 } catch (const MissingVariableInDatabase&) {
705 // nothing to do
706 }
707 }
708 setSliceOrder(slice_order);
709 }
710 if (!learner.constraintTotalOrder_.totalOrder().empty()) {
711 setTotalOrder(learner.constraintTotalOrder_.totalOrder());
712 }
713 }
714
715 template < GUM_Numeric GUM_SCALAR >
717 // first, save the old prior, to be delete if everything is ok
718 Prior* old_prior = prior_;
719
720 // create the new prior
721 switch (priorType_) {
722 case BNLearnerPriorType::NO_prior :
723 prior_ = new NoPrior(scoreDatabase_.databaseTable(), scoreDatabase_.nodeId2Columns());
724 break;
725
726 case BNLearnerPriorType::SMOOTHING :
727 prior_
728 = new SmoothingPrior(scoreDatabase_.databaseTable(), scoreDatabase_.nodeId2Columns());
729 break;
730
731 case BNLearnerPriorType::DIRICHLET_FROM_DATABASE :
732 if (priorDatabase_ != nullptr) {
733 delete priorDatabase_;
734 priorDatabase_ = nullptr;
735 }
736
737 priorDatabase_
738 = new Database(priorDbname_, scoreDatabase_, scoreDatabase_.missingSymbols());
739
740 prior_ = new DirichletPriorFromDatabase(scoreDatabase_.databaseTable(),
741 priorDatabase_->parser(),
742 priorDatabase_->nodeId2Columns());
743 break;
744
745 case BNLearnerPriorType::DIRICHLET_FROM_BAYESNET :
746 prior_
747 = new DirichletPriorFromBN< GUM_SCALAR >(scoreDatabase_.databaseTable(), &_prior_bn_);
748 break;
749
750 case BNLearnerPriorType::BDEU :
751 prior_ = new BDeuPrior(scoreDatabase_.databaseTable(), scoreDatabase_.nodeId2Columns());
752 break;
753
754 default : GUM_ERROR(OperationNotAllowed, "The BNLearner does not support yet this prior")
755 }
756
757 // do not forget to assign a weight to the prior
758 prior_->setWeight(priorWeight_);
759
760 // remove the old prior, if any
761 if (old_prior != nullptr) delete old_prior;
762 }
763
764 template < GUM_Numeric GUM_SCALAR >
765 std::ostream& operator<<(std::ostream& output, const BNLearner< GUM_SCALAR >& learner) {
766 output << learner.toString();
767 return output;
768 }
769
770 // =========================================================================
771 // Delegation methods — each calls IBNLearner and returns *this
772 // =========================================================================
773
774 template < GUM_Numeric GUM_SCALAR >
777 return *this;
778 }
779
780 template < GUM_Numeric GUM_SCALAR >
782 const double noise) {
783 IBNLearner::useEM(epsilon, noise);
784 return *this;
785 }
786
787 template < GUM_Numeric GUM_SCALAR >
789 const double noise) {
791 return *this;
792 }
793
794 template < GUM_Numeric GUM_SCALAR >
796 const double noise) {
798 return *this;
799 }
800
801 template < GUM_Numeric GUM_SCALAR >
804 return *this;
805 }
806
807 template < GUM_Numeric GUM_SCALAR >
810 return *this;
811 }
812
813 template < GUM_Numeric GUM_SCALAR >
816 return *this;
817 }
818
819 template < GUM_Numeric GUM_SCALAR >
822 return *this;
823 }
824
825 template < GUM_Numeric GUM_SCALAR >
828 return *this;
829 }
830
831 template < GUM_Numeric GUM_SCALAR >
834 return *this;
835 }
836
837 template < GUM_Numeric GUM_SCALAR >
840 return *this;
841 }
842
843 template < GUM_Numeric GUM_SCALAR >
846 return *this;
847 }
848
849 template < GUM_Numeric GUM_SCALAR >
852 return *this;
853 }
854
855 template < GUM_Numeric GUM_SCALAR >
858 return *this;
859 }
860
861 template < GUM_Numeric GUM_SCALAR >
864 return *this;
865 }
866
867 template < GUM_Numeric GUM_SCALAR >
870 return *this;
871 }
872
873 template < GUM_Numeric GUM_SCALAR >
876 return *this;
877 }
878
879 template < GUM_Numeric GUM_SCALAR >
882 return *this;
883 }
884
885 template < GUM_Numeric GUM_SCALAR >
888 return *this;
889 }
890
891 template < GUM_Numeric GUM_SCALAR >
894 return *this;
895 }
896
897 template < GUM_Numeric GUM_SCALAR >
900 return *this;
901 }
902
903 template < GUM_Numeric GUM_SCALAR >
906 return *this;
907 }
908
909 template < GUM_Numeric GUM_SCALAR >
912 return *this;
913 }
914
915 template < GUM_Numeric GUM_SCALAR >
918 return *this;
919 }
920
921 template < GUM_Numeric GUM_SCALAR >
924 return *this;
925 }
926
927 template < GUM_Numeric GUM_SCALAR >
930 return *this;
931 }
932
933 template < GUM_Numeric GUM_SCALAR >
936 return *this;
937 }
938
939 template < GUM_Numeric GUM_SCALAR >
942 return *this;
943 }
944
945 template < GUM_Numeric GUM_SCALAR >
947 double weight) {
948 IBNLearner::useDirichletPrior(filename, weight);
949 return *this;
950 }
951
952 template < GUM_Numeric GUM_SCALAR >
954 BNLearner< GUM_SCALAR >::useDirichletPrior(const gum::BayesNet< GUM_SCALAR >& bn,
955 double weight) {
956 _prior_bn_ = bn;
957 priorType_ = BNLearnerPriorType::DIRICHLET_FROM_BAYESNET;
958 _setPriorWeight_(weight);
959 return *this;
960 }
961
962 template < GUM_Numeric GUM_SCALAR >
965 return *this;
966 }
967
968 template < GUM_Numeric GUM_SCALAR >
971 return *this;
972 }
973
974 template < GUM_Numeric GUM_SCALAR >
977 return *this;
978 }
979
980 template < GUM_Numeric GUM_SCALAR >
983 return *this;
984 }
985
986 template < GUM_Numeric GUM_SCALAR >
989 }
990
991 template < GUM_Numeric GUM_SCALAR >
993 Size nb_decrease) {
994 IBNLearner::useLocalSearchWithTabuList(tabu_size, nb_decrease);
995 return *this;
996 }
997
998 template < GUM_Numeric GUM_SCALAR >
999 BNLearner< GUM_SCALAR >& BNLearner< GUM_SCALAR >::useK2(const Sequence< NodeId >& order) {
1000 IBNLearner::useK2(order);
1001 return *this;
1002 }
1003
1004 template < GUM_Numeric GUM_SCALAR >
1005 BNLearner< GUM_SCALAR >& BNLearner< GUM_SCALAR >::useK2(const std::vector< NodeId >& order) {
1006 IBNLearner::useK2(order);
1007 return *this;
1008 }
1009
1010 template < GUM_Numeric GUM_SCALAR >
1013 return *this;
1014 }
1015
1016 template < GUM_Numeric GUM_SCALAR >
1019 return *this;
1020 }
1021
1022 template < GUM_Numeric GUM_SCALAR >
1025 return *this;
1026 }
1027
1028 template < GUM_Numeric GUM_SCALAR >
1031 return *this;
1032 }
1033
1034 template < GUM_Numeric GUM_SCALAR >
1037 return *this;
1038 }
1039
1040 template < GUM_Numeric GUM_SCALAR >
1043 return *this;
1044 }
1045
1046 template < GUM_Numeric GUM_SCALAR >
1049 return *this;
1050 }
1051
1052 template < GUM_Numeric GUM_SCALAR >
1055 return *this;
1056 }
1057
1058 template < GUM_Numeric GUM_SCALAR >
1061 }
1062
1063 template < GUM_Numeric GUM_SCALAR >
1066 return *this;
1067 }
1068
1069 template < GUM_Numeric GUM_SCALAR >
1072 return *this;
1073 }
1074
1075 template < GUM_Numeric GUM_SCALAR >
1078 return *this;
1079 }
1080
1081 template < GUM_Numeric GUM_SCALAR >
1084 return *this;
1085 }
1086
1087 template < GUM_Numeric GUM_SCALAR >
1090 return *this;
1091 }
1092
1093 template < GUM_Numeric GUM_SCALAR >
1096 return *this;
1097 }
1098
1099 template < GUM_Numeric GUM_SCALAR >
1102 return *this;
1103 }
1104
1105 template < GUM_Numeric GUM_SCALAR >
1108 return *this;
1109 }
1110
1111 template < GUM_Numeric GUM_SCALAR >
1114 return *this;
1115 }
1116
1117 template < GUM_Numeric GUM_SCALAR >
1119 IBNLearner::setMaxIndegree(max_indegree);
1120 return *this;
1121 }
1122
1123 template < GUM_Numeric GUM_SCALAR >
1126 IBNLearner::setSliceOrder(slice_order);
1127 return *this;
1128 }
1129
1130 template < GUM_Numeric GUM_SCALAR >
1132 const std::vector< std::vector< std::string > >& slices) {
1134 return *this;
1135 }
1136
1137 template < GUM_Numeric GUM_SCALAR >
1139 BNLearner< GUM_SCALAR >::setTotalOrder(const std::vector< std::string >& order) {
1141 return *this;
1142 }
1143
1144 template < GUM_Numeric GUM_SCALAR >
1146 BNLearner< GUM_SCALAR >::setTotalOrder(const Sequence< NodeId >& order) {
1148 return *this;
1149 }
1150
1151 template < GUM_Numeric GUM_SCALAR >
1154 return *this;
1155 }
1156
1157 template < GUM_Numeric GUM_SCALAR >
1160 return *this;
1161 }
1162
1163 template < GUM_Numeric GUM_SCALAR >
1165 IBNLearner::addForbiddenArc(tail, head);
1166 return *this;
1167 }
1168
1169 template < GUM_Numeric GUM_SCALAR >
1171 std::string_view head) {
1172 IBNLearner::addForbiddenArc(tail, head);
1173 return *this;
1174 }
1175
1176 template < GUM_Numeric GUM_SCALAR >
1179 return *this;
1180 }
1181
1182 template < GUM_Numeric GUM_SCALAR >
1185 return *this;
1186 }
1187
1188 template < GUM_Numeric GUM_SCALAR >
1190 std::string_view head) {
1192 return *this;
1193 }
1194
1195 template < GUM_Numeric GUM_SCALAR >
1198 return *this;
1199 }
1200
1201 template < GUM_Numeric GUM_SCALAR >
1203 IBNLearner::addMandatoryArc(tail, head);
1204 return *this;
1205 }
1206
1207 template < GUM_Numeric GUM_SCALAR >
1209 std::string_view head) {
1210 IBNLearner::addMandatoryArc(tail, head);
1211 return *this;
1212 }
1213
1214 template < GUM_Numeric GUM_SCALAR >
1217 return *this;
1218 }
1219
1220 template < GUM_Numeric GUM_SCALAR >
1223 return *this;
1224 }
1225
1226 template < GUM_Numeric GUM_SCALAR >
1228 std::string_view head) {
1230 return *this;
1231 }
1232
1233 template < GUM_Numeric GUM_SCALAR >
1236 return *this;
1237 }
1238
1239 template < GUM_Numeric GUM_SCALAR >
1241 IBNLearner::addPossibleEdge(tail, head);
1242 return *this;
1243 }
1244
1245 template < GUM_Numeric GUM_SCALAR >
1247 std::string_view head) {
1248 IBNLearner::addPossibleEdge(tail, head);
1249 return *this;
1250 }
1251
1252 template < GUM_Numeric GUM_SCALAR >
1255 return *this;
1256 }
1257
1258 template < GUM_Numeric GUM_SCALAR >
1261 return *this;
1262 }
1263
1264 template < GUM_Numeric GUM_SCALAR >
1266 std::string_view head) {
1268 return *this;
1269 }
1270
1271 template < GUM_Numeric GUM_SCALAR >
1274 return *this;
1275 }
1276
1277 template < GUM_Numeric GUM_SCALAR >
1280 return *this;
1281 }
1282
1283 template < GUM_Numeric GUM_SCALAR >
1285 BNLearner< GUM_SCALAR >::setPossibleSkeleton(const UndiGraph& skeleton) {
1287 return *this;
1288 }
1289
1290 template < GUM_Numeric GUM_SCALAR >
1293 return *this;
1294 }
1295
1296 template < GUM_Numeric GUM_SCALAR >
1299 return *this;
1300 }
1301
1302 template < GUM_Numeric GUM_SCALAR >
1305 return *this;
1306 }
1307
1308 template < GUM_Numeric GUM_SCALAR >
1311 return *this;
1312 }
1313
1314 template < GUM_Numeric GUM_SCALAR >
1317 return *this;
1318 }
1319
1320 template < GUM_Numeric GUM_SCALAR >
1323 return *this;
1324 }
1325
1326 template < GUM_Numeric GUM_SCALAR >
1329 return *this;
1330 }
1331
1332 template < GUM_Numeric GUM_SCALAR >
1335 return *this;
1336 }
1337
1338 template < GUM_Numeric GUM_SCALAR >
1341 return *this;
1342 }
1343
1344 template < GUM_Numeric GUM_SCALAR >
1347 return *this;
1348 }
1349
1350 template < GUM_Numeric GUM_SCALAR >
1353 return *this;
1354 }
1355
1356 template < GUM_Numeric GUM_SCALAR >
1359 return *this;
1360 }
1361
1362 template < GUM_Numeric GUM_SCALAR >
1365 }
1366
1367 template < GUM_Numeric GUM_SCALAR >
1369 return IBNLearner::isScoreBased();
1370 }
1371
1372 } /* namespace learning */
1373
1374} /* namespace gum */
1375
1376#endif /* DOXYGEN_SHOULD_SKIP_THIS */
A listener that allows BNLearner to be used as a proxy for its inner algorithms.
A basic pack of learning algorithms that can easily be used.
Class representing a Bayesian network.
Definition BayesNet.h:99
BDeuPrior(const DatabaseTable &database, const Bijection< NodeId, std::size_t > &nodeId2columns=Bijection< NodeId, std::size_t >())
default constructor
A pack of learning algorithms that can easily be used.
Definition BNLearner.h:74
BNLearner< GUM_SCALAR > & useNoPrior()
BNLearner< GUM_SCALAR > & EMdisableMaxIter()
Disable stopping criterion on max iterations.
BNLearner< GUM_SCALAR > & useFCIChi2Test()
BNLearner< GUM_SCALAR > & EMenableMinEpsilonRate()
Enable the log-likelihood evolution rate stopping criterion.
BNLearner< GUM_SCALAR > & useGreedyThickThinning()
BNLearner< GUM_SCALAR > & addForbiddenArc(const Arc &arc)
BNLearner< GUM_SCALAR > & useScoreAIC()
BNLearner< GUM_SCALAR > & eraseMandatoryArc(const Arc &arc)
BNLearner< GUM_SCALAR > & setTotalOrder(const std::vector< std::string > &order)
BNLearner< GUM_SCALAR > & EMdisableEpsilon()
Disable the min log-likelihood diff stopping criterion.
BNLearner< GUM_SCALAR > & addPossibleEdge(const Edge &edge)
BNLearner< GUM_SCALAR > & useScoreBD()
BNLearner< GUM_SCALAR > & allowArcReversals(bool allow)
std::vector< std::tuple< std::string, std::string, std::string > > state() const
BNLearner< GUM_SCALAR > & setPCStable(bool stable)
BNLearner< GUM_SCALAR > & addMandatoryArc(const Arc &arc)
BNLearner< GUM_SCALAR > & useBDeuPrior(double weight=1.0)
BNLearner< GUM_SCALAR > & useScoreBIC()
BNLearner< GUM_SCALAR > & usePC()
BNLearner< GUM_SCALAR > & useNoCorrection()
std::pair< std::shared_ptr< ParamEstimator >, std::shared_ptr< ParamEstimator > > _initializeEMParameterLearning_(const DAG &dag, bool takeIntoAccountScore)
initializes EM and returns a pair containing, first, a bootstrap estimator and, second,...
BNLearner< GUM_SCALAR > & useG2Test()
BNLearner< GUM_SCALAR > & setFCIMaxPathLength(Size max_len)
BNLearner< GUM_SCALAR > & useSmoothingPrior(double weight=1)
BNLearner< GUM_SCALAR > & EMdisableMinEpsilonRate()
Disable the log-likelihood evolution rate stopping criterion.
BNLearner(std::string_view filename, const std::vector< std::string > &missingSymbols={"?"}, const bool induceTypes=true)
default constructor
BNLearner< GUM_SCALAR > & erasePossibleEdge(const Edge &edge)
BNLearner< GUM_SCALAR > & setGreedyThickThinningReversals(bool allow)
BNLearner< GUM_SCALAR > & setPossibleSkeleton(const UndiGraph &skeleton)
BayesNet< GUM_SCALAR > _learnParameters_(const DAG &dag, bool takeIntoAccountScore)
learns a BN (its parameters) with the structure passed in argument using a single pass estimation (no...
BNLearner< GUM_SCALAR > & EMenableEpsilon()
Enable the log-likelihood min diff stopping criterion in EM.
BNLearner< GUM_SCALAR > & setPCMaxCondSetSize(Size max_k)
BNLearner< GUM_SCALAR > & setPossibleEdges(const EdgeSet &set)
BNLearner< GUM_SCALAR > & allowArcDeletions(bool allow)
BNLearner< GUM_SCALAR > & setFCIExhaustiveSepSet(bool exhaustive)
BNLearner< GUM_SCALAR > & EMenableMaxTime()
enable EM's timeout stopping criterion
BayesNet< GUM_SCALAR > _learnParametersWithEM_(const DAG &dag, bool takeIntoAccountScore)
learns a BN (its parameters) with the structure passed in argument using the EM algorithm initialized...
BNLearner< GUM_SCALAR > & addNoChildrenNode(NodeId node)
BNLearner< GUM_SCALAR > & EMsetEpsilon(const double eps)
sets the stopping criterion of EM as being the minimal difference between two consecutive log-likelih...
BNLearner< GUM_SCALAR > & EMdisableMaxTime()
Disable EM's timeout stopping criterion.
BNLearner & operator=(const BNLearner &)
copy operator
bool greedyThickThinningReversals() const
BNLearner< GUM_SCALAR > & useGreedyHillClimbing()
BNLearner< GUM_SCALAR > & forbidEM()
prevent using the EM algorithm for parameter learning
BNLearner< GUM_SCALAR > & useK2(const Sequence< NodeId > &order)
BNLearner< GUM_SCALAR > & useExtendedGreedyHillClimbing()
BNLearner< GUM_SCALAR > & useScoreK2()
BNLearner< GUM_SCALAR > & setMandatoryArcs(const ArcSet &set)
BNLearner< GUM_SCALAR > & eraseNoChildrenNode(NodeId node)
BNLearner< GUM_SCALAR > & useMIIC()
bool fciExhaustiveSepSet() const
BNLearner< GUM_SCALAR > & EMsetPeriodSize(const Size p)
how many samples between 2 stoppings isEnabled
BayesNet< GUM_SCALAR > learnBN()
learn a Bayes Net from a file (must have read the db before)
BNLearner< GUM_SCALAR > & setForbiddenArcs(const ArcSet &set)
bool isConstraintBased() const
BNLearner< GUM_SCALAR > & useEMWithRateCriterion(const double epsilon, const double noise=default_EM_noise)
use The EM algorithm to learn parameters with the rate stopping criterion
BNLearner< GUM_SCALAR > & setInitialDAG(const DAG &dag)
BNLearner< GUM_SCALAR > & addNoParentNode(NodeId node)
BNLearner< GUM_SCALAR > & setPCAlpha(double alpha)
BNLearner< GUM_SCALAR > & useEMWithDiffCriterion(const double epsilon, const double noise=default_EM_noise)
use The EM algorithm to learn parameters with the diff stopping criterion
BNLearner< GUM_SCALAR > & useScoreLog2Likelihood()
BNLearner< GUM_SCALAR > & EMsetMaxIter(const Size max)
add a max iteration stopping criterion
BNLearner< GUM_SCALAR > & useEM(const double epsilon, const double noise=default_EM_noise)
use The EM algorithm to learn parameters
BNLearner< GUM_SCALAR > & useFCI()
BNLearner< GUM_SCALAR > & useDirichletPrior(std::string_view filename, double weight=1)
BNLearner< GUM_SCALAR > & useLocalSearchWithTabuList(Size tabu_size=100, Size nb_decrease=2)
BNLearner< GUM_SCALAR > & EMsetMinEpsilonRate(const double rate)
sets the stopping criterion of EM as being the minimal log-likelihood's evolution rate
BNLearner< GUM_SCALAR > & allowArcTriangleDeletions(bool allow)
NodeProperty< Sequence< std::string > > _labelsFromBN_(std::string_view filename, const BayesNet< GUM_SCALAR > &src)
read the first line of a file to find column names
BNLearner< GUM_SCALAR > & useMDLCorrection()
BNLearner< GUM_SCALAR > & eraseNoParentNode(NodeId node)
BNLearner< GUM_SCALAR > & allowArcAdditions(bool allow)
BNLearner< GUM_SCALAR > & EMsetVerbosity(const bool v)
sets or unsets EM's verbosity
BNLearner< GUM_SCALAR > & eraseForbiddenArc(const Arc &arc)
BayesNet< GUM_SCALAR > learnParameters(const DAG &dag, bool takeIntoAccountScore=true)
learns a BN (its parameters) with the structure passed in argument
BNLearner< GUM_SCALAR > & setFCIAlpha(double alpha)
BNLearner< GUM_SCALAR > & useFCIG2Test()
void _checkDAGCompatibility_(const DAG &dag)
check that the database contains the nodes of the dag, else raise an exception
BNLearner< GUM_SCALAR > & useNMLCorrection()
BNLearner< GUM_SCALAR > & setSliceOrder(const NodeProperty< NodeId > &slice_order)
std::string toString() const
void createPrior_() override
create the prior used for learning
BNLearner< GUM_SCALAR > & EMsetMaxTime(const double timeout)
add a stopping criterion on timeout
void copyState(const BNLearner< GUM_SCALAR > &learner)
copy the states of the BNLearner
BNLearner< GUM_SCALAR > & setPCUnshieldedColliderSorted(bool sorted)
BNLearner< GUM_SCALAR > & EMenableMaxIter()
Enable stopping criterion on max iterations.
BNLearner< GUM_SCALAR > & useChi2Test()
BNLearner< GUM_SCALAR > & useScoreBDeu()
BNLearner< GUM_SCALAR > & setMaxIndegree(Size max_indegree)
Class for fast parsing of CSV file (never more than one line in application memory).
Definition CSVParser.h:78
A DBRowGenerator class that returns the rows that are complete (fully observed) w....
A DBRowGenerator class that returns incomplete rows as EM would do.
the class used to read a row in the database and to transform it into a set of DBRow instances that c...
The class used to pack sets of generators.
void insertGenerator(const Generator &generator)
inserts a new generator at the end of the set
The base class for all DBRow generators.
DirichletPriorFromBN(const DatabaseTable &learning_db, const BayesNet< GUM_SCALAR > *priorbn)
default constructor
DirichletPriorFromDatabase(const DatabaseTable &learning_db, const DBRowGeneratorParser &prior_parser, const Bijection< NodeId, std::size_t > &nodeId2columns=Bijection< NodeId, std::size_t >())
default constructor
A pack of learning algorithms that can easily be used.
Definition IBNLearner.h:106
void usePC()
indicate that we wish to use PC (Chi2 test by default)
void eraseNoChildrenNode(NodeId node)
void EMenableEpsilon()
Enable the log-likelihood min diff stopping criterion in EM.
void EMsetPeriodSize(Size p)
how many samples between 2 stoppings isEnabled
void useGreedyHillClimbing()
indicate that we wish to use a greedy hill climbing algorithm
void useScoreBDeu()
indicate that we wish to use a BDeu score
void addNoParentNode(NodeId node)
void setSliceOrder(const NodeProperty< NodeId > &slice_order)
sets a partial order on the nodes
bool isScoreBased() const
indicate if the selected algorithm is score-based
void setForbiddenArcs(const ArcSet &set)
removes a total
void useFCIChi2Test()
indicate that we wish to use Chi2 independence test for FCI
void useBDeuPrior(double weight=1.0)
use the BDeu prior
void setMandatoryArcs(const ArcSet &set)
assign a set of mandatory arcs
bool greedyThickThinningReversals() const
returns whether arc reversals are allowed in the thin phase of greedy thick-thinning
void EMdisableMinEpsilonRate()
Disable the log-likelihood evolution rate stopping criterion.
void useExtendedGreedyHillClimbing()
indicate that we wish to use the extended greedy hill climbing algorithm
void setFCIMaxPathLength(Size max_len)
set maximum discriminating-path length for FCI R4 (default Size(-1) = unlimited)
void addMandatoryArc(const Arc &arc)
void EMenableMaxIter()
Enable stopping criterion on max iterations.
void useFCI()
indicate that we wish to use FCI (Chi2 test by default)
void useFCIG2Test()
indicate that we wish to use G2 independence test for FCI
void setMaxIndegree(Size max_indegree)
sets the max indegree
void EMdisableEpsilon()
Disable the min log-likelihood diff stopping criterion for EM.
void addPossibleEdge(const Edge &edge)
void EMsetMaxIter(Size max)
add a max iteration stopping criterion
void useChi2Test()
indicate that we wish to use Chi2 independence test for PC
void setInitialDAG(const DAG &)
sets an initial DAG structure
void useK2(const Sequence< NodeId > &order)
indicate that we wish to use K2
void allowArcDeletions(bool allow=true)
allow (true)/forbid (false) to delete arcs during learning.
void EMsetMinEpsilonRate(double rate)
sets the stopping criterion of EM as being the minimal log-likelihood's evolution rate
void setGreedyThickThinningReversals(bool allow)
enable or disable arc reversals in the thin phase of greedy thick-thinning
void EMdisableMaxIter()
Disable stopping criterion on max iterations.
void erasePossibleEdge(const Edge &edge)
void useScoreBIC()
indicate that we wish to use a BIC score
void allowArcTriangleDeletions(bool allow=true)
allow (true)/forbid (false) to delete arc triangles during learning.
void EMsetVerbosity(bool v)
sets or unsets EM's verbosity
void setPossibleEdges(const EdgeSet &set)
assign a set of possible edges
void useNoPrior()
use no prior
void eraseForbiddenArc(const Arc &arc)
void useSmoothingPrior(double weight=1)
use the prior smoothing
void allowArcAdditions(bool allow=true)
allow (true)/forbid (false) to add arcs during learning.
void useLocalSearchWithTabuList(Size tabu_size=100, Size nb_decrease=2)
indicate that we wish to use a local search with tabu list
void useScoreK2()
indicate that we wish to use a K2 score
void useGreedyThickThinning()
indicate that we wish to use greedy thick-thinning
void useG2Test()
indicate that we wish to use G2 independence test for PC
void setPossibleSkeleton(const UndiGraph &skeleton)
assign a set of possible edges
void useEMWithRateCriterion(const double epsilon, const double noise=default_EM_noise)
use The EM algorithm to learn parameters with the rate stopping criterion
void useNMLCorrection()
indicate that we wish to use the NML correction for and MIIC
void useEM(const double epsilon, const double noise=default_EM_noise)
use The EM algorithm to learn parameters
void useEMWithDiffCriterion(const double epsilon, const double noise=default_EM_noise)
use The EM algorithm to learn parameters with the diff stopping criterion
void forbidEM()
prevent using the EM algorithm for parameter learning
void setPCMaxCondSetSize(Size max_k)
set maximum conditioning set size for PC (default Size(-1) = unlimited)
void EMenableMaxTime()
sets the stopping criterion of EM as being the minimal difference between two consecutive log-likelih...
void useNoCorrection()
indicate that we wish to use the NoCorr correction for MIIC
void useScoreLog2Likelihood()
indicate that we wish to use a Log2Likelihood score
void useDirichletPrior(std::string_view filename, double weight=1)
use the Dirichlet prior from a database
void useMDLCorrection()
indicate that we wish to use the MDL correction for MIIC
void setFCIAlpha(double alpha)
set the significance threshold alpha for FCI (default 0.05)
bool fciExhaustiveSepSet() const
return true when FCI uses exhaustive sepset mode
void setPCAlpha(double alpha)
set the significance threshold alpha for PC (default 0.05)
void addForbiddenArc(const Arc &arc)
void addNoChildrenNode(NodeId node)
void EMsetMaxTime(double timeout)
add a stopping criterion on timeout
IBNLearner & operator=(const IBNLearner &)
copy operator
void EMenableMinEpsilonRate()
Enable the log-likelihood evolution rate stopping criterion.
void setFCIExhaustiveSepSet(bool exhaustive)
enable exhaustive sepset mode for FCI skeleton learning (default false)
void setTotalOrder(const Sequence< NodeId > &order)
sets a total order over some nodes
void useScoreAIC()
indicate that we wish to use an AIC score
void eraseMandatoryArc(const Arc &arc)
void allowArcReversals(bool allow=true)
allow (true)/forbid (false) to reverse arcs during learning.
void useMIIC()
indicate that we wish to use MIIC
void EMdisableMaxTime()
Disable EM's timeout stopping criterion.
void eraseNoParentNode(NodeId node)
void setPCUnshieldedColliderSorted(bool sorted)
set unshielded-collider ordering for PC: sorted=true uses descending p-value order (strongest evidenc...
void EMsetEpsilon(double eps)
sets the stopping criterion of EM as being the minimal difference between two consecutive log-likelih...
void setPCStable(bool stable)
set stable mode for PC — defer removals to end of each depth level (default true)
void useScoreBD()
indicate that we wish to use a BD score
bool isConstraintBased() const
indicate if the selected algorithm is constraint-based
NoPrior(const DatabaseTable &database, const Bijection< NodeId, std::size_t > &nodeId2columns=Bijection< NodeId, std::size_t >())
default constructor
the base class for all a priori
Definition prior.h:84
virtual void setWeight(double weight)
sets the weight of the a prior(kind of effective sample size)
SmoothingPrior(const DatabaseTable &database, const Bijection< NodeId, std::size_t > &nodeId2columns=Bijection< NodeId, std::size_t >())
default constructor
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
Size Idx
Type for indexes.
Definition types.h:79
Set< Edge > EdgeSet
Some typdefs and define for shortcuts ...
Size NodeId
Type for node ids.
Set< Arc > ArcSet
Some typdefs and define for shortcuts ...
HashTable< NodeId, VAL > NodeProperty
Property on graph elements.
include the inlined functions if necessary
Definition CSVParser.h:55
std::ostream & operator<<(std::ostream &stream, const IdCondSet &idset)
the display operator
gum is the global namespace for all aGrUM entities
Definition agrum.h:46