<commit_before>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
 */
#include <sstream>
#include <float.h>
#include "reductions.h"
#include "vw.h"

struct oaa{
  size_t k;
};

template <bool is_learn>
void predict_or_learn(oaa& o, LEARNER::base_learner& base, example& ec) {
  MULTILABEL::labels multilabels = ec.l.multilabels;
  MULTILABEL::labels preds = ec.pred.multilabels;
  preds.label_v.erase();

  ec.l.simple = {FLT_MAX, 1.f, 0.f};
  uint32_t multilabel_index = 0;
  for (uint32_t i = 0; i < o.k; i++) {
    if (is_learn) {
      ec.l.simple.label = -1.f;
      if (multilabels.label_v.size() > multilabel_index 
	  && multilabels.label_v[multilabel_index] == i)
	{
	  ec.l.simple.label = 1.f;
	  multilabel_index++;
	}
      base.learn(ec, i);
    } else
      base.predict(ec, i);
    
    if (ec.pred.scalar > 0.) 
      preds.label_v.push_back(i);
  }
  if (multilabel_index < multilabels.label_v.size())
    cout << "label " << multilabels.label_v[multilabel_index] << " is not in {0,"<< o.k-1 << "} This won't work right." << endl;    
  
  ec.pred.multilabels = preds;
  ec.l.multilabels = multilabels;
}

  void finish_example(vw& all, oaa& c, example& ec)
  {
    MULTILABEL::output_example(all, ec);
    VW::finish_example(all, &ec);
  }

LEARNER::base_learner* multilabel_oaa_setup(vw& all)
{
  if (missing_option<size_t, true>(all, "multilabel_oaa", "One-against-all multilabel with <k> labels")) 
    return NULL;
  
  oaa& data = calloc_or_die<oaa>();
  data.k = all.vm["multilabel_oaa"].as<size_t>();
  
  LEARNER::learner<oaa>& l = LEARNER::init_learner(&data, setup_base(all), predict_or_learn<true>, 
						   predict_or_learn<false>, data.k);
  l.set_finish_example(finish_example);
  all.p->lp = MULTILABEL::multilabel;

  return make_base(l);
}
<commit_msg>multilabel works with predictions<commit_after>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
 */
#include <sstream>
#include <float.h>
#include "reductions.h"
#include "vw.h"

struct oaa{
  size_t k;
};

template <bool is_learn>
void predict_or_learn(oaa& o, LEARNER::base_learner& base, example& ec) {
  MULTILABEL::labels multilabels = ec.l.multilabels;
  MULTILABEL::labels preds = ec.pred.multilabels;
  preds.label_v.erase();

  ec.l.simple = {FLT_MAX, 1.f, 0.f};
  uint32_t multilabel_index = 0;
  for (uint32_t i = 0; i < o.k; i++) {
    if (is_learn) {
      ec.l.simple.label = -1.f;
      if (multilabels.label_v.size() > multilabel_index 
	  && multilabels.label_v[multilabel_index] == i)
	{
	  ec.l.simple.label = 1.f;
	  multilabel_index++;
	}
      base.learn(ec, i);
    } else
      base.predict(ec, i);
    if (ec.pred.scalar > 0.) 
      preds.label_v.push_back(i);
  }
  if (is_learn && multilabel_index < multilabels.label_v.size())
    cout << "label " << multilabels.label_v[multilabel_index] << " is not in {0," << o.k-1 << "} This won't work right." << endl;

  ec.pred.multilabels = preds;
  ec.l.multilabels = multilabels;
}

  void finish_example(vw& all, oaa& c, example& ec)
  {
    MULTILABEL::output_example(all, ec);
    VW::finish_example(all, &ec);
  }

LEARNER::base_learner* multilabel_oaa_setup(vw& all)
{
  if (missing_option<size_t, true>(all, "multilabel_oaa", "One-against-all multilabel with <k> labels")) 
    return NULL;
  
  oaa& data = calloc_or_die<oaa>();
  data.k = all.vm["multilabel_oaa"].as<size_t>();
  
  LEARNER::learner<oaa>& l = LEARNER::init_learner(&data, setup_base(all), predict_or_learn<true>, 
						   predict_or_learn<false>, data.k);
  l.set_finish_example(finish_example);
  all.p->lp = MULTILABEL::multilabel;

  return make_base(l);
}

{'fraction_non_alphanumeric': 0.15265600825167613, 'fraction_numerical': 0.006704486848891181, 'mean_word_length': 3.8609022556390977, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6320665', 'n_tokens_mistral': 1614, 'n_tokens_neox': 1533, 'n_words': 310}