contrib/mul/clsfy/clsfy_random_builder.cxx
Go to the documentation of this file.
00001 // This is mul/clsfy/clsfy_random_builder.cxx
00002 // Copyright (c) 2001: British Telecommunications plc
00003 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00004 #pragma implementation
00005 #endif
00006 //:
00007 // \file
00008 // \brief Implement a random classifier builder
00009 // \author Ian Scott
00010 // \date 2001-10-08
00011 
00012 #include "clsfy_random_builder.h"
00013 
00014 #include <vcl_iostream.h>
00015 #include <vcl_string.h>
00016 #include <vcl_cassert.h>
00017 #include <vsl/vsl_binary_loader.h>
00018 #include <clsfy/clsfy_random_classifier.h>
00019 #include <vnl/vnl_c_vector.h>
00020 
00021 //=======================================================================
00022 
00023 clsfy_random_builder::clsfy_random_builder():
00024 confidence_(0.0)
00025 {}
00026 
00027 //=======================================================================
00028 
00029 short clsfy_random_builder::version_no() const
00030 {
00031   return 1;
00032 }
00033 
00034 //=======================================================================
00035 
00036 vcl_string clsfy_random_builder::is_a() const
00037 {
00038   return vcl_string("clsfy_random_builder");
00039 }
00040 
00041 //=======================================================================
00042 
00043 bool clsfy_random_builder::is_class(vcl_string const& s) const
00044 {
00045   return s == clsfy_random_builder::is_a() || clsfy_builder_base::is_class(s);
00046 }
00047 
00048 //=======================================================================
00049 
00050 clsfy_builder_base* clsfy_random_builder::clone() const
00051 {
00052   return new clsfy_random_builder(*this);
00053 }
00054 
00055 //=======================================================================
00056 
00057 void clsfy_random_builder::print_summary(vcl_ostream& os) const
00058 {
00059   os << "confidence = " << confidence_;
00060 }
00061 
00062 //=======================================================================
00063 
00064 void clsfy_random_builder::b_write(vsl_b_ostream& bfs) const
00065 {
00066   vsl_b_write(bfs, version_no());
00067   vsl_b_write(bfs, confidence_);
00068 }
00069 
00070 //=======================================================================
00071 
00072 void clsfy_random_builder::b_read(vsl_b_istream& bfs)
00073 {
00074   if (!bfs) return;
00075 
00076   short version;
00077   vsl_b_read(bfs,version);
00078   switch (version)
00079   {
00080   case (1):
00081     vsl_b_read(bfs, confidence_);
00082     break;
00083   default:
00084     vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, clsfy_random_builder&)\n"
00085              << "           Unknown version number "<< version << '\n';
00086     bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00087   }
00088 }
00089 
00090 //=======================================================================
00091 
00092 //: Build model from data
00093 // return the mean error over the training set.
00094 // For many classifiers, you may use nClasses==1 to
00095 // indicate a binary classifier
00096 double clsfy_random_builder::build(clsfy_classifier_base& model,
00097                                    mbl_data_wrapper<vnl_vector<double> >& inputs,
00098                                    unsigned nClasses,
00099                                    const vcl_vector<unsigned> &outputs) const
00100 {
00101   const unsigned n = outputs.size();
00102   assert(model.is_class("clsfy_random_classifier"));
00103   clsfy_random_classifier &randclass = (clsfy_random_classifier&) model;
00104 
00105   if (nClasses==1) nClasses=2;
00106 
00107   assert (n>0);
00108 
00109   vcl_vector<unsigned> freqs(nClasses);
00110   for (unsigned i=0; i < n; ++i)
00111   {
00112     assert (outputs[i] < nClasses);
00113     freqs[outputs[i]] ++;
00114   }
00115 
00116   double sum = (double)(vnl_c_vector<unsigned>::sum(&freqs.front(), nClasses));
00117   vcl_vector<double> probs(nClasses);
00118   for (unsigned i=0; i < nClasses; ++i)
00119     probs[i] = freqs[i] / sum;
00120   randclass.set_probs(probs);
00121 
00122   assert (inputs.size() > 0);
00123   inputs.reset();
00124   randclass.set_n_dims(inputs.current().size());
00125   randclass.set_confidence(confidence_);
00126   return clsfy_test_error(model, inputs, outputs);
00127 }
00128 
00129 //=======================================================================
00130 
00131 double clsfy_random_builder::confidence() const
00132 {
00133   return confidence_;
00134 }
00135 
00136 //=======================================================================
00137 
00138 void clsfy_random_builder::set_confidence(double confidence)
00139 {
00140   confidence_ = confidence;
00141 }
00142 
00143 //=======================================================================
00144 
00145 //: Create empty classifier
00146 // Caller is responsible for deletion
00147 clsfy_classifier_base* clsfy_random_builder::new_classifier() const
00148 {
00149   return new clsfy_random_classifier();
00150 }
00151