contrib/mul/clsfy/clsfy_parzen_builder.cxx

Go to the documentation of this file.
00001 // This is mul/clsfy/clsfy_parzen_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 Parzen window classifier builder
00009 // \author Ian Scott
00010 // \date 2001/10/07
00011 
00012 #include "clsfy_parzen_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_rbf_parzen.h>
00019 
00020 //=======================================================================
00021 
00022 clsfy_parzen_builder::clsfy_parzen_builder():
00023 sigma_(1.0), power_(2.0)
00024 {
00025 }
00026 
00027 
00028 //=======================================================================
00029 
00030 short clsfy_parzen_builder::version_no() const
00031 {
00032   return 1;
00033 }
00034 
00035 //=======================================================================
00036 
00037 vcl_string clsfy_parzen_builder::is_a() const
00038 {
00039   return vcl_string("clsfy_parzen_builder");
00040 }
00041 
00042 //=======================================================================
00043 
00044 bool clsfy_parzen_builder::is_class(vcl_string const& s) const
00045 {
00046   return s == clsfy_parzen_builder::is_a() || clsfy_builder_base::is_class(s);
00047 }
00048 
00049 //=======================================================================
00050 
00051 clsfy_builder_base* clsfy_parzen_builder::clone() const
00052 {
00053   return new clsfy_parzen_builder(*this);
00054 }
00055 
00056 //=======================================================================
00057 
00058 void clsfy_parzen_builder::print_summary(vcl_ostream& os) const
00059 {
00060   os << "rbf width = " << sigma_ << ", power = "<< power_;
00061 }
00062 
00063 //=======================================================================
00064 
00065 void clsfy_parzen_builder::b_write(vsl_b_ostream& bfs) const
00066 {
00067   vsl_b_write(bfs, version_no());
00068   vsl_b_write(bfs, sigma_);
00069   vsl_b_write(bfs, power_);
00070 }
00071 
00072 //=======================================================================
00073 
00074 void clsfy_parzen_builder::b_read(vsl_b_istream& bfs)
00075 {
00076   if (!bfs) return;
00077 
00078   short version;
00079   vsl_b_read(bfs,version);
00080   switch (version)
00081   {
00082   case (1):
00083     vsl_b_read(bfs, sigma_);
00084     vsl_b_read(bfs, power_);
00085     break;
00086   default:
00087     vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&, clsfy_parzen_builder&)\n"
00088              << "           Unknown version number "<< version << "\n";
00089     bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00090   }
00091 }
00092 
00093 //=======================================================================
00094 
00095 //: Build model from data
00096 // return the mean error over the training set.
00097 // For many classifiers, you may use nClasses==1 to
00098 // indicate a binary classifier
00099 double clsfy_parzen_builder::build(clsfy_classifier_base& model,
00100                                    mbl_data_wrapper<vnl_vector<double> >& inputs,
00101                                    unsigned /* nClasses */,
00102                                    const vcl_vector<unsigned> &outputs) const
00103 {
00104   assert(model.is_class("clsfy_rbf_parzen")); // equiv to dynamic_cast<> != 0
00105   assert(inputs.size()==outputs.size());
00106 
00107   clsfy_rbf_parzen &parzen = (clsfy_rbf_parzen&) model;
00108 
00109   vcl_vector<vnl_vector<double> > vin(inputs.size());
00110 
00111   inputs.reset();
00112   unsigned i=0;
00113   do
00114   {
00115     vin[i++] = inputs.current();
00116   } while (inputs.next());
00117 
00118   assert(i==inputs.size());
00119 
00120   parzen.set(vin, outputs);
00121   parzen.set_power(power_);
00122   parzen.set_rbf_width(sigma_);
00123   return clsfy_test_error(model, inputs, outputs);
00124 }
00125 
00126 //=======================================================================
00127 
00128 
00129 //: Set the 1st standard deviation width of the RBF window.
00130 // The default value is 1. Really this could be better named as the RBF radius.
00131 void clsfy_parzen_builder::set_rbf_width(double sigma)
00132 {
00133   assert(sigma > 0.0);
00134   sigma_=sigma;
00135 }
00136 
00137 //=======================================================================
00138 
00139 //: The value p in the window function $exp(-1/(2*sigma^p) * |x-y|^p)$.
00140 // The value p affects the kurtosis, or peakyness of the window.
00141 // Towards 0 gives a more peaked central spike, and longer tail.
00142 // Toward +inf gives a broader peak, and shorter tail.
00143 // The default value is 2, giving a Gaussian distribution.
00144 void clsfy_parzen_builder::set_power(double p)
00145 {
00146   assert(p != 0.0);
00147   power_ = p;
00148 }
00149 
00150 //=======================================================================
00151 
00152 //: Create empty classifier
00153 // Caller is responsible for deletion
00154 clsfy_classifier_base* clsfy_parzen_builder::new_classifier() const
00155 {
00156   return new clsfy_rbf_parzen();
00157 }
00158 

Generated on Thu Jan 8 05:11:33 2009 for contrib/mul/clsfy by  doxygen 1.5.1