72 _resolution = resolution;
75 _use_absences_as_background =
false;
82 _resolution = resolution;
84 _num_background_points = num_background_points;
85 _use_absences_as_background =
false;
92 _resolution = resolution;
94 _num_background_points = 0;
95 _use_absences_as_background = use_absences_as_background;
105 _category.erase( _category.begin(), _category.end() );
106 _prediction.erase( _prediction.begin(), _prediction.end() );
107 _data.erase( _data.begin(), _data.end() );
112 _proportions.erase( _proportions.begin(), _proportions.end() );
113 _proportions.reserve( _resolution );
115 _thresholds.erase( _thresholds.begin(), _thresholds.end() );
116 _thresholds.reserve( _resolution );
119 for (
int i = 0; i < _resolution; i++ ) {
121 _thresholds.push_back(
Scalar(i) / ( _resolution - 1 ) );
122 _proportions.push_back( 0 );
137 model->setNormalization( sampler );
139 _loadPredictions( model, sampler );
141 _calculateGraphPoints();
157 std::string msg =
"No environment specified for the ROC curve\n";
168 std::string msg =
"No presence points specified for the ROC curve\n";
176 int size = presences->numOccurrences();
178 if ( absences && ! absences->isEmpty() ) {
180 if ( _approach == 0 ) {
185 int num_absences = absences->numOccurrences();
187 if ( _approach == 1 ) {
189 size += num_absences;
193 if ( _use_absences_as_background ) {
195 if ( absences->isEmpty() ) {
197 std::string msg =
"Cannot use absences as background points for the ROC curve when no absences are provided\n";
203 _num_background_points = num_absences;
215 if ( _approach == 0 ) {
219 else if ( _approach == 1 ) {
221 std::string msg =
"Cannot calculate traditional ROC curve when no absences are provided\n";
227 if ( _use_absences_as_background ) {
229 std::string msg =
"Cannot use absences as background points for the ROC curve when no absences are provided\n";
238 _category.reserve( size );
239 _prediction.reserve( size );
252 if ( (*it)->hasEnvironment() ) {
254 sample = (*it)->environment();
258 sample = env->get( (*it)->x(), (*it)->y() );
261 if ( sample.
size() > 0 ) {
265 predictionValue = model->getValue( sample );
267 _category.push_back( 1 );
268 _prediction.push_back( predictionValue );
271 ((*it)->id()).c_str(), (*it)->x(), (*it)->y(), predictionValue );
276 ((*it)->id()).c_str() );
284 if ( _approach == 1 ) {
286 it = absences->begin();
287 fin = absences->end();
293 if ( (*it)->hasEnvironment() ) {
295 sample = (*it)->environment();
299 sample = env->get( (*it)->x(), (*it)->y() );
302 if ( sample.
size() > 0 ) {
306 predictionValue = model->getValue( sample );
308 _category.push_back( 0 );
309 _prediction.push_back( predictionValue );
312 ((*it)->id()).c_str(), (*it)->x(), (*it)->y(), predictionValue );
317 ((*it)->id()).c_str() );
325 if ( _use_absences_as_background ) {
327 Log::instance()->
info(
"Using %d absences as background for the ROC curve\n", _num_background_points );
329 it = absences->begin();
330 fin = absences->end();
336 if ( (*it)->hasEnvironment() ) {
338 sample = (*it)->environment();
342 sample = env->get( (*it)->x(), (*it)->y() );
345 if ( sample.
size() > 0 ) {
349 predictionValue = model->getValue( sample );
351 for (
unsigned int j = 0; j < _thresholds.size(); j++ ) {
353 if ( predictionValue < _thresholds[j] ) {
358 _proportions[j] += 1;
369 Log::instance()->
info(
"Generating %d background points\n", _num_background_points );
378 Sample s( env->getRandom( &x, &y ) );
380 prob = model->getValue( s );
382 for (
unsigned int j = 0; j < _thresholds.size(); j++ ) {
384 if ( prob < _thresholds[j] ) {
389 _proportions[j] += 1;
394 }
while ( i < _num_background_points );
398 if ( _approach == 2 ) {
400 for (
unsigned int f = 0; f < _proportions.size(); f++ ) {
402 _proportions[f] /= _num_background_points;
412 int i, j, num_pairs = _prediction.size();
414 if ( _approach == 2 ) {
424 for ( i = 0; i < _resolution; i++ ) {
433 Scalar threshold = _thresholds[i];
438 for ( j = 0; j < num_pairs; j++ ) {
441 bool act_flag = ( _category[j] == 1 );
442 bool prd_flag = ( _prediction[j] >= threshold );
445 if ( act_flag && prd_flag ) {
449 else if ( !act_flag && !prd_flag ) {
453 else if ( !act_flag && prd_flag ) {
464 int num_ap = num_tp + num_fn;
465 int num_pp = num_tp + num_fp;
466 int num_an = num_tn + num_fp;
467 int num_pn = num_tn + num_fn;
468 int num_tt = num_ap + num_an;
470 _true_negatives = num_an;
471 _true_positives = num_ap;
481 if ( sensitivity == -1 ) {
488 if ( specificity == -1 && _approach == 1 ) {
494 std::vector<Scalar> v;
500 if ( _approach == 1 ) {
502 v.push_back(1 - specificity);
507 v.push_back( _proportions[i] );
514 v.push_back(sensitivity);
516 v.push_back(ppvalue);
517 v.push_back(npvalue);
518 v.push_back(accuracy);
519 v.push_back(threshold);
526 std::vector<Scalar> v00;
537 _data.push_back(v00);
539 if ( _approach == 1 ) {
542 std::vector<Scalar> v11;
553 _data.push_back(v11);
559 std::sort( _data.begin(), _data.end(), compare );
569 int i, num_points = numPoints();
572 if ( num_points < 2 ) {
580 for ( i = 1; i < num_points; i++ ) {
582 double x1 = getX(i - 1);
583 double y1 = getY(i - 1);
589 area += (x2 - x1) * 0.5 * (y1 + y2);
606 _calculateTotalArea();
631 double diag_area = 0.0;
633 int i, num_points = numPoints();
636 if ( num_points < 2 ) {
641 map<double, double>::iterator it;
643 it = _ratios.find( e );
645 if ( it != _ratios.end() ) {
650 bool interpolate =
true;
653 for ( i = 1; i < num_points; i++ ) {
655 double x1 = getX(i - 1);
656 double y1 = getY(i - 1);
663 if ( y1 == (1.0 - e) ) {
665 area += (x2 - x1) * 0.5 * (y1 + y2);
667 diag_area += (x2 - x1) * 0.5 * (x1 + x2);
671 else if ( y1 > (1.0 - e) ) {
677 double x0 = getX(i - 2);
678 double y0 = getY(i - 2);
690 x = x1 - ((x1-x0)*(y1-y)/(y1-y0));
694 area += (x1 - x) * 0.5 * (y + y1);
696 diag_area += (x1 - x) * 0.5 * (x + x1);
699 area += (x2 - x1) * 0.5 * (y1 + y2);
701 diag_area += (x2 - x1) * 0.5 * (x1 + x2);
708 area += (x2 - x1) * 0.5 * (y1 + y2);
710 diag_area += (x2 - x1) * 0.5 * (x1 + x2);
718 double ratio = area / diag_area;
721 bool ratio_isnan = (_isnan(ratio) == 1) ?
true :
false;
723 bool ratio_isnan = isnan(ratio);
743 config->addNameValue(
"Auc", _auc );
745 if ( _approach == 2 ) {
747 config->addNameValue(
"NumBackgroundPoints", _num_background_points );
750 int num_points = numPoints();
752 double *tmp_points =
new double[num_points*2];
756 for (
int i = 0; i < num_points; ++i, ++cnt ) {
758 tmp_points[cnt] = getX( i );
762 tmp_points[cnt] = getY( i );
765 config->addNameValue(
"Points", tmp_points, num_points*2 );
767 for ( map<double, double>::const_iterator it = _ratios.begin(); it != _ratios.end(); it++ ) {
771 ratio->addNameValue(
"E", (*it).first );
772 ratio->addNameValue(
"Value", (*it).second );
774 config->addSubsection( ratio );
void initialize(int resolution=ROC_DEFAULT_RESOLUTION)
void warn(const char *format,...)
'Warn' level.
double Scalar
Type of map values.
static Log * instance()
Returns the instance pointer, creating the object on the first call.
void error(const char *format,...)
'Error' level.
void _loadPredictions(const Model &model, const SamplerPtr &sampler)
#define ROC_DEFAULT_BACKGROUND_POINTS
void info(const char *format,...)
'Info' level.
void calculate(const Model &model, const SamplerPtr &sampler)
ConfigurationPtr getConfiguration() const
double Coord
Type of map coordinates.
std::vector< OccurrencePtr >::const_iterator const_iterator
bool _calculateTotalArea()
void debug(const char *format,...)
'Debug' level.
double getPartialAreaRatio(double e=1.0)
void _calculateGraphPoints()