<commit_before>#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include <cmath> // sqrt
#include "oll.hpp"

namespace oll_tool{  
  int trainFile(const char* trainfile, const char* modelfile, const trainMethod tm, 
		const float C, const float bias, const int iter, bool verb, bool shuffle){
    oll ol;
    ol.setC(C);
    ol.setBias(bias);
    
    bool error = false;
    if (tm == P){
      P_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == AP){
      AP_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == PA){
      PA_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == PA1){
      PA1_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == PA2){
      PA2_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == PAK){
      PAK_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == CW){
      CW_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == AL){
      AL_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else {
      if (verb){
	std::cerr << "unknown trainMethod" << std::endl;
      }
      return -1;
    }

    if (error){
      if (verb){
	std::cerr << ol.getErrorLog() << std::endl;
      }
      return -1;
    }

    if (ol.save(modelfile) == -1){
      if (verb){
	std::cerr << ol.getErrorLog() << std::endl;
      }
      return -1;
    }
    return 0;
  }

  int testFile (const char* testfile, const char* modelfile, std::vector<int>& confMat, int verb){
    oll ol;
    if (ol.load(modelfile) == -1){
      if (verb){
	std::cerr << ol.getErrorLog() << std::endl;
      }
      return -1;
    }

    bool verb2 = false;
    if (verb == 2) verb2 = true;
    
    if (ol.testFile(testfile, confMat, verb2) == -1){
      if (verb){
	std::cerr << ol.getErrorLog() << std::endl;
      }
      return -1;
    }

    if (verb2){
      std::cout << ol.getResultLog();
    }

    if (verb >= 1){
      const int correctNum = confMat[0] + confMat[3];
      const int num        = confMat[0] + confMat[1] + confMat[2] + confMat[3];
      printf("Accuracy %.3f%% (%d/%d)\n"
	     "(Answer, Predict): (p,p):%d (p,n):%d (n,p):%d (n,n):%d\n", (float)correctNum*100.f/num, correctNum, num, 
	     confMat[0], confMat[1], confMat[2], confMat[3]);
    }

    return 0;
  }

  int oll::parseLine(const std::string& line, fv_t& fv, int& y){
    std::istringstream is(line);
    if (!(is >> y)){
      errorLog << "parse error: no label ";
      return -1;
    }
    
    if (y != 1 &&
	y != -1){
      errorLog << "parse error: y is not +1 nor -1 ";
    }
    
    int  id = 0;
    char sep = 0;
    float val = 0.f;
    while (is >> id >> sep >> val){
      fv.push_back(std::make_pair(id, val));
    }
    return 0;
  }


  oll::oll() : exampleN(0), featureN(0), updateN(0), C(1.f), bias(0.f), b(0.f), b0(0.f), ba(0.f), covb(0.f) {}
  oll::~oll() {}

  void oll::setC(const float C_){
    C = C_;
  }
  
  void oll::setBias(const float bias_){
    bias = bias_;
  }

  float oll::getMargin(const fvec& v, const float bias_, const fv_t& fv) const {
    float ret = bias_;
    for (size_t i = 0; i < fv.size(); i++){
      if (v.size() <= fv[i].first) continue;
      ret += v[fv[i].first] * fv[i].second;
    }
    return ret;
  }

  float oll::getMarginK(const fv_t& fv) { // kernel
    for (size_t i = 0; i < margins.size(); i++){
      margins[i] = 0.f;
    }

    for (size_t i = 0; i < fv.size(); i++){
      const int id = fv[i].first;
      const float val = fv[i].second;
      if (id >= inv_svs.size()) continue;
      const fv_t& ifv = inv_svs[id];
      for (size_t j = 0; j < ifv.size(); j++){
	margins[ifv[j].first] += ifv[j].second * val;
      }
    }

    float ret = 0.f;
    for (size_t i = 0; i < margins.size(); i++){
      ret += (margins[i] * margins[i]) * alphas[i]; // 2nd polynomial
    }
    return ret;
  }

  float oll::getVariance(const fv_t& fv) const{
    float ret = 0.f;
    for (size_t i = 0; i < fv.size(); i++){
      if (cov.size() <= fv[i].first){
	ret += 1.f * fv[i].second * fv[i].second; // assume cov[fv[i].first=1
      } else {
	ret += cov[fv[i].first] * fv[i].second * fv[i].second;
      }
    }
    return ret;
  }

  float oll::getNorm(const fv_t& fv) const{
    float ret = 1.f; // bias
    for (size_t i = 0; i < fv.size(); i++){
      ret += fv[i].second * fv[i].second;
    }
    return ret;
  }

  void oll::update(fvec& v, const fv_t& fv, const float alpha) {
    for (size_t i = 0; i < fv.size(); i++){
      if (v.size() <= fv[i].first) v.resize(fv[i].first+1);
      v[fv[i].first] += fv[i].second * alpha;
    }
    b += alpha * bias;
    updateN++;
  }


  // perceptron
  template <>
  void oll::trainExample(const P_s& a, const fv_t& fv, const int y) {
    const float score = getMargin(w, b, fv) * y;
    printf("score:%f\n", score);
    if (score <= 0.f){
      update(w, fv, y);
    }
    exampleN++;
  }
  
  // averaged perceptron
  template <>
  void oll::trainExample(const AP_s& a, const fv_t& fv, const int y) {
    const float score = getMargin(w0, b0, fv) * y;
    if (score <= 0.f){
      update(w0, fv, y);
      update(wa, fv, y * (exampleN+1.f));
    }
    exampleN++;
  }

  // passive agressive
  template <>
  void oll::trainExample(const PA_s& a, const fv_t& fv, const int y) {
    const float score = getMargin(w, b, fv) * y;
    if (score <= 1.f){<commit_msg>suppress print in perceptron training<commit_after>#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include <cmath> // sqrt
#include "oll.hpp"

namespace oll_tool{  
  int trainFile(const char* trainfile, const char* modelfile, const trainMethod tm, 
		const float C, const float bias, const int iter, bool verb, bool shuffle){
    oll ol;
    ol.setC(C);
    ol.setBias(bias);
    
    bool error = false;
    if (tm == P){
      P_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == AP){
      AP_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == PA){
      PA_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == PA1){
      PA1_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == PA2){
      PA2_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == PAK){
      PAK_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == CW){
      CW_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else if (tm == AL){
      AL_s a;
      if (ol.trainFile(a, trainfile, iter, verb, shuffle) == -1) error = true;
    } else {
      if (verb){
	std::cerr << "unknown trainMethod" << std::endl;
      }
      return -1;
    }

    if (error){
      if (verb){
	std::cerr << ol.getErrorLog() << std::endl;
      }
      return -1;
    }

    if (ol.save(modelfile) == -1){
      if (verb){
	std::cerr << ol.getErrorLog() << std::endl;
      }
      return -1;
    }
    return 0;
  }

  int testFile (const char* testfile, const char* modelfile, std::vector<int>& confMat, int verb){
    oll ol;
    if (ol.load(modelfile) == -1){
      if (verb){
	std::cerr << ol.getErrorLog() << std::endl;
      }
      return -1;
    }

    bool verb2 = false;
    if (verb == 2) verb2 = true;
    
    if (ol.testFile(testfile, confMat, verb2) == -1){
      if (verb){
	std::cerr << ol.getErrorLog() << std::endl;
      }
      return -1;
    }

    if (verb2){
      std::cout << ol.getResultLog();
    }

    if (verb >= 1){
      const int correctNum = confMat[0] + confMat[3];
      const int num        = confMat[0] + confMat[1] + confMat[2] + confMat[3];
      printf("Accuracy %.3f%% (%d/%d)\n"
	     "(Answer, Predict): (p,p):%d (p,n):%d (n,p):%d (n,n):%d\n", (float)correctNum*100.f/num, correctNum, num, 
	     confMat[0], confMat[1], confMat[2], confMat[3]);
    }

    return 0;
  }

  int oll::parseLine(const std::string& line, fv_t& fv, int& y){
    std::istringstream is(line);
    if (!(is >> y)){
      errorLog << "parse error: no label ";
      return -1;
    }
    
    if (y != 1 &&
	y != -1){
      errorLog << "parse error: y is not +1 nor -1 ";
    }
    
    int  id = 0;
    char sep = 0;
    float val = 0.f;
    while (is >> id >> sep >> val){
      fv.push_back(std::make_pair(id, val));
    }
    return 0;
  }


  oll::oll() : exampleN(0), featureN(0), updateN(0), C(1.f), bias(0.f), b(0.f), b0(0.f), ba(0.f), covb(0.f) {}
  oll::~oll() {}

  void oll::setC(const float C_){
    C = C_;
  }
  
  void oll::setBias(const float bias_){
    bias = bias_;
  }

  float oll::getMargin(const fvec& v, const float bias_, const fv_t& fv) const {
    float ret = bias_;
    for (size_t i = 0; i < fv.size(); i++){
      if (v.size() <= fv[i].first) continue;
      ret += v[fv[i].first] * fv[i].second;
    }
    return ret;
  }

  float oll::getMarginK(const fv_t& fv) { // kernel
    for (size_t i = 0; i < margins.size(); i++){
      margins[i] = 0.f;
    }

    for (size_t i = 0; i < fv.size(); i++){
      const int id = fv[i].first;
      const float val = fv[i].second;
      if (id >= inv_svs.size()) continue;
      const fv_t& ifv = inv_svs[id];
      for (size_t j = 0; j < ifv.size(); j++){
	margins[ifv[j].first] += ifv[j].second * val;
      }
    }

    float ret = 0.f;
    for (size_t i = 0; i < margins.size(); i++){
      ret += (margins[i] * margins[i]) * alphas[i]; // 2nd polynomial
    }
    return ret;
  }

  float oll::getVariance(const fv_t& fv) const{
    float ret = 0.f;
    for (size_t i = 0; i < fv.size(); i++){
      if (cov.size() <= fv[i].first){
	ret += 1.f * fv[i].second * fv[i].second; // assume cov[fv[i].first=1
      } else {
	ret += cov[fv[i].first] * fv[i].second * fv[i].second;
      }
    }
    return ret;
  }

  float oll::getNorm(const fv_t& fv) const{
    float ret = 1.f; // bias
    for (size_t i = 0; i < fv.size(); i++){
      ret += fv[i].second * fv[i].second;
    }
    return ret;
  }

  void oll::update(fvec& v, const fv_t& fv, const float alpha) {
    for (size_t i = 0; i < fv.size(); i++){
      if (v.size() <= fv[i].first) v.resize(fv[i].first+1);
      v[fv[i].first] += fv[i].second * alpha;
    }
    b += alpha * bias;
    updateN++;
  }


  // perceptron
  template <>
  void oll::trainExample(const P_s& a, const fv_t& fv, const int y) {
    const float score = getMargin(w, b, fv) * y;
    if (score <= 0.f){
      update(w, fv, y);
    }
    exampleN++;
  }
  
  // averaged perceptron
  template <>
  void oll::trainExample(const AP_s& a, const fv_t& fv, const int y) {
    const float score = getMargin(w0, b0, fv) * y;
    if (score <= 0.f){
      update(w0, fv, y);
      update(wa, fv, y * (exampleN+1.f));
    }
    exampleN++;
  }

  // passive agressive
  template <>
  void oll::trainExample(const PA_s& a, const fv_t& fv, const int y) {
    const float score = getMargin(w, b, fv) * y;
    if (score <= 1.f){
{'fraction_non_alphanumeric': 0.1871092718147398, 'fraction_numerical': 0.014792638901118253, 'mean_word_length': 2.303664921465969, 'pattern_counts': {'":': 0, '<': 101, '<?xml version=': 0, '>': 41, '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': '2164207', 'n_tokens_mistral': 4709, 'n_tokens_neox': 4565, 'n_words': 1213}