/////////////////////////////////////////////////////////////////////////////// // roc_curve.hpp // // Copyright 2005 Hirotaka Niitsuma. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_ACCUMULATORS_STATISTICS_ROC_CURVE_HPP_DE_01_01_2006 #define BOOST_ACCUMULATORS_STATISTICS_ROC_CURVE_HPP_DE_01_01_2006 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace accumulators { /////////////////////////////////////////////////////////////////////////////// // num_cells named parameter // BOOST_PARAMETER_NESTED_KEYWORD(tag, roc_curve_num_cells, num_cells) BOOST_PARAMETER_NESTED_KEYWORD(tag, roc_curve_positive_or_negative, positive_or_negative) namespace impl { /////////////////////////////////////////////////////////////////////////////// // roc_curve_impl // cumulative_distribution calculation (as histogram) /* */ template struct roc_curve_impl : accumulator_base { typedef typename numeric::functional::average::result_type float_type; typedef std::vector > histogram_type; typedef boost::numeric::ublas::matrix result_type; template roc_curve_impl(Args const &args) : num_cells(args[roc_curve_num_cells]) ,sample_float(0) ,acc_positive( boost::accumulators::p_square_cumulative_distribution_num_cells = args[roc_curve_num_cells] ,boost::accumulators::sample = sample_float ) //false_positive_rate ,acc_negative( boost::accumulators::p_square_cumulative_distribution_num_cells = args[roc_curve_num_cells] ,boost::accumulators::sample = sample_float ) //true_negative_rate {} template void operator ()(Args const &args) { positive_or_negative = args[roc_curve_positive_or_negative]; if(positive_or_negative > 0) { this->acc_positive(args[sample]);//false_positive_rate } else { this->acc_negative(args[sample]);//true_negative_rate } } template result_type result(Args const &args) const { boost::iterator_range histogram_positive = boost::accumulators::p_square_cumulative_distribution(this->acc_positive) //false_positive_rate ,histogram_negative = boost::accumulators::p_square_cumulative_distribution(this->acc_negative);//true_negative_rate boost::iterator_range::iterator hit_pos=histogram_positive.begin(),hit_neg=histogram_negative.begin(); result_type mat_tmp(num_cells*3,3); float_type h, vp=0.0, vn=0.0; int icount=0; do { if( hit_pos != histogram_positive.end() && hit_neg != histogram_negative.end() ) { if( hit_pos->first < hit_neg->first ) { h= hit_pos->first; vp= hit_pos->second; hit_pos++; }else if(hit_neg->first < hit_pos->first ) { h= hit_neg->first; vn= hit_neg->second; hit_neg++; } }else{ if( hit_neg != histogram_negative.end() ) { h= hit_neg->first; vn= hit_neg->second; hit_neg++; }else if(hit_pos != histogram_positive.end() ) { h= hit_pos->first; vp= hit_pos->second; hit_pos++; } } float_type tpr=1-vp; //true_positive_rate float_type fnr=1-vn; //false_negative_rate mat_tmp(icount,0)=h; mat_tmp(icount,1)=tpr; mat_tmp(icount,2)=fnr; icount++; }while( hit_pos != histogram_positive.end() || hit_neg != histogram_negative.end() ); result_type mat(icount,3); for(int i=0;i >acc_positive, acc_negative; }; } // namespace detail /////////////////////////////////////////////////////////////////////////////// // tag::roc_curve // namespace tag { struct roc_curve : depends_on , roc_curve_num_cells,roc_curve_positive_or_negative { /// INTERNAL ONLY typedef accumulators::impl::roc_curve_impl impl; }; } /////////////////////////////////////////////////////////////////////////////// // extract::roc_curve // namespace extract { extractor const roc_curve = {}; } using extract::roc_curve; }} // namespace boost::accumulators #endif