Skip to content

Commit

Permalink
Added multitask ROC evaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
lisitsyn committed Aug 9, 2012
1 parent d699fc5 commit 5e63792
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/interfaces/modular/Transfer.i
Expand Up @@ -29,6 +29,8 @@

%rename(MultitaskCompositeMachine) CMultitaskCompositeMachine;

%rename(MultitaskROCEvaluation) CMultitaskROCEvaluation;

%rename(LibLinearMTL) CLibLinearMTL;

/* Domain adaptation renames */
Expand Down Expand Up @@ -59,6 +61,8 @@

%include <shogun/transfer/multitask/MultitaskCompositeMachine.h>

%include <shogun/transfer/multitask/MultitaskROCEvaluation.h>

%include <shogun/transfer/multitask/LibLinearMTL.h>

/* Domain adaptation includes */
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/modular/Transfer_includes.i
Expand Up @@ -19,6 +19,8 @@
#include <shogun/transfer/multitask/MultitaskTraceLogisticRegression.h>
#include <shogun/transfer/multitask/MultitaskClusteredLogisticRegression.h>

#include <shogun/transfer/multitask/MultitaskROCEvaluation.h>

#ifdef USE_SVMLIGHT
#include <shogun/transfer/domain_adaptation/DomainAdaptationSVM.h>
#endif /* USE_SVMLIGHT */
Expand Down
1 change: 1 addition & 0 deletions src/shogun/evaluation/CrossValidation.cpp
Expand Up @@ -213,6 +213,7 @@ float64_t CCrossValidation::evaluate_one_run(CModelSelectionOutput* ms_output)
m_labels->add_subset(subset_indices);

/* evaluate against own labels */
m_evaluation_criterion->set_indices(subset_indices);
results[i]=m_evaluation_criterion->evaluate(result_labels, m_labels);

if (ms_output)
Expand Down
9 changes: 9 additions & 0 deletions src/shogun/evaluation/Evaluation.h
Expand Up @@ -49,6 +49,15 @@ class CEvaluation: public CSGObject
*/
virtual float64_t evaluate(CLabels* predicted, CLabels* ground_truth) = 0;

/** set absolute indices of labels to be evaluated next
* used by multitask evaluations
*
* @param indices indices
*/
virtual void set_indices(SGVector<index_t> indices)
{
}

/** @return whether criterium has to be maximized or minimized */
virtual EEvaluationDirection get_evaluation_direction()=0;
};
Expand Down
9 changes: 8 additions & 1 deletion src/shogun/evaluation/ROCEvaluation.cpp
Expand Up @@ -18,6 +18,11 @@ CROCEvaluation::~CROCEvaluation()
}

float64_t CROCEvaluation::evaluate(CLabels* predicted, CLabels* ground_truth)
{
return evaluate_roc(predicted,ground_truth);
}

float64_t CROCEvaluation::evaluate_roc(CLabels* predicted, CLabels* ground_truth)
{
ASSERT(predicted && ground_truth);
ASSERT(predicted->get_num_labels()==ground_truth->get_num_labels());
Expand All @@ -38,8 +43,10 @@ float64_t CROCEvaluation::evaluate(CLabels* predicted, CLabels* ground_truth)
int32_t neg_count=0;

// initialize number of labels and labels
SGVector<float64_t> orig_labels = predicted->get_confidences();
SGVector<float64_t> orig_labels(predicted->get_num_labels());
int32_t length = orig_labels.vlen;
for (i=0; i<length; i++)
orig_labels[i] = predicted->get_confidence(i);
float64_t* labels = SGVector<float64_t>::clone_vector(orig_labels.vector, length);

// get sorted indexes
Expand Down
11 changes: 10 additions & 1 deletion src/shogun/evaluation/ROCEvaluation.h
Expand Up @@ -51,7 +51,7 @@ class CROCEvaluation: public CBinaryClassEvaluation
*/
virtual float64_t evaluate(CLabels* predicted, CLabels* ground_truth);

inline EEvaluationDirection get_evaluation_direction()
virtual EEvaluationDirection get_evaluation_direction()
{
return ED_MAXIMIZE;
}
Expand All @@ -71,6 +71,15 @@ class CROCEvaluation: public CBinaryClassEvaluation
*/
SGVector<float64_t> get_thresholds();

protected:

/** evaluate ROC and auROC
* @param predicted labels
* @param ground_truth labels assumed to be correct
* @return auROC
*/
float64_t evaluate_roc(CLabels* predicted, CLabels* ground_truth);

protected:

/** 2-d array used to store ROC graph */
Expand Down
80 changes: 80 additions & 0 deletions src/shogun/transfer/multitask/MultitaskROCEvaluation.cpp
@@ -0,0 +1,80 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2012 Sergey Lisitsyn
*/

#include <shogun/transfer/multitask/MultitaskROCEvaluation.h>
#include <shogun/mathematics/Math.h>

#include <set>
#include <vector>

using namespace std;
using namespace shogun;

void CMultitaskROCEvaluation::set_indices(SGVector<index_t> indices)
{
indices.display_vector("indices");
ASSERT(m_task_relation);

set<index_t> indices_set;
for (int32_t i=0; i<indices.vlen; i++)
indices_set.insert(indices[i]);

if (m_num_tasks>0)
{
for (int32_t t=0; t<m_num_tasks; t++)
m_tasks_indices[t].~SGVector<index_t>();
SG_FREE(m_tasks_indices);
}
m_num_tasks = m_task_relation->get_num_tasks();
m_tasks_indices = SG_MALLOC(SGVector<index_t>, m_num_tasks);

SGVector<index_t>* tasks_indices = m_task_relation->get_tasks_indices();
for (int32_t t=0; t<m_num_tasks; t++)
{
new (&m_tasks_indices[t]) SGVector<index_t>();
vector<index_t> task_indices_cut;
SGVector<index_t> task_indices = tasks_indices[t];
//task_indices.display_vector("task indices");
for (int32_t i=0; i<task_indices.vlen; i++)
{
if (indices_set.count(task_indices[i]))
{
//SG_SPRINT("%d is in %d task\n",task_indices[i],t);
task_indices_cut.push_back(task_indices[i]);
}
}

SGVector<index_t> cutted(task_indices_cut.size());
for (int32_t i=0; i<cutted.vlen; i++)
cutted[i] = task_indices_cut[i];
//cutted.display_vector("cutted");
m_tasks_indices[t] = cutted;
tasks_indices[t].~SGVector<index_t>();
}
SG_FREE(tasks_indices);
}

float64_t CMultitaskROCEvaluation::evaluate(CLabels* predicted, CLabels* ground_truth)
{
//SG_SPRINT("Evaluate\n");
predicted->remove_all_subsets();
ground_truth->remove_all_subsets();
float64_t result = 0.0;
for (int32_t t=0; t<m_num_tasks; t++)
{
//SG_SPRINT("%d task", t);
//m_tasks_indices[t].display_vector();
predicted->add_subset(m_tasks_indices[t]);
ground_truth->add_subset(m_tasks_indices[t]);
result += evaluate_roc(predicted,ground_truth)/m_tasks_indices[t].vlen;
predicted->remove_subset();
ground_truth->remove_subset();
}
return result;
}
102 changes: 102 additions & 0 deletions src/shogun/transfer/multitask/MultitaskROCEvaluation.h
@@ -0,0 +1,102 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2012 Sergey Lisitsyn
*/

#ifndef MULTITASKROCEVALUATION_H_
#define MULTITASKROCEVALUATION_H_

#include <shogun/transfer/multitask/TaskRelation.h>
#include <shogun/evaluation/ROCEvaluation.h>

namespace shogun
{

/** @brief Class MultitaskROCEvalution used to evaluate ROC
* (Receiver Operating Characteristic) and an area
* under ROC curve (auROC) of each task separately.
*
*/
class CMultitaskROCEvaluation: public CROCEvaluation
{
public:
/** constructor */
CMultitaskROCEvaluation() :
CROCEvaluation(), m_task_relation(NULL), m_tasks_indices(NULL),
m_num_tasks(0)
{
}

/** constructor */
CMultitaskROCEvaluation(CTaskRelation* task_relation) :
CROCEvaluation(), m_task_relation(NULL), m_tasks_indices(NULL),
m_num_tasks(0)
{
set_task_relation(task_relation);
}

/** destructor */
virtual ~CMultitaskROCEvaluation()
{
for (int32_t i=0; i<m_num_tasks; i++)
m_tasks_indices[i].~SGVector<index_t>();
SG_FREE(m_tasks_indices);
}

/** set task relation */
void set_task_relation(CTaskRelation* task_relation)
{
SG_REF(task_relation);
SG_UNREF(m_task_relation);
m_task_relation = task_relation;
}

/** get task relation */
CTaskRelation* get_task_relation() const
{
SG_REF(m_task_relation);
return m_task_relation;
}

/** set absolute indices of labels to be evaluated next
* used by multitask evaluations
*
* @param indices indices
*/
virtual void set_indices(SGVector<index_t> indices);

/** get name */
virtual const char* get_name() const { return "MultitaskROCEvaluation"; };

/** evaluate ROC and auROC
* @param predicted labels
* @param ground_truth labels assumed to be correct
* @return auROC
*/
virtual float64_t evaluate(CLabels* predicted, CLabels* ground_truth);

/** get evaluation direction */
virtual EEvaluationDirection get_evaluation_direction()
{
return ED_MAXIMIZE;
}

protected:

/** task relation */
CTaskRelation* m_task_relation;

/** indices */
SGVector<index_t>* m_tasks_indices;

/** num tasks */
int32_t m_num_tasks;
};

}

#endif /* MULTITASKROCEVALUATION_H_ */

0 comments on commit 5e63792

Please sign in to comment.