Changeset 2556


Ignore:
Timestamp:
Aug 20, 2011, 4:28:52 AM (12 years ago)
Author:
Peter
Message:

ROC: implement correction for ties in large sample approximation o p-value. refs #144.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/roc.cc

    r2551 r2556  
    2525#include "yat/classifier/DataLookupWeighted1D.h"
    2626#include "yat/classifier/Target.h"
     27#include "yat/statistics/Fisher.h"
    2728#include "yat/statistics/ROC.h"
    2829#include "yat/statistics/utility.h"
    2930#include "yat/utility/Vector.h"
    3031
     32#include <cassert>
    3133#include <cmath>
    3234#include <fstream>
     
    3739
    3840void test_ties(test::Suite& suite);
     41void test_p_exact_with_ties(test::Suite& suite);
     42void test_p_approx_with_ties(test::Suite& suite);
    3943
    4044int main(int argc, char* argv[])
     
    96100  add(roc, dlw.begin(), dlw.end(), target);
    97101  test_ties(suite);
    98  
     102  test_p_approx_with_ties(suite);
     103  test_p_exact_with_ties(suite);
     104
    99105  return suite.return_value();
     106}
     107
     108
     109void test_p_exact_with_ties(test::Suite& suite)
     110{
     111  suite.out() << "test p exact with ties\n";
     112  statistics::ROC roc;
     113  /*
     114    +++-- 6
     115    ++-+- 5 4.5 *** our case ***
     116    +-++- 4 4.5
     117    ++--+ 4 3.5
     118    +-+-+ 3 3.5
     119    +--++ 2 2
     120    -+++- 3 3
     121    -++-+ 2 2
     122    -+-++ 1 0.5
     123    --+++ 0 0.5
     124   */
     125  roc.add(2, true);
     126  roc.add(1, true);
     127  roc.add(1, false);
     128  roc.add(0, true);
     129  roc.add(-1, false);
     130  roc.area();
     131  if (!suite.equal(roc.p_value_one_sided(), 3.0/10.0)) {
     132    suite.xadd(false);
     133    suite.out() << "p_value_one_sided: expected 0.3\n";
     134  }
     135  else
     136    suite.xadd(true);
     137  if (!suite.equal(roc.p_value(), 5.0/10.0)) {
     138    suite.xadd(false);
     139    suite.out() << "p_value: expected 0.5\n";
     140  }
     141  else
     142    suite.xadd(true);
     143}
     144
     145
     146void test_p_approx_with_ties(test::Suite& suite)
     147{
     148  suite.out() << "test p approx with ties\n";
     149  statistics::ROC roc;
     150  for (size_t i=0; i<100; ++i) {
     151    roc.add(1, i<60);
     152    roc.add(0, i<40);
     153  }
     154  suite.add(suite.equal(roc.area(), 0.6));
     155  // Having only two data values, 0 and 1, data can be represented as
     156  // a 2x2 contigency table, and ROC test is same as Fisher's exact
     157  // test.
     158  statistics::Fisher fisher;
     159  fisher.oddsratio(60, 40, 40, 60);
     160  suite.add(suite.equal_fix(roc.p_value(), fisher.p_value(), 0.0002));
    100161}
    101162
  • trunk/yat/statistics/ROC.cc

    r2554 r2556  
    2121*/
    2222
     23#include <iostream>
     24
    2325#include "ROC.h"
    2426#include "AUC.h"
     
    2628#include <gsl/gsl_cdf.h>
    2729
     30#include <cassert>
    2831#include <cmath>
    2932#include <utility>
     
    4043  }
    4144
    42   ROC::~ROC(void)
    43   {
    44   }
    45 
    4645
    4746  void ROC::add(double x, bool target, double w)
     
    4948    if (!w)
    5049      return;
    51     multimap_.insert(std::make_pair(x, std::make_pair(target, w)));
     50    typedef std::multimap<double, std::pair<bool, double> > Map;
     51    Map::value_type element(x, std::make_pair(target, w));
     52    Map::iterator lower = multimap_.lower_bound(x);
     53    if (lower!=multimap_.end() && lower->first == x)
     54      has_ties_ = true;
     55    multimap_.insert(lower, element);
     56    //    multimap_.insert(std::make_pair(x, std::make_pair(target, w)));
    5257    if (target)
    5358      w_pos_+=w;
     
    7984    else
    8085      return 0.5;
    81     double sigma = std::sqrt( ( n()+1.0 )/(12*n_pos()*n_neg()) );
    82     return gsl_cdf_gaussian_Q(x, sigma);
     86    double var = 1.0+n();
     87    if (has_ties_) {
     88      double correction = 0;
     89      Map::const_iterator first = multimap_.begin();
     90      Map::const_iterator last = multimap_.begin();
     91      while (first!=multimap_.end()) {
     92        size_t n = 0;
     93        while (first->first == last->first) {
     94          ++n;
     95          ++last;
     96        }
     97        correction += n * (n-1) * (n+1);
     98        first = last;
     99      }
     100      /*
     101        mn(N+1)/12-[mn/(12N(N-1)) * sum(t(t-1)(t+1))] =
     102        mn/12 [ N+1 - 1/(N(N-1)) * sum(t(t-1)(t+1)) ]
     103      */
     104      var -= correction/(n() * (n()-1));
     105    }
     106    var = var / (12*n_pos()*n_neg());
     107    return gsl_cdf_gaussian_Q(x, std::sqrt(var));
    83108  }
    84109
     
    153178  {
    154179    area_=-1;
     180    has_ties_ = false;
    155181    w_pos_=0;
    156182    w_neg_=0;
  • trunk/yat/statistics/ROC.h

    r2553 r2556  
    77  Copyright (C) 2004 Peter Johansson
    88  Copyright (C) 2005, 2006, 2007, 2008 Jari Häkkinen, Peter Johansson
     9  Copyright (C) 2011 Peter Johansson
    910
    1011  This file is part of the yat library, http://dev.thep.lu.se/yat
     
    4647    ///
    4748    ROC(void);
    48          
    49     ///
    50     /// @brief The destructor
    51     ///
    52     virtual ~ROC(void);
    5349         
    5450    /**
     
    136132
    137133    double area_;
     134    bool has_ties_;
    138135    unsigned int minimum_size_;
    139136    double w_neg_;
    140137    double w_pos_;
    141138    // <data pair<class, weight> >
    142     std::multimap<double, std::pair<bool, double> > multimap_;
     139    typedef std::multimap<double, std::pair<bool, double> > Map;
     140    Map multimap_;
    143141  };
    144142
Note: See TracChangeset for help on using the changeset viewer.