9 #include "spdlog/fmt/fmt.h"
14 m_Labels(sparse_labels), m_Predictions(sparse_predictions), m_NumLabels(num_labels) {
16 throw std::invalid_argument(
"number of predictions does not match number of labels");
25 std::vector<sTrueLabelInfo>& proc_labels, std::vector<sPredLabelInfo>& proc_pred) {
27 proc_labels.reserve(raw_labels.size());
28 std::transform(begin(raw_labels), end(raw_labels), std::back_inserter(proc_labels),
34 for(
long j = 0; j < raw_prediction.size(); ++j) {
36 auto lookup = std::lower_bound(begin(raw_labels), end(raw_labels),
label_id_t{raw_prediction.coeff(j)});
37 bool is_correct =
false;
38 if(lookup != end(raw_labels)) {
40 is_correct = (*lookup) ==
label_id_t{raw_prediction.coeff(j)};
41 proc_labels[std::distance(begin(raw_labels), lookup)].Rank = j;
49 const auto& labels = (*m_Labels)[task_id];
57 c->update(predicted_cache, true_cache);
62 for(
long t = begin; t < end; ++t) {
73 throw std::invalid_argument(
"Cannot calculate top-k precision for k > #predictions");
77 name = fmt::format(
"InstanceP@{}", k);
80 auto collector = std::make_unique<InstanceRankedPositives>(
m_NumLabels, k);
81 m_Metrics.push_back( std::make_unique<InstanceWiseMetricReporter>(name, collector.get()) );
87 throw std::invalid_argument(
"Cannot calculate top-k DCG for k > #predictions");
91 name = fmt::format(
"Instance{}DCG@{}", normalize ?
"n" :
"", k);
94 std::vector<double> weights(k);
95 for(
int i = 0; i < k; ++i) {
97 weights[i] = 1.0 / std::log(2 + i);
100 auto collector = std::make_unique<InstanceRankedPositives>(
m_NumLabels, k, normalize, std::move(weights));
101 m_Metrics.push_back( std::make_unique<InstanceWiseMetricReporter>(name, collector.get()) );
108 throw std::invalid_argument(
"Cannot calculate top-k abandonment for k > #predictions");
112 name = fmt::format(
"Abd@{}", k);
115 auto collector = std::make_unique<AbandonmentAtK>(
m_NumLabels, k);
116 m_Metrics.push_back( std::make_unique<InstanceWiseMetricReporter>(name, collector.get()) );
122 throw std::invalid_argument(
"Cannot calculate top-k abandonment for k > #predictions");
125 auto collector = std::make_unique<ConfusionMatrixRecorder>(
m_NumLabels, k);
126 auto metrics = std::make_unique<MacroMetricReporter>(collector.get());
127 auto* result = metrics.get();
128 m_Metrics.push_back( std::move(metrics) );
135 std::vector<std::pair<std::string, double>> results;
137 auto result = m->get_values();
138 std::copy(begin(result), end(result), std::back_inserter(results));
161 if(thread_id.
to_index() == 0)
return;
165 [](
const auto& other){
166 return other->clone();
Strong typedef for an int to signify a label id.
constexpr T to_index() const
! Explicitly convert to an integer.
Strong typedef for an int to signify a thread id.
const IndexMatrix * m_Predictions
void add_dcg_at_k(long k, bool normalize, std::string name={})
MacroMetricReporter * add_macro_at_k(long k)
std::vector< std::vector< sTrueLabelInfo > > m_ThreadLocalTrueLabels
void prepare(long num_threads, long chunk_size) override
Called to notify the TaskGenerator about the number of threads.
~EvaluateMetrics() override
void add_precision_at_k(long k, std::string name={})
EvaluateMetrics(const LabelList *sparse_labels, const IndexMatrix *sparse_predictions, long num_labels)
void finalize() override
Called after all threads have finished their tasks.
long num_tasks() const override
std::vector< std::vector< std::unique_ptr< MetricCollectionInterface > > > m_Collectors
Eigen::Ref< const Eigen::Matrix< long, 1, Eigen::Dynamic > > prediction_t
void run_tasks(long begin, long end, thread_id_t thread_id) override
std::vector< std::unique_ptr< MetricReportInterface > > m_Metrics
std::vector< std::pair< std::string, double > > get_metrics() const
const LabelList * m_Labels
void add_abandonment_at_k(long k, std::string name={})
void init_thread(thread_id_t thread_id) override
Called once a thread has spun up, but before it runs its first task.
static void process_prediction(const std::vector< label_id_t > &raw_labels, const prediction_t &raw_prediction, std::vector< sTrueLabelInfo > &proc_labels, std::vector< sPredLabelInfo > &proc_pred)
std::vector< std::vector< sPredLabelInfo > > m_ThreadLocalPredictedLabels
std::vector< std::vector< label_id_t > > LabelList
void run_task(long task_id, thread_id_t thread_id)
types::DenseRowMajor< long > IndexMatrix
Matrix used for indices in sparse predictions.
constexpr auto ssize(const C &c) -> std::common_type_t< std::ptrdiff_t, std::make_signed_t< decltype(c.size())>>
signed size free function. Taken from https://en.cppreference.com/w/cpp/iterator/size