# LCOV - BayesNet Coverage Report - bayesnet/feature_selection/FeatureSelect.cc

LCOV - code coverage report

Current view: | top level - bayesnet/feature_selection - FeatureSelect.cc (source / functions) |  |  | Coverage | Total | Hit
Test: | BayesNet Coverage Report |  | Lines: | 100.0 % | 44 | 44
Test Date: | 2024-05-06 17:54:04 |  | Functions: | 100.0 % | 8 | 8
Legend: | Lines: hit not hit |

                Line data    Source code

           1              : // ***************************************************************
           2              : // SPDX-FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
           3              : // SPDX-FileType: SOURCE
           4              : // SPDX-License-Identifier: MIT
           5              : // ***************************************************************
           6              :
           7              : #include <limits>
           8              : #include "bayesnet/utils/bayesnetUtils.h"
           9              : #include "FeatureSelect.h"
          10              : namespace bayesnet {
          11          221 :     FeatureSelect::FeatureSelect(const torch::Tensor& samples, const std::vector<std::string>& features, const std::string& className, const int maxFeatures, const int classNumStates, const torch::Tensor& weights) :
          12          221 :         Metrics(samples, features, className, classNumStates), maxFeatures(maxFeatures == 0 ? samples.size(0) - 1 : maxFeatures), weights(weights)
          13              :
          14              :     {
          15          221 :     }
          16          151 :     void FeatureSelect::initialize()
          17              :     {
          18          151 :         selectedFeatures.clear();
          19          151 :         selectedScores.clear();
          20          151 :     }
          21         3728 :     double FeatureSelect::symmetricalUncertainty(int a, int b)
          22              :     {
          23              :         /*
          24              :         Compute symmetrical uncertainty. Normalize* information gain (mutual
          25              :         information) with the entropies of the features in order to compensate
          26              :         the bias due to high cardinality features. *Range [0, 1]
          27              :         (https://www.sciencedirect.com/science/article/pii/S0020025519303603)
          28              :         */
          29        11184 :         auto x = samples.index({ a, "..." });
          30        11184 :         auto y = samples.index({ b, "..." });
          31         3728 :         auto mu = mutualInformation(x, y, weights);
          32         3728 :         auto hx = entropy(x, weights);
          33         3728 :         auto hy = entropy(y, weights);
          34         3728 :         return 2.0 * mu / (hx + hy);
          35        11184 :     }
          36          151 :     void FeatureSelect::computeSuLabels()
          37              :     {
          38              :         // Compute Simmetrical Uncertainty between features and labels
          39              :         // https://en.wikipedia.org/wiki/Symmetric_uncertainty
          40         1258 :         for (int i = 0; i < features.size(); ++i) {
          41         1107 :             suLabels.push_back(symmetricalUncertainty(i, -1));
          42              :         }
          43          151 :     }
          44         7921 :     double FeatureSelect::computeSuFeatures(const int firstFeature, const int secondFeature)
          45              :     {
          46              :         // Compute Simmetrical Uncertainty between features
          47              :         // https://en.wikipedia.org/wiki/Symmetric_uncertainty
          48              :         try {
          49         7921 :             return suFeatures.at({ firstFeature, secondFeature });
          50              :         }
          51         2621 :         catch (const std::out_of_range& e) {
          52         2621 :             double result = symmetricalUncertainty(firstFeature, secondFeature);
          53         2621 :             suFeatures[{firstFeature, secondFeature}] = result;
          54         2621 :             return result;
          55         2621 :         }
          56              :     }
          57         1239 :     double FeatureSelect::computeMeritCFS()
          58              :     {
          59         1239 :         double rcf = 0;
          60         5693 :         for (auto feature : selectedFeatures) {
          61         4454 :             rcf += suLabels[feature];
          62              :         }
          63         1239 :         double rff = 0;
          64         1239 :         int n = selectedFeatures.size();
          65         8154 :         for (const auto& item : doCombinations(selectedFeatures)) {
          66         6915 :             rff += computeSuFeatures(item.first, item.second);
          67         1239 :         }
          68         1239 :         return rcf / sqrt(n + (n * n - n) * rff);
          69              :     }
          70          171 :     std::vector<int> FeatureSelect::getFeatures() const
          71              :     {
          72          171 :         if (!fitted) {
          73           20 :             throw std::runtime_error("FeatureSelect not fitted");
          74              :         }
          75          151 :         return selectedFeatures;
          76              :     }
          77          156 :     std::vector<double> FeatureSelect::getScores() const
          78              :     {
          79          156 :         if (!fitted) {
          80           20 :             throw std::runtime_error("FeatureSelect not fitted");
          81              :         }
          82          136 :         return selectedScores;
          83              :     }
          84              : }

Generated by: LCOV version 2.0-1