Exemplo n.º 1
0
double DCGCalculator::CalDCGAtK(data_size_t k, const label_t* label,
                                const double* score, data_size_t num_data) {
  // get sorted indices by score
  std::vector<data_size_t> sorted_idx(num_data);
  for (data_size_t i = 0; i < num_data; ++i) {
    sorted_idx[i] = i;
  }
  std::sort(sorted_idx.begin(), sorted_idx.end(),
           [score](data_size_t a, data_size_t b) {return score[a] > score[b]; });

  if (k > num_data) { k = num_data; }
  double dcg = 0.0f;
  // calculate dcg
  for (data_size_t i = 0; i < k; ++i) {
    data_size_t idx = sorted_idx[i];
    dcg += label_gain_[static_cast<int>(label[idx])] * discount_[i];
  }
  return dcg;
}
Exemplo n.º 2
0
void DCGCalculator::CalDCG(const std::vector<data_size_t>& ks, const label_t* label,
                           const double * score, data_size_t num_data, std::vector<double>* out) {
  // get sorted indices by score
  std::vector<data_size_t> sorted_idx(num_data);
  for (data_size_t i = 0; i < num_data; ++i) {
    sorted_idx[i] = i;
  }
  std::sort(sorted_idx.begin(), sorted_idx.end(),
            [score](data_size_t a, data_size_t b) {return score[a] > score[b]; });

  double cur_result = 0.0f;
  data_size_t cur_left = 0;
  // calculate multi dcg by one pass
  for (size_t i = 0; i < ks.size(); ++i) {
    data_size_t cur_k = ks[i];
    if (cur_k > num_data) { cur_k = num_data; }
    for (data_size_t j = cur_left; j < cur_k; ++j) {
      data_size_t idx = sorted_idx[j];
      cur_result += label_gain_[static_cast<int>(label[idx])] * discount_[j];
    }
    (*out)[i] = cur_result;
    cur_left = cur_k;
  }
}
Exemplo n.º 3
0
//
// Get ranks and index of scores
//
// [[Rcpp::export]]
Rcpp::List get_score_ranks(const Rcpp::NumericVector& scores,
                           const bool& na_last,
                           const std::string& ties_method) {

  // Variables
  Rcpp::List ret_val;
  std::string errmsg = "";
  std::vector<int> ranks(scores.size());
  std::vector<int> rank_idx(scores.size());

  // Update NAs
  std::vector<double> svals(scores.size());
  std::vector<int> sorted_idx(scores.size());
  for (int i = 0; i < scores.size(); ++i) {
    if (Rcpp::NumericVector::is_na(scores[i])) {
      if (na_last) {
        svals[i] = DBL_MIN;
      } else {
        svals[i] = DBL_MAX;
      }
    } else {
      svals[i] = scores[i];
    }
    sorted_idx[i] = i;
  }

  // Sort scores
  CompDVec fcomp(svals);
  if (ties_method == "first") {
    std::stable_sort(sorted_idx.begin(), sorted_idx.end(), fcomp);
  } else {
    std::sort(sorted_idx.begin(), sorted_idx.end(), fcomp);
  }

  // Set ranks
  for (unsigned i = 0; i < sorted_idx.size(); ++i) {
     ranks[sorted_idx[i]] = i + 1;
     rank_idx[i] = sorted_idx[i];
  }

  // Update ties
  if (ties_method == "equiv" || ties_method == "random") {
    std::vector<int> tied_idx;
    double prev_val = svals[rank_idx[0]];
    bool tied = false;
    for (unsigned i = 1; i < rank_idx.size(); ++i) {
      if (tied) {
        if (prev_val != svals[rank_idx[i]]) {
          update_ties(ranks, rank_idx, tied_idx, ties_method);
          tied_idx.clear();
          tied = false;
        } else {
          tied_idx.push_back(rank_idx[i]);
        }
      } else if (prev_val == svals[rank_idx[i]]) {
        tied_idx.push_back(rank_idx[i - 1]);
        tied_idx.push_back(rank_idx[i]);
        tied = true;
      }

      prev_val = svals[rank_idx[i]];
    }

    if (tied) {
      update_ties(ranks, rank_idx, tied_idx, ties_method);
    }
  }

  // Add 1 to rank_idx
  for (unsigned i = 0; i < rank_idx.size(); ++i) {
    rank_idx[i] = rank_idx[i] + 1;
  }

  // Return result
  ret_val["ranks"] = ranks;
  ret_val["rank_idx"] = rank_idx;
  ret_val["errmsg"] = errmsg;

  return ret_val;
}