Browse Source

added clone member function

Sven Sickert 11 years ago
parent
commit
d1e6db8ffd

+ 33 - 21
regression/linregression/LinRegression.cpp

@@ -8,6 +8,7 @@
 
 #include "vislearning/regression/linregression/LinRegression.h"
 #include "core/vector/Algorithms.h"
+#include "LinRegression.h"
 
 using namespace OBJREC;
 
@@ -15,58 +16,67 @@ using namespace std;
 
 using namespace NICE;
 
-LinRegression::LinRegression(){
+LinRegression::LinRegression()
+{
   dim = 0;
 }
 
-LinRegression::LinRegression(uint dimension){
+LinRegression::LinRegression(uint dimension)
+{
   dim = dimension;
 }
 
 LinRegression::LinRegression ( const LinRegression & src ) : 
 RegressionAlgorithm ( src )
 {
-dim = src.dim;
+  dim = src.dim;
 }
 
 LinRegression::~LinRegression()
 {
 }
 
+LinRegression* LinRegression::clone ( void ) const
+{
+  return new LinRegression(*this);
+}
+
+
 void LinRegression::teach ( const NICE::VVector & x, const NICE::Vector & y ){
   
-  if (dim == 0){	//dimension not specified via constructor
+  if (dim == 0)           //dimension not specified via constructor
+  {
     dim = x[0].size()+1;  //use full dimension of data
   }
   
   cerr<<"dim: "<<dim<<endl;
   cerr<<"examples: "<<x.size()<<endl;
   
-  for ( uint i = 0;i < dim;i++ ){  //initialize vector of model parameters
+  for ( uint i = 0;i < dim;i++ )  //initialize vector of model parameters
+  {
     modelParams.push_back(0.0);
   }
   
-  if ( dim == 2 ){  //two-dimensional least squares
+  if ( dim == 2 )         //two-dimensional least squares
+  {  
     double meanX;
     double meanY = y.Mean();
     double sumX = 0.0;
     
-    for ( uint i = 0;i < x.size();i++ ){
+    for ( uint i = 0;i < x.size();i++ )
       sumX += x[i][0];
-    }
+
     meanX = sumX / (double)x.size();
- 
-    
-    for ( uint i = 0; i < x.size(); i++ ){
-	modelParams[1] += x[i][0] * y[i];
-    }
     
+    for ( uint i = 0; i < x.size(); i++ )
+      modelParams[1] += x[i][0] * y[i];
+
     modelParams[1] -= x.size() * meanX * meanY;
     
     double tmp = 0.0;
-    for ( uint i = 0; i < x.size(); i++ ){
+    for ( uint i = 0; i < x.size(); i++ )
       tmp += x[i][0] * x[i][0];
-    }
+
     tmp -= x.size() * meanX * meanX;
     
     modelParams[1] /= tmp;
@@ -83,9 +93,11 @@ void LinRegression::teach ( const NICE::VVector & x, const NICE::Vector & y ){
     
     // attach front column with ones
 
-    for(uint row = 0;row<X.rows();row++){
-      for(uint col = 0;col<X.cols();col++){
-	Xtmp(row,col+1) = X(row,col);
+    for(uint row = 0;row<X.rows();row++)
+    {
+      for(uint col = 0;col<X.cols();col++)
+      {
+        Xtmp(row,col+1) = X(row,col);
       }
     }
 
@@ -94,12 +106,11 @@ void LinRegression::teach ( const NICE::VVector & x, const NICE::Vector & y ){
     NICE::Vector rhs;
       
     rhs.multiply(Xtmp,y,true);
-      
     tmp.multiply(Xtmp,Xtmp,true);
       
     choleskyDecomp(tmp,G);
     choleskyInvert(G,tmpInv);
-      
+
     params.multiply(tmpInv,rhs);
 
     modelParams = params.std_vector();
@@ -112,7 +123,8 @@ std::vector<double> LinRegression::getModelParams(){
 
 double LinRegression::predict ( const NICE::Vector & x ){
   double y;
-  if ( dim == 2 ){  //two-dimensional least squares
+  if ( dim == 2 )     //two-dimensional least squares
+  {  
     y = modelParams[0] + modelParams[1] * x[0];
   }
   else {

+ 5 - 1
regression/linregression/LinRegression.h

@@ -39,6 +39,9 @@ class LinRegression : public RegressionAlgorithm
     /** simple destructor */
     virtual ~LinRegression();
     
+    /** clone function */
+    LinRegression* clone (void) const;
+    
     /** method to learn model parameters */
     void teach ( const NICE::VVector & x, const NICE::Vector & y );
     
@@ -47,7 +50,8 @@ class LinRegression : public RegressionAlgorithm
     
     /** method to predict function value */
     double predict ( const NICE::Vector & x );
-}; 
+};
+
 }	//namespace
 
 #endif

+ 82 - 70
regression/npregression/RegKNN.cpp

@@ -24,100 +24,112 @@ using namespace NICE;
 
 RegKNN::RegKNN ( const Config *_conf, NICE::VectorDistance<double> *_distancefunc ) : distancefunc (_distancefunc)
 {
-    K = _conf->gI("RegKNN", "K", 1 );
-    if ( _distancefunc == NULL )
-		distancefunc = new EuclidianDistance<double>();
+  K = _conf->gI("RegKNN", "K", 1 );
+  if ( _distancefunc == NULL )
+  distancefunc = new EuclidianDistance<double>();
 }
 
 RegKNN::RegKNN ( const RegKNN & src ) : RegressionAlgorithm ( src )
 {
-    dataSet = src.dataSet;
-    labelSet = src.labelSet;
-    distancefunc = src.distancefunc;
+  dataSet = src.dataSet;
+  labelSet = src.labelSet;
+  distancefunc = src.distancefunc;
+  K = src.K;
 }
 
-RegKNN::~RegKNN()
+RegKNN::~RegKNN ()
 {
 }
 
+RegKNN* RegKNN::clone ( void ) const
+{
+  return new RegKNN(*this);
+}
+
+
 void RegKNN::teach ( const NICE::VVector & _dataSet, const NICE::Vector & _labelSet)
 {
-    fprintf (stderr, "teach using all !\n");
-    //NOTE this is crucial if we clear _teachSet afterwards!
-    //therefore, take care NOT to call _techSet.clear() somewhere out of this method
-    this->dataSet = _dataSet;
-    this->labelSet = _labelSet.std_vector();
-    
-    std::cerr << "number of known training samples: " << this->dataSet.size() << std::endl;   
+  fprintf (stderr, "teach using all !\n");
+  //NOTE this is crucial if we clear _teachSet afterwards!
+  //therefore, take care NOT to call _techSet.clear() somewhere out of this method
+  this->dataSet = _dataSet;
+  this->labelSet = _labelSet.std_vector();
+  
+  std::cerr << "number of known training samples: " << this->dataSet.size() << std::endl;   
     
 }
 
 void RegKNN::teach ( const NICE::Vector & x, const double & y )
 {
-    std::cerr << "RegKNN::teach one new example" << std::endl;
-    
-    for ( size_t i = 0 ; i < x.size() ; i++ )
-      if ( isnan(x[i]) ) 
-      {
-          fprintf (stderr, "There is a NAN value in within this vector: x[%d] = %f\n", (int)i, x[i]);
-          cerr << x << endl;
-          exit(-1);
-      }
-
-    dataSet.push_back ( x );
-    
-    labelSet.push_back ( y );
-    
-    std::cerr << "number of known training samples: " << dataSet.size()<< std::endl;
+  std::cerr << "RegKNN::teach one new example" << std::endl;
+
+  for ( size_t i = 0 ; i < x.size() ; i++ )
+    if ( isnan(x[i]) ) 
+    {
+        fprintf (stderr, "There is a NAN value within this vector: x[%d] = %f\n", (int)i, x[i]);
+        cerr << x << endl;
+        exit(-1);
+    }
+
+  dataSet.push_back ( x );
+
+  labelSet.push_back ( y );
+
+  std::cerr << "number of known training samples: " << dataSet.size()<< std::endl;
 }
 
 double RegKNN::predict ( const NICE::Vector & x )
 {
-    FullVector distances(dataSet.size());
+  FullVector distances(dataSet.size());
 
-    if ( dataSet.size() <= 0 ) {
-		fprintf (stderr, "RegKNN: please use the train method first\n");
-		exit(-1);
-    }
+  if ( dataSet.size() <= 0 )
+  {
+    fprintf (stderr, "RegKNN: please use the teach method first\n");
+    exit(-1);
+  }
 
 #pragma omp parallel for
-    for(uint i = 0; i < dataSet.size(); i++){
-    
-      double distance = distancefunc->calculate (x,dataSet[i]);
-      
-      if ( isnan(distance) ){
-          fprintf (stderr, "RegKNN::predict: NAN value found !!\n");
-          cerr << x << endl;
-          cerr << dataSet[i] << endl;
-      }
-// #pragma omp critical      
-      distances[i] = distance;     
-    }
-    
-    std::vector<int> ind;
-    distances.getSortedIndices(ind);
-    
-    double response = 0.0;  
-    
-    if ( dataSet.size() < K ){
-      K = dataSet.size();
-      cerr<<"RegKNN: Not enough datapoints! Setting K to: "<< K <<endl;
-    }
-        
-    if ( distances[ind[0]] == 0.0 ) {
-      cerr<<"RegKNN: Warning: datapoint was already seen during training... using its label as prediction."<<endl;
-      return labelSet[ind[0]];  
+  for(uint i = 0; i < dataSet.size(); i++)
+  {
+    double distance = distancefunc->calculate (x,dataSet[i]);
+
+    if ( isnan(distance) )
+    {
+      fprintf (stderr, "RegKNN::predict: NAN value found !!\n");
+      cerr << x << endl;
+      cerr << dataSet[i] << endl;
     }
+// #pragma omp critical      
+    distances[i] = distance;     
+  }
     
-    double maxElement = distances.max();	//normalize distances
-    distances.multiply(1.0/maxElement);
-    
-    double weightSum = 0.0;
+  std::vector<int> ind;
+  distances.getSortedIndices(ind);
+
+  double response = 0.0;  
     
-    for(uint i = 0; i < K; i++){
-      response += 1.0/distances[ind[i]] * labelSet[ind[i]];
-      weightSum += 1.0/distances[ind[i]];
-    }
-       
-    return ( response / weightSum );
+  if ( dataSet.size() < K )
+  {
+    cerr << K << endl;
+    K = dataSet.size();
+    cerr<<"RegKNN: Not enough datapoints! Setting K to: "<< K <<endl;
+  }
+
+  if ( distances[ind[0]] == 0.0 ) {
+    cerr<<"RegKNN: Warning: datapoint was already seen during training... using its label as prediction."<<endl;
+    return labelSet[ind[0]];  
+  }
+
+  double maxElement = distances.max();	//normalize distances
+  distances.multiply(1.0/maxElement);
+
+  double weightSum = 0.0;
+
+  for(uint i = 0; i < K; i++)
+  {
+    response += 1.0/distances[ind[i]] * labelSet[ind[i]];
+    weightSum += 1.0/distances[ind[i]];
+  }
+
+  return ( response / weightSum );
 }

+ 4 - 0
regression/npregression/RegKNN.h

@@ -44,6 +44,9 @@ class RegKNN : public RegressionAlgorithm
     /** simple destructor */
     virtual ~RegKNN();
     
+    /** clone function */
+    RegKNN* clone (void) const;
+    
     /** predict response using simple vector */
     double predict ( const NICE::Vector & x );
     
@@ -53,6 +56,7 @@ class RegKNN : public RegressionAlgorithm
     /** teach one data point at a time */
     void teach ( const NICE::Vector & x, const double & y );
 };
+
 }	//namespace
 
 #endif

+ 6 - 0
regression/progs/testRegressionRDFGP.cpp

@@ -23,6 +23,8 @@
 
 #include "vislearning/regression/regcombination/RegPreRandomForests.h"
 #include "vislearning/regression/gpregression/RegGaussianProcess.h"
+#include "vislearning/regression/linregression/LinRegression.h"
+#include "vislearning/regression/npregression/RegKNN.h"
 
 #include "vislearning/math/kernels/KernelExp.h"
 
@@ -223,6 +225,10 @@ void testFrame ( Config confRDF,
       kernel_function = new KernelExp ( *(kernel_template) );
       leafRegression = new RegGaussianProcess( &confRDF, kernel_function, "GPRegression" );
     }
+    else if ( leafReg == "Linear" )
+      leafRegression = new LinRegression ();
+    else if ( leafReg == "KNN" )
+      leafRegression = new RegKNN ( &confRDF, NULL);
     else if ( leafReg == "none" ) {
       cerr << "\ntestRegressionRDFGP::testFrame: No leaf regression method set! Using RandomForest prediction..." << endl;
     } else {