Changeset 523


Ignore:
Timestamp:
Feb 23, 2006, 9:52:04 AM (16 years ago)
Author:
Peter
Message:

add prediction functions to SVM

Location:
trunk/lib/classifier
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/classifier/Kernel.h

    r513 r523  
    55
    66#include <c++_tools/gslapi/matrix.h>
     7#include <c++_tools/gslapi/vector.h>
     8#include <c++_tools/classifier/KernelFunction.h>
    79
    810#include <cctype>
     
    1012namespace theplu {
    1113namespace classifier {
    12 
    13   class KernelFunction;
    1414
    1515  ///
     
    6262    inline size_t size(void) const { return data_.columns(); }
    6363
     64   
     65    virtual double element(const gslapi::vector& vec, const size_t i) const=0;
     66
    6467  protected:
    6568    const gslapi::matrix& data_;
  • trunk/lib/classifier/KernelLookup.h

    r517 r523  
    8484    { return (*kernel_)(row_index_[row],column_index_[column]); }
    8585
    86    
     86    inline double element(const gslapi::vector& vec, const size_t i) const
     87    { return kernel_->element(vec, row_index_[i]); }
    8788
    8889  private:
  • trunk/lib/classifier/KernelWeighted_MEV.h

    r513 r523  
    5151                      gslapi::vector(weights_,column,false)); }
    5252
     53    ///
     54    /// @return kernel element between data @a ve and training sample @a i
     55    ///
     56    inline double element(const gslapi::vector& vec, const size_t i) const
     57    {
     58      return (*kf_)(vec, gslapi::vector(data_,i),
     59                           gslapi::vector(vec.size(),1.0),
     60                           gslapi::vector(weights_,i));
     61    }
     62
    5363  private:
    5464    ///
  • trunk/lib/classifier/KernelWeighted_SEV.h

    r513 r523  
    66#include <c++_tools/classifier/Kernel.h>
    77#include <c++_tools/gslapi/matrix.h>
     8#include <c++_tools/gslapi/vector.h>
    89
    910
     
    4849    { return kernel_matrix_(row,column); }
    4950
     51    ///
     52    /// @return kernel element between data @a ve and training sample @a i
     53    ///
     54    inline double element(const gslapi::vector& vec, const size_t i) const
     55    {
     56      return (*kf_)(vec, gslapi::vector(data_,i),
     57                    gslapi::vector(vec.size(),1.0),
     58                    gslapi::vector(weights_,i));
     59    }
     60
     61
    5062  private:
    5163    /// Copy constructor (not implemented)
  • trunk/lib/classifier/Kernel_MEV.h

    r513 r523  
    5757                      gslapi::vector(data_,column,false)); }
    5858
     59    ///
     60    /// @return kernel element between data @a ve and training sample @a i
     61    ///
     62    inline double element(const gslapi::vector& vec, const size_t i) const
     63    { return kf_->operator()(vec, gslapi::vector(data_,i)); }
     64     
     65
    5966  private:
    6067    ///
  • trunk/lib/classifier/Kernel_SEV.cc

    r512 r523  
    1212
    1313
    14 Kernel_SEV::Kernel_SEV(const gslapi::matrix& data, const KernelFunction& kf)
    15   : Kernel(data,kf)
    16 {
    17   kernel_matrix_ = gslapi::matrix(data.columns(),data.columns());
    18   for (size_t i=0; i<kernel_matrix_.rows(); i++)
    19     for (size_t j=i; j<kernel_matrix_.columns(); j++)
    20       kernel_matrix_(i,j) = kernel_matrix_(j,i) =
    21         (*kf_)(gslapi::vector(data_,i,false),gslapi::vector(data_,j,false));
    22 }
     14  Kernel_SEV::Kernel_SEV(const gslapi::matrix& data, const KernelFunction& kf)
     15    : Kernel(data,kf)
     16  {
     17    kernel_matrix_ = gslapi::matrix(data.columns(),data.columns());
     18    for (size_t i=0; i<kernel_matrix_.rows(); i++)
     19      for (size_t j=i; j<kernel_matrix_.columns(); j++)
     20        kernel_matrix_(i,j) = kernel_matrix_(j,i) =
     21          (*kf_)(gslapi::vector(data_,i,false),gslapi::vector(data_,j,false));
     22  }
     23
     24  double Kernel_SEV::element(const gslapi::vector& vec, const size_t i) const
     25  {
     26    return kf_->operator()(vec, gslapi::vector(data_,i));
     27  }
    2328
    2429
  • trunk/lib/classifier/Kernel_SEV.h

    r513 r523  
    5757    { return kernel_matrix_(row,column); }
    5858
     59    ///
     60    /// @return kernel element between data @a ve and training sample @a i
     61    ///
     62    double element(const gslapi::vector& vec, const size_t i) const;
     63
     64
    5965  private:
    6066    gslapi::matrix kernel_matrix_;
  • trunk/lib/classifier/NCC.cc

    r509 r523  
    2020  NCC::NCC(const DataLookup2D& data, const Target& target,
    2121           const statistics::Distance& distance)
    22     : SupervisedClassifier(data,target), distance_(distance)
     22    : SupervisedClassifier(target), distance_(distance), matrix_(data)
    2323  {   
    2424  }
  • trunk/lib/classifier/NCC.h

    r505 r523  
    5757
    5858  private:
     59    gslapi::matrix centroids_;
    5960    const statistics::Distance& distance_;                 
    60     gslapi::matrix centroids_;
     61    const DataLookup2D& matrix_;
     62
    6163  };
    6264
  • trunk/lib/classifier/SVM.cc

    r520 r523  
    2020namespace classifier { 
    2121
    22   Index::Index(void)
    23     : nof_sv_(0), vec_(std::vector<size_t>(0))
    24   {
    25   }
    26 
    27   Index::Index(const size_t n)
    28     : nof_sv_(0), vec_(std::vector<size_t>(n))
    29   {
    30     for (size_t i=0; i<vec_.size(); i++)
    31       vec_[i]=i;
    32   }
    33 
    34   void Index::init(const gslapi::vector& alpha, const double tol)
    35   {
    36     nof_sv_=0;
    37     size_t nof_nsv=0;
    38     for (size_t i=0; i<alpha.size(); i++)
    39       if (alpha(i)<tol){
    40         nof_nsv++;
    41         vec_[vec_.size()-nof_nsv]=i;
    42       }
    43       else{
    44         vec_[nof_sv_]=i;
    45         nof_sv_++;
    46       }
    47     assert(nof_sv_+nof_nsv==vec_.size());
    48 
    49   }
    50 
    51   void Index::sv_first(void)
    52   {
    53     // if already sv, do nothing
    54     if (index_first_<nof_sv())
    55       return;
    56 
    57     // swap elements
    58     if(index_second_==nof_sv_){
    59       index_second_=index_first_;
    60     }
    61     vec_[index_first_]=vec_[nof_sv_];
    62     vec_[nof_sv_]=value_first_;
    63     index_first_ = nof_sv_;
    64 
    65     nof_sv_++;
    66 
    67   }
    68 
    69   void Index::sv_second(void)
    70   {
    71     // if already sv, do nothing
    72     if (index_second_<nof_sv())
    73       return;
    74 
    75     // swap elements
    76     if(index_first_==nof_sv_){
    77       index_first_=index_second_;
    78     }
    79 
    80     vec_[index_second_]=vec_[nof_sv_];
    81     vec_[nof_sv_]=value_second_;
    82     index_second_=nof_sv_;
    83 
    84     nof_sv_++;
    85   }
    86 
    87   void Index::nsv_first(void)
    88   {
    89     // if already nsv, do nothing
    90     if ( !(index_first_<nof_sv()) )
    91       return;
    92    
    93     if(index_second_==nof_sv_-1)
    94       index_second_=index_first_;
    95     vec_[index_first_]=vec_[nof_sv_-1];
    96     vec_[nof_sv_-1]=value_first_;
    97     index_first_=nof_sv_-1;
    98    
    99     nof_sv_--;
    100   }
    101 
    102   void Index::nsv_second(void)
    103   {
    104     // if already nsv, do nothing
    105     if ( !(index_second_<nof_sv()) )
    106       return;
    107 
    108     if(index_first_==nof_sv_-1)
    109       index_first_=index_second_;
    110     vec_[index_second_]=vec_[nof_sv_-1];
    111     vec_[nof_sv_-1]=value_second_;
    112     index_second_ = nof_sv_-1;
    113    
    114     nof_sv_--;
    115   }
    116 
    117 
    118   void Index::shuffle(void)
    119   {
    120     random::DiscreteUniform a;
    121     random_shuffle(vec_.begin()+nof_sv_, vec_.end(), a);
    122   }
    123 
    124   void Index::update_first(const size_t i)
    125   {
    126     assert(i<n());
    127     index_first_=i;
    128     value_first_=vec_[i];
    129   }
    130 
    131   void Index::update_second(const size_t i)
    132   {
    133     assert(i<n());
    134     index_second_=i;
    135     value_second_=vec_[i];
    136   }
    137 
    138   SVM::SVM(const DataLookup2D& kernel, const Target& target)
    139     : SupervisedClassifier(kernel,target),
     22  SVM::SVM(const KernelLookup& kernel, const Target& target)
     23    : SupervisedClassifier(target),
    14024      alpha_(target.size(),0),
    14125      bias_(0),
    14226      C_inverse_(0),
    143       kernel_(kernel),
     27      kernel_(&kernel),
    14428      max_epochs_(10000000),
    14529      output_(target.size(),0),
     
    15438                                             const Target& target) const
    15539  {
    156     SVM* sc = new SVM(data,target);
     40    // Peter, should check success of dynamic_cast
     41    const KernelLookup& tmp = dynamic_cast<const KernelLookup&>(data);
     42    SVM* sc = new SVM(tmp,target);
    15743    //Copy those variables possible to modify from outside
    15844    return sc;
    15945  }
    16046
     47  void SVM::predict(const DataLookup2D& input, gslapi::matrix& prediction) const
     48  {
     49    assert(input.rows()==alpha_.size());
     50    prediction=gslapi::matrix(2,input.columns(),0);
     51    for (size_t i = 0; i<input.columns(); i++){
     52      for (size_t j = 0; i<input.rows(); i++)
     53        prediction(0,i) += target(j)*alpha_(i)*input(j,i);
     54      prediction(0,i) += bias_;
     55    }
     56
     57    for (size_t i = 0; i<prediction.columns(); i++)
     58      prediction(1,i) = -prediction(0,i);
     59  }
     60
     61  double SVM::predict(const gslapi::vector& x) const
     62  {
     63    double y=0;
     64    for (size_t i=0; i<alpha_.size(); i++)
     65      y += alpha_(i)*target_(i)*kernel_->element(x,i);
     66
     67    return y+bias_;
     68  }
     69
    16170  bool SVM::train(void)
    16271  {
    16372    // initializing variables for optimization
    164     assert(target_.size()==kernel_.rows());
     73    assert(target_.size()==kernel_->rows());
    16574    assert(target_.size()==alpha_.size());
    16675
     
    359268      output_(i)=0;
    360269      for (size_t j=0; j<output_.size(); j++)
    361         output_(i)+=alpha_(j)*target(j) * kernel_(i,j);
     270        output_(i)+=alpha_(j)*target(j) * (*kernel_)(i,j);
    362271    }
    363272
     
    381290  }
    382291
     292  Index::Index(void)
     293    : nof_sv_(0), vec_(std::vector<size_t>(0))
     294  {
     295  }
     296
     297  Index::Index(const size_t n)
     298    : nof_sv_(0), vec_(std::vector<size_t>(n))
     299  {
     300    for (size_t i=0; i<vec_.size(); i++)
     301      vec_[i]=i;
     302  }
     303
     304  void Index::init(const gslapi::vector& alpha, const double tol)
     305  {
     306    nof_sv_=0;
     307    size_t nof_nsv=0;
     308    for (size_t i=0; i<alpha.size(); i++)
     309      if (alpha(i)<tol){
     310        nof_nsv++;
     311        vec_[vec_.size()-nof_nsv]=i;
     312      }
     313      else{
     314        vec_[nof_sv_]=i;
     315        nof_sv_++;
     316      }
     317    assert(nof_sv_+nof_nsv==vec_.size());
     318
     319  }
     320
     321  void Index::sv_first(void)
     322  {
     323    // if already sv, do nothing
     324    if (index_first_<nof_sv())
     325      return;
     326
     327    // swap elements
     328    if(index_second_==nof_sv_){
     329      index_second_=index_first_;
     330    }
     331    vec_[index_first_]=vec_[nof_sv_];
     332    vec_[nof_sv_]=value_first_;
     333    index_first_ = nof_sv_;
     334
     335    nof_sv_++;
     336
     337  }
     338
     339  void Index::sv_second(void)
     340  {
     341    // if already sv, do nothing
     342    if (index_second_<nof_sv())
     343      return;
     344
     345    // swap elements
     346    if(index_first_==nof_sv_){
     347      index_first_=index_second_;
     348    }
     349
     350    vec_[index_second_]=vec_[nof_sv_];
     351    vec_[nof_sv_]=value_second_;
     352    index_second_=nof_sv_;
     353
     354    nof_sv_++;
     355  }
     356
     357  void Index::nsv_first(void)
     358  {
     359    // if already nsv, do nothing
     360    if ( !(index_first_<nof_sv()) )
     361      return;
     362   
     363    if(index_second_==nof_sv_-1)
     364      index_second_=index_first_;
     365    vec_[index_first_]=vec_[nof_sv_-1];
     366    vec_[nof_sv_-1]=value_first_;
     367    index_first_=nof_sv_-1;
     368   
     369    nof_sv_--;
     370  }
     371
     372  void Index::nsv_second(void)
     373  {
     374    // if already nsv, do nothing
     375    if ( !(index_second_<nof_sv()) )
     376      return;
     377
     378    if(index_first_==nof_sv_-1)
     379      index_first_=index_second_;
     380    vec_[index_second_]=vec_[nof_sv_-1];
     381    vec_[nof_sv_-1]=value_second_;
     382    index_second_ = nof_sv_-1;
     383   
     384    nof_sv_--;
     385  }
     386
     387
     388  void Index::shuffle(void)
     389  {
     390    random::DiscreteUniform a;
     391    random_shuffle(vec_.begin()+nof_sv_, vec_.end(), a);
     392  }
     393
     394  void Index::update_first(const size_t i)
     395  {
     396    assert(i<n());
     397    index_first_=i;
     398    value_first_=vec_[i];
     399  }
     400
     401  void Index::update_second(const size_t i)
     402  {
     403    assert(i<n());
     404    index_second_=i;
     405    value_second_=vec_[i];
     406  }
     407
    383408}} // of namespace classifier and namespace theplu
  • trunk/lib/classifier/SVM.h

    r520 r523  
    55
    66#include <c++_tools/classifier/DataLookup2D.h>
     7#include <c++_tools/classifier/KernelLookup.h>
    78#include <c++_tools/classifier/SupervisedClassifier.h>
    89#include <c++_tools/classifier/Target.h>
     
    105106    /// input.
    106107    ///
    107     /// @note if the target, kernel (or data in kernel) is destroyed
    108     /// the SVM is no longer defined.
    109     ///
    110     SVM(const DataLookup2D&, const Target&);
     108    /// @note @a target must be a KernelLookup if the target or kernel
     109    /// is destroyed the SVM is no longer defined.
     110    ///
     111    SVM(const KernelLookup&, const Target&);
    111112
    112113    ///
     
    153154
    154155    ///
    155     /// Generate output values for a data set
    156     /// Not implemented !!!!!
    157     ///
    158     inline void predict(const DataLookup2D&, gslapi::matrix&) const
    159     {}
    160 
     156    /// Generate prediction @a output from @a input. The prediction is
     157    /// returned in @a output. The output has 2 rows. The first row is
     158    /// for binary target true, and the second is for binary target
     159    /// false. The second row is superfluous because it the first row
     160    /// negated. It exist just to be aligned with multi-class
     161    /// SupervisedClassifiers. Each column in @a input and @a output
     162    /// corresponds to a sample to predict. Each row in @a input
     163    /// corresponds to a training sample, and more exactly row i in @a
     164    /// input should correspond to row i in KernelLookup that was used
     165    /// for training.
     166    ///
     167    void predict(const DataLookup2D& input, gslapi::matrix& output) const;
     168
     169    ///
     170    /// @return output from data @a input
     171    ///
     172    double predict(const gslapi::vector& input) const;
    161173
    162174    ///
     
    211223    ///
    212224    inline double kernel_mod(const size_t i, const size_t j) const
    213     { return i!=j ? (kernel_)(i,j) : (kernel_)(i,j) + C_inverse_; }
     225    { return i!=j ? (*kernel_)(i,j) : (*kernel_)(i,j) + C_inverse_; }
    214226   
    215     /// @return 1 if i belong to class one and -1 if i belong to rest
     227    /// @return 1 if i belong to binary target true else -1
    216228    inline int target(size_t i) const { return target_.binary(i) ? 1 : -1; }
    217229
     
    219231    double bias_;
    220232    double C_inverse_;
    221     const DataLookup2D& kernel_;
     233    const KernelLookup* kernel_;
    222234    unsigned long int max_epochs_;
    223235    gslapi::vector output_;
  • trunk/lib/classifier/SupervisedClassifier.cc

    r476 r523  
    66namespace classifier {
    77
    8   SupervisedClassifier::SupervisedClassifier(const DataLookup2D& mv,
    9                                              const Target& target)
    10     : matrix_(mv), target_(target), trained_(false)
     8  SupervisedClassifier::SupervisedClassifier(const Target& target)
     9    : target_(target), trained_(false)
    1110  {
    1211  }
  • trunk/lib/classifier/SupervisedClassifier.h

    r505 r523  
    2727  public:
    2828    ///
    29     /// Constructor. Taking a DataLookup2D into the data or kernel and a
    30     /// vector of target values.
     29    /// Constructor. Taking a vector of target values.
    3130    ///
    32     SupervisedClassifier(const DataLookup2D&, const Target&);
     31    SupervisedClassifier(const Target&);
    3332   
    3433    ///
     
    6261  protected:
    6362   
    64     const DataLookup2D& matrix_;
    6563    const Target& target_;
    6664    bool trained_;
Note: See TracChangeset for help on using the changeset viewer.