// *************************************************************** // SPDX-FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez // SPDX-FileType: SOURCE // SPDX-License-Identifier: MIT // *************************************************************** #ifndef XSPODE_H #define XSPODE_H #include #include #include "Classifier.h" #include "bayesnet/utils/CountingSemaphore.h" namespace bayesnet { class XSpode : public Classifier { public: explicit XSpode(int spIndex); std::vector predict_proba(const std::vector& instance) const; std::vector> predict_proba(std::vector>& X) override; int predict(const std::vector& instance) const; void normalize(std::vector& v) const; std::string to_string() const; int getNFeatures() const; int getNumberOfNodes() const override; int getNumberOfEdges() const override; int getNumberOfStates() const override; int getClassNumStates() const override; std::vector& getStates(); std::vector graph(const std::string& title) const override { return std::vector({ title }); } void fitx(torch::Tensor& X, torch::Tensor& y, torch::Tensor& weights_, const Smoothing_t smoothing); void setHyperparameters(const nlohmann::json& hyperparameters_) override; // // Classifier interface // torch::Tensor predict(torch::Tensor& X) override; std::vector predict(std::vector>& X) override; torch::Tensor predict_proba(torch::Tensor& X) override; float score(torch::Tensor& X, torch::Tensor& y) override; float score(std::vector>& X, std::vector& y) override; protected: void buildModel(const torch::Tensor& weights) override; void trainModel(const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing) override; private: void addSample(const std::vector& instance, double weight); void computeProbabilities(); int superParent_; int nFeatures_; int statesClass_; std::vector states_; // [states_feat0, ..., states_feat(N-1)] (class not included in this array) // Class counts std::vector classCounts_; // [c], accumulative std::vector classPriors_; // [c], after normalization // For p(x_sp = spVal | c) std::vector spFeatureCounts_; // [spVal * statesClass_ + c] std::vector spFeatureProbs_; // same shape, after normalization // For p(x_child = childVal | x_sp = spVal, c) // childCounts_ is big enough to hold all child features except sp: // For each child f, we store childOffsets_[f] as the start index, then // childVal, spVal, c => the data. std::vector childCounts_; std::vector childProbs_; std::vector childOffsets_; double alpha_ = 1.0; double initializer_; // for numerical stability CountingSemaphore& semaphore_; }; } #endif // XSPODE_H