contrib/mul/clsfy/clsfy_rbf_svm.h
Go to the documentation of this file.
00001 // This is mul/clsfy/clsfy_rbf_svm.h
00002 // Copyright: (C) 2000 British Telecommunications plc.
00003 #ifndef clsfy_rbf_svm_h_
00004 #define clsfy_rbf_svm_h_
00005 //:
00006 // \file
00007 // \brief Describe a RBF Support Vector Machine
00008 // \author Ian Scott
00009 // \date Jan 2001
00010 // \verbatim
00011 //  Modifications
00012 //   31 May 2001 IMS Converted to VXL
00013 //   31 May 2001 IMS Merged with Finder/IS_OrderedSVM
00014 // \endverbatim
00015 
00016 #include <clsfy/clsfy_classifier_base.h>
00017 #include <vcl_cmath.h>
00018 #include <vcl_iosfwd.h>
00019 
00020 //: A Support Vector Machine Binary Classifier.
00021 class clsfy_rbf_svm : public clsfy_classifier_base
00022 {
00023  protected:
00024   //: the starting upper bound.
00025   // If the function sum exceeds this value, the decision will definitely be 1.
00026   double upper_target_;
00027   //: the starting lower bound.
00028   // If the function sum falls below this value, the decision will definitely be 0.
00029   double lower_target_;
00030 
00031   //: The support vectors.
00032   vcl_vector<vnl_vector<double> > supports_;
00033 
00034   //: The Lagrangian multipliers
00035   // The values have been pre-multiplied by the +/-1.0 depending on the support target.
00036   vcl_vector<double> lagrangians_;
00037 
00038   //: The offset bias.
00039   double bias_;
00040 
00041   //: -1/(2 * sigma*sigma), where sigma = RBF kernel width
00042   double gamma_;
00043 
00044  public:
00045 
00046   //: Dflt constructor
00047   clsfy_rbf_svm();
00048 
00049   //: Destructor
00050   virtual ~clsfy_rbf_svm();
00051 
00052   //: Classify the input vector
00053   // returns 0 to indicate out of (or negative) class and one to indicate in class (or positive.)
00054   virtual unsigned classify(const vnl_vector<double> &input) const;
00055 
00056   //: Return the probability the input being in each class.
00057   // output(i) i<<nClasses, contains the probability that the input
00058   // is in class i;
00059   // This are not strict probability values, since SVMs do not give Bayesian
00060   // outputs. However their properties fit the requirements of a probability.
00061   virtual void class_probabilities(vcl_vector<double> &outputs,
00062                                    const vnl_vector<double> &input) const;
00063 
00064   //: Log likelihood of being in class (binary classifiers only)
00065   // class probability = vcl_exp(logL) / (1+vcl_exp(logL)
00066   virtual double log_l(const vnl_vector<double> &input) const;
00067 
00068   //: Set the internal values defining the classifier.
00069   // \param supportVectors
00070   // \param lagrangianAlphas
00071   // \param labels These should be 0 or 1.
00072   // \param RBFWidth
00073   // \param bias
00074   virtual void set( const vcl_vector<vnl_vector<double> > & supportVectors,
00075                     const vcl_vector<double> & lagrangianAlphas,
00076                     const vcl_vector<unsigned> &labels,
00077                     double RBFWidth, double bias);
00078 
00079   //: The 1st standard deviation width of the RBF kernel.
00080   // Really this could be better named as the RBF radius.
00081   double rbf_width() const { return 1/vcl_sqrt(-2.0*gamma_);}
00082 
00083   //: The number of support vectors.
00084   unsigned n_support_vectors() const { return supports_.size();}
00085 
00086   //: The kernel function
00087   // Uses the SVM's current value of RBFWidth.
00088   double kernel(const vnl_vector<double> &v1, const vnl_vector<double> &v2) const;
00089 
00090   //: The SVM function bias.
00091   double bias() const {return bias_;}
00092 
00093   //: The Lagrange multipliers.
00094   // The values corresponding to negative training vectors are pre-multiplied by -1.
00095   // The array ordering corresponds to supportVectors()
00096   const vcl_vector<double> & lagrangians() const {return lagrangians_;}
00097 
00098   //: The support vectors.
00099   // The array ordering corresponds to lagrangians()
00100   const vcl_vector<vnl_vector<double> > & support_vectors() const {return supports_;}
00101 
00102 
00103   //: The number of possible output classes.
00104   virtual unsigned n_classes() const {return 1;}
00105 
00106   //: The dimensionality of input vectors.
00107   virtual unsigned n_dims() const {return supports_[0].size();}
00108 
00109   //: Return the class's IO version number
00110   short version_no() const;
00111 
00112   //: Name of the class
00113   virtual vcl_string is_a() const ;
00114 
00115   //: Name of the class
00116   virtual bool is_class(vcl_string const& s) const;
00117 
00118   //: Create a copy on the heap and return base class pointer
00119   virtual clsfy_classifier_base* clone() const;
00120 
00121   //: Print class to os
00122   virtual void print_summary(vcl_ostream& os) const;
00123 
00124   //: Save class to binary file stream
00125   virtual void b_write(vsl_b_ostream& bfs) const;
00126 
00127   //: Load class from binary file stream
00128   virtual void b_read(vsl_b_istream& bfs);
00129 
00130  protected:
00131   //: Set the private target member values to the correct value.
00132   void calculate_targets();
00133 
00134   //: Calculate the contribution of a single support vector to the classifier;
00135   // This local version is used so that the number of calls can be tested.
00136   double localEuclideanDistanceSq(const vnl_vector<double> &a, const vnl_vector<double> &b) const
00137   {
00138 #ifdef CLSFY_RBF_SVM_GLOBAL_COUNT_USE_OF_EUCLIDEAN_DISTANCE_SQ
00139     extern CLSFY_RBF_SVM_GLOBAL_COUNT_USE_OF_EUCLIDEAN_DISTANCE_SQ;
00140     CLSFY_RBF_SVM_GLOBAL_COUNT_USE_OF_EUCLIDEAN_DISTANCE_SQ ++;
00141 #endif
00142     return vnl_vector_ssd(a, b);
00143   }
00144 };
00145 
00146 #endif // clsfy_rbf_svm_h_