Complete proposal

This commit is contained in:
2025-07-07 00:37:16 +02:00
parent 97894cc49c
commit 62fa85a1b3
14 changed files with 492 additions and 290 deletions

View File

@@ -5,6 +5,9 @@
// ***************************************************************
#include "Proposal.h"
#include <iostream>
#include <cmath>
#include <limits>
namespace bayesnet {
Proposal::Proposal(torch::Tensor& dataset_, std::vector<std::string>& features_, std::string& className_) : pDataset(dataset_), pFeatures(features_), pClassName(className_)
@@ -38,6 +41,15 @@ namespace bayesnet {
throw std::invalid_argument("Invalid discretization algorithm: " + algorithm.get<std::string>());
}
}
// Convergence parameters
if (hyperparameters.contains("max_iterations")) {
convergence_params.maxIterations = hyperparameters["max_iterations"];
hyperparameters.erase("max_iterations");
}
if (hyperparameters.contains("verbose_convergence")) {
convergence_params.verbose = hyperparameters["verbose_convergence"];
hyperparameters.erase("verbose_convergence");
}
if (!hyperparameters.empty()) {
throw std::invalid_argument("Invalid hyperparameters for Proposal: " + hyperparameters.dump());
}
@@ -163,4 +175,94 @@ namespace bayesnet {
}
return yy;
}
template<typename Classifier>
map<std::string, std::vector<int>> Proposal::iterativeLocalDiscretization(
const torch::Tensor& y,
Classifier* classifier,
const torch::Tensor& dataset,
const std::vector<std::string>& features,
const std::string& className,
const map<std::string, std::vector<int>>& initialStates,
Smoothing_t smoothing
)
{
// Phase 1: Initial discretization (same as original)
auto currentStates = fit_local_discretization(y);
auto previousModel = Network();
if (convergence_params.verbose) {
std::cout << "Starting iterative local discretization with "
<< convergence_params.maxIterations << " max iterations" << std::endl;
}
for (int iteration = 0; iteration < convergence_params.maxIterations; ++iteration) {
if (convergence_params.verbose) {
std::cout << "Iteration " << (iteration + 1) << "/" << convergence_params.maxIterations << std::endl;
}
// Phase 2: Build model with current discretization
classifier->fit(dataset, features, className, currentStates, smoothing);
// Phase 3: Network-aware discretization refinement
currentStates = localDiscretizationProposal(currentStates, classifier->model);
// Check convergence
if (iteration > 0 && previousModel == classifier->model) {
if (convergence_params.verbose) {
std::cout << "Converged after " << (iteration + 1) << " iterations" << std::endl;
}
break;
}
// Update for next iteration
previousModel = classifier->model;
}
return currentStates;
}
double Proposal::computeLogLikelihood(Network& model, const torch::Tensor& dataset)
{
double logLikelihood = 0.0;
int n_samples = dataset.size(0);
int n_features = dataset.size(1);
for (int i = 0; i < n_samples; ++i) {
double sampleLogLikelihood = 0.0;
// Get class value for this sample
int classValue = dataset[i][n_features - 1].item<int>();
// Compute log-likelihood for each feature given its parents and class
for (const auto& node : model.getNodes()) {
if (node.first == model.getClassName()) {
// For class node, add log P(class)
auto classCounts = node.second->getCPT();
double classProb = classCounts[classValue].item<double>() / dataset.size(0);
sampleLogLikelihood += std::log(std::max(classProb, 1e-10));
} else {
// For feature nodes, add log P(feature | parents, class)
int featureIdx = std::distance(model.getFeatures().begin(),
std::find(model.getFeatures().begin(),
model.getFeatures().end(),
node.first));
int featureValue = dataset[i][featureIdx].item<int>();
// Simplified probability computation - in practice would need full CPT lookup
double featureProb = 0.1; // Placeholder - would compute from CPT
sampleLogLikelihood += std::log(std::max(featureProb, 1e-10));
}
}
logLikelihood += sampleLogLikelihood;
}
return logLikelihood;
}
// Explicit template instantiation for common classifier types
// template map<std::string, std::vector<int>> Proposal::iterativeLocalDiscretization<Classifier>(
// const torch::Tensor&, Classifier*, const torch::Tensor&, const std::vector<std::string>&,
// const std::string&, const map<std::string, std::vector<int>>&, Smoothing_t);
}