00001 // This is mul/clsfy/clsfy_binary_pdf_classifier.cxx 00002 // Copyright: (C) 2000 British Telecommunications PLC 00003 #include "clsfy_binary_pdf_classifier.h" 00004 //: 00005 // \file 00006 00007 #include <vcl_string.h> 00008 #include <vcl_cmath.h> 00009 #include <vcl_iostream.h> 00010 #include <vcl_vector.h> 00011 #include <vnl/io/vnl_io_vector.h> 00012 #include <vsl/vsl_binary_loader.h> 00013 #include <vcl_cassert.h> 00014 00015 //======================================================================= 00016 00017 void clsfy_binary_pdf_classifier::deleteStuff() 00018 { 00019 delete pdf_; 00020 pdf_ = 0; 00021 } 00022 00023 //======================================================================= 00024 00025 //: Classify the input vector 00026 // Returns either class1 (Inside PDF mode) or class 0 (Outside PDF mode). 00027 unsigned clsfy_binary_pdf_classifier::classify(const vnl_vector<double> &input) const 00028 { 00029 assert(pdf_!=0); 00030 00031 if (pdf_->log_p(input) >= log_prob_limit_) 00032 return 1; 00033 else 00034 return 0; 00035 } 00036 00037 //======================================================================= 00038 00039 //: Return the probability the input being in each class P(class|data). 00040 // output(i) i<n_classes, contains the probability that the input is in class i 00041 // 00042 void clsfy_binary_pdf_classifier::class_probabilities( 00043 vcl_vector<double> &outputs, 00044 const vnl_vector<double> &input) const 00045 { 00046 // likelihood = P(input|InClass) / prob_limit_ 00047 double likelihood= vcl_exp(log_l(input)); 00048 outputs.resize(1); 00049 outputs[0] = likelihood / (1 + likelihood); 00050 } 00051 00052 //======================================================================= 00053 00054 //: Log likelihood of being in class 0. log(P(class=0|data)) 00055 // This function is intended for use in binary classifiers only. It is 00056 // related to the class 0 probability as follows, 00057 // P(class=0|data) = exp(logL) / (1+exp(logL)). 00058 // Don't forget that P(X|data) is a density and so the result can be 00059 // greater than 1.0 or less than 0.0, (or indeed between 0.0 and 1.0). 00060 double clsfy_binary_pdf_classifier::log_l(const vnl_vector<double> &input) const 00061 { 00062 assert(pdf_!=0); 00063 00064 // likelihood = P(input|InClass) / prob_limit_ 00065 return pdf_->log_p(input) - log_prob_limit_; 00066 } 00067 00068 //======================================================================= 00069 00070 vcl_string clsfy_binary_pdf_classifier::is_a() const 00071 { 00072 return vcl_string("clsfy_binary_pdf_classifier"); 00073 } 00074 00075 //======================================================================= 00076 00077 bool clsfy_binary_pdf_classifier::is_class(vcl_string const& s) const 00078 { 00079 return s == clsfy_binary_pdf_classifier::is_a() || clsfy_classifier_base::is_class(s); 00080 } 00081 00082 //======================================================================= 00083 00084 short clsfy_binary_pdf_classifier::version_no() const 00085 { 00086 return 1; 00087 } 00088 00089 //======================================================================= 00090 00091 // required if data is present in this class 00092 void clsfy_binary_pdf_classifier::print_summary(vcl_ostream& os) const 00093 { 00094 os << "log Probability limit, " << log_prob_limit_ << " ,PDF " << pdf_; 00095 } 00096 00097 //======================================================================= 00098 00099 clsfy_classifier_base* clsfy_binary_pdf_classifier::clone() const 00100 { 00101 return new clsfy_binary_pdf_classifier(*this); 00102 } 00103 00104 //======================================================================= 00105 00106 clsfy_binary_pdf_classifier& clsfy_binary_pdf_classifier::operator=(const clsfy_binary_pdf_classifier& classifier) 00107 { 00108 if (&classifier==this) return *this; 00109 00110 clsfy_classifier_base::operator=(classifier); 00111 00112 deleteStuff(); 00113 00114 if (classifier.pdf_) 00115 pdf_ = classifier.pdf_->clone(); 00116 00117 log_prob_limit_ = classifier.log_prob_limit_; 00118 00119 return *this; 00120 } 00121 00122 00123 //======================================================================= 00124 00125 void clsfy_binary_pdf_classifier::b_write(vsl_b_ostream& bfs) const 00126 { 00127 vsl_b_write(bfs,version_no()); 00128 vsl_b_write(bfs,log_prob_limit_); 00129 vsl_b_write(bfs,pdf_); 00130 } 00131 00132 //======================================================================= 00133 00134 void clsfy_binary_pdf_classifier::b_read(vsl_b_istream& bfs) 00135 { 00136 if (!bfs) return; 00137 00138 short version; 00139 vsl_b_read(bfs,version); 00140 switch (version) 00141 { 00142 case (1): 00143 vsl_b_read(bfs,log_prob_limit_); 00144 vsl_b_read(bfs,pdf_); 00145 break; 00146 default: 00147 vcl_cerr << "I/O ERROR: clsfy_binary_pdf_classifier::b_read(vsl_b_istream&)\n" 00148 << " Unknown version number "<< version << "\n"; 00149 bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream 00150 } 00151 }