contrib/mul/clsfy/clsfy_binary_pdf_classifier.cxx
Go to the documentation of this file.
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 }