51#ifndef DOXYGEN_SHOULD_SKIP_THIS
68 const Prior& external_prior,
69 const Prior& score_internal_prior,
70 const std::vector< std::pair< std::size_t, std::size_t > >& ranges,
71 const Bijection< NodeId, std::size_t >& nodeId2columns) :
72 ParamEstimator(parser, external_prior, score_internal_prior, ranges, nodeId2columns) {
73 GUM_CONSTRUCTOR(ParamEstimatorML);
77 ParamEstimatorML::ParamEstimatorML(
const DBRowGeneratorParser& parser,
78 const Prior& external_prior,
79 const Prior& score_internal_prior,
80 const Bijection< NodeId, std::size_t >& nodeId2columns) :
81 ParamEstimator(parser, external_prior, score_internal_prior, nodeId2columns) {
82 GUM_CONSTRUCTOR(ParamEstimatorML);
86 ParamEstimatorML::ParamEstimatorML(
const ParamEstimatorML& from) : ParamEstimator(from) {
87 GUM_CONS_CPY(ParamEstimatorML);
91 ParamEstimatorML::ParamEstimatorML(ParamEstimatorML&& from) : ParamEstimator(
std::move(from)) {
92 GUM_CONS_MOV(ParamEstimatorML);
96 ParamEstimatorML::~ParamEstimatorML() { GUM_DESTRUCTOR(ParamEstimatorML); }
99 ParamEstimatorML& ParamEstimatorML::operator=(
const ParamEstimatorML& from) {
100 ParamEstimator::operator=(from);
101 GUM_OP_CPY(ParamEstimatorML);
106 ParamEstimatorML& ParamEstimatorML::operator=(ParamEstimatorML&& from) {
107 ParamEstimator::operator=(std::move(from));
108 GUM_OP_MOV(ParamEstimatorML);
113 std::pair< std::vector< double >,
double > ParamEstimatorML::_parametersAndLogLikelihood_(
114 const NodeId target_node,
115 const std::vector< NodeId >& conditioning_nodes,
116 const bool compute_log_likelihood) {
119 IdCondSet idset(target_node, conditioning_nodes,
true);
123 this->counter_.clear();
124 const std::vector< double >& original_N_ijk = this->counter_.counts(idset,
true);
125 std::vector< double > N_ijk = original_N_ijk;
126 const bool informative_external_prior = this->external_prior_->isInformative();
127 const bool informative_score_internal_prior = this->score_internal_prior_->isInformative();
130 if (informative_external_prior) this->external_prior_->addJointPseudoCount(idset, N_ijk);
131 if (informative_score_internal_prior)
132 this->score_internal_prior_->addJointPseudoCount(idset, N_ijk);
133 double log_likelihood = 0.0;
139 if (!conditioning_nodes.empty()) {
142 std::vector< double > N_ij(this->counter_.counts(idset.conditionalIdCondSet(),
false));
143 if (informative_external_prior)
144 this->external_prior_->addConditioningPseudoCount(idset, N_ij);
145 if (informative_score_internal_prior)
146 this->score_internal_prior_->addConditioningPseudoCount(idset, N_ij);
148 const std::size_t conditioning_domsize = N_ij.size();
149 const std::size_t target_domsize = N_ijk.size() / conditioning_domsize;
152 for (std::size_t j = std::size_t(0); j < conditioning_domsize; ++j) {
155 const std::size_t cond_nb = conditioning_nodes.size();
156 std::vector< Idx > cond_domsize(cond_nb);
158 const auto& node2cols = this->counter_.nodeId2Columns();
159 const auto& database = this->counter_.database();
160 if (node2cols.empty()) {
161 for (std::size_t i = std::size_t(0); i < cond_nb; ++i) {
162 cond_domsize[i] = database.domainSize(conditioning_nodes[i]);
165 for (std::size_t i = std::size_t(0); i < cond_nb; ++i) {
166 cond_domsize[i] = database.domainSize(node2cols.second(conditioning_nodes[i]));
171 std::vector< Idx > offsets(cond_nb);
174 for (i = std::size_t(0); i < cond_nb; ++i) {
176 offset *= cond_domsize[i];
178 std::vector< Idx > values(cond_nb);
181 for (Idx jj = cond_nb - 1; i < cond_nb; ++i, --jj) {
182 values[jj] = offset / offsets[jj];
183 offset %= offsets[jj];
187 std::string str =
"The conditioning set <";
189 for (i = std::size_t(0); i < cond_nb; ++i) {
190 if (deja) str +=
", ";
192 std::size_t col = node2cols.empty() ? conditioning_nodes[i]
193 : node2cols.second(conditioning_nodes[i]);
194 const DiscreteVariable& var
195 =
dynamic_cast< const DiscreteVariable&
>(database.variable(col));
196 str += std::format(
"{}={}", var.name(), var.labels()[values[i]]);
198 auto target_col = node2cols.empty() ? target_node : node2cols.second(target_node);
199 const Variable& var = database.variable(target_col);
200 str += std::format(
"> for target node {} never appears in the database. "
201 "Please consider using priors such as smoothing.",
209 if (compute_log_likelihood) {
210 for (std::size_t j = std::size_t(0), k = std::size_t(0); j < conditioning_domsize; ++j) {
211 for (std::size_t i = std::size_t(0); i < target_domsize; ++i, ++k) {
213 if (original_N_ijk[k]) { log_likelihood += original_N_ijk[k] * std::log(N_ijk[k]); }
217 for (std::size_t j = std::size_t(0), k = std::size_t(0); j < conditioning_domsize; ++j) {
218 for (std::size_t i = std::size_t(0); i < target_domsize; ++i, ++k) {
228 for (
const double n_ijk: N_ijk)
232 if (compute_log_likelihood) {
233 for (std::size_t k = std::size_t(0), end = N_ijk.size(); k < end; ++k) {
235 if (original_N_ijk[k]) { log_likelihood += original_N_ijk[k] * std::log(N_ijk[k]); }
238 for (
double& n_ijk: N_ijk)
242 const auto& node2cols = this->counter_.nodeId2Columns();
243 const auto& database = this->counter_.database();
244 auto target_col = node2cols.empty() ? target_node : node2cols.second(target_node);
245 const Variable& var = database.variable(target_col);
247 std::format(
"No data for target node {}. It is impossible to estimate "
248 "the parameters by maximum likelihood",
253 return {std::move(N_ijk), log_likelihood};
Error: An unknown error occurred while accessing a database.
the class used to read a row in the database and to transform it into a set of DBRow instances that c...
ParamEstimatorML(const DBRowGeneratorParser &parser, const Prior &external_prior, const Prior &_score_internal_prior, const std::vector< std::pair< std::size_t, std::size_t > > &ranges, const Bijection< NodeId, std::size_t > &nodeId2columns=Bijection< NodeId, std::size_t >())
default constructor
The base class for estimating parameters of CPTs.
the base class for all a priori
#define GUM_ERROR(type, msg)
include the inlined functions if necessary
class GUM_SHARED_PUBLIC IdCondSet
gum is the global namespace for all aGrUM entities
the class for estimating parameters of CPTs using Maximum Likelihood
the class for estimating parameters of CPTs using Maximum Likelihood