KCGPApproxOneClass.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /**
  2. * @file KCGPApproxOneClass.cpp
  3. * @brief One-Class Gaussian Process Regression for Classification: we approximate the inverse of the regularized kernel matrix using a diagonal matrix
  4. * @author Alexander Lütz
  5. * @date 22-05-2012 (dd-mm-yyyy)
  6. */
  7. #include <iostream>
  8. #include <typeinfo>
  9. #include <cstring>
  10. #include "core/vector/Algorithms.h"
  11. #include "core/vector/VVector.h"
  12. #include "KCGPApproxOneClass.h"
  13. using namespace std;
  14. using namespace NICE;
  15. using namespace OBJREC;
  16. KCGPApproxOneClass::KCGPApproxOneClass( const Config *conf, Kernel *kernel, const string & section ) : KernelClassifier ( conf, kernel )
  17. {
  18. // this->kernelFunction = kernel;
  19. //overwrite the default optimization options, since we don't want to perform standard loo or marginal likelihood stuff
  20. Config config(*conf);
  21. string modestr = config.gS(section,"detection_mode");
  22. if(strcmp("mean",modestr.c_str())==0){
  23. this->mode=MEAN_DETECTION_MODE;cerr << "One-class classification via GP predictive _mean_ !!!"<<endl;
  24. }
  25. if(strcmp("variance",modestr.c_str())==0){
  26. mode=VARIANCE_DETECTION_MODE;cerr << "One-class classification via GP predictive _variance_ !!!"<<endl;
  27. }
  28. this->staticNoise = conf->gD(section, "static_noise", 0.0);
  29. }
  30. KCGPApproxOneClass::KCGPApproxOneClass( const KCGPApproxOneClass & src ) : KernelClassifier ( src )
  31. {
  32. this->matrixDInv = src.matrixDInv;
  33. this->InvDY = src.InvDY;
  34. this->mode = src.mode;
  35. this->staticNoise = src.staticNoise;
  36. }
  37. KCGPApproxOneClass::~KCGPApproxOneClass()
  38. {
  39. }
  40. void KCGPApproxOneClass::teach ( KernelData *kernelData, const NICE::Vector & y )
  41. {
  42. fthrow( Exception, "KCGPApproxOneClass::teach: this method is not implemented for this specific type of classifier. Please use the second teach-method." );
  43. }
  44. void KCGPApproxOneClass::teach (const LabeledSetVector &teachSet)
  45. {
  46. if ( this->kernelFunction == NULL )
  47. fthrow( Exception, "KernelClassifier::teach: To use this function, you have to specify a kernel function using the constructor" );
  48. //we do not have to allocate new storage here since these variables come from the interface KernelClassifier
  49. // NICE::VVector vecSet;
  50. teachSet.getFlatRepresentation (this->vecSet, this->vecSetLabels);
  51. if ( (this->vecSetLabels.Min() != 1) || (this->vecSetLabels.Max() != 1) ) {
  52. fthrow(Exception, "This classifier is suitable only for one-class classification problems, i.e. max(y) = min(y) = 1");
  53. }
  54. this->matrixDInv.resize(this->vecSetLabels.size());
  55. //compute D
  56. //start with adding some noise, if necessary
  57. if (this->staticNoise != 0.0)
  58. this->matrixDInv.set(this->staticNoise);
  59. else
  60. this->matrixDInv.set(0.0);
  61. //now sum up all entries of each row in the original kernel matrix
  62. double kernelScore(0.0);
  63. for (int i = 0; i < (int)this->vecSetLabels.size(); i++)
  64. {
  65. for (int j = i; j < (int)this->vecSetLabels.size(); j++)
  66. {
  67. kernelScore = this->kernelFunction->K(vecSet[i],vecSet[j]);
  68. this->matrixDInv[i] += kernelScore;
  69. if (i != j)
  70. this->matrixDInv[j] += kernelScore;
  71. }
  72. }
  73. //compute its inverse
  74. for (int i = 0; i < (int)this->vecSetLabels.size(); i++)
  75. {
  76. this->matrixDInv[i] = 1.0 / this->matrixDInv[i];
  77. }
  78. //and multiply it from right with the label vector (precalculation for mean computation)
  79. if(this->mode==MEAN_DETECTION_MODE)
  80. {
  81. this->InvDY.resize ( this->vecSetLabels.size() );
  82. for (int i = 0; i < (int)this->vecSetLabels.size(); i++)
  83. {
  84. this->InvDY[i] = this->vecSetLabels[i] * this->matrixDInv[i];
  85. }
  86. }
  87. }
  88. ClassificationResult KCGPApproxOneClass::classifyKernel ( const NICE::Vector & kernelVector, double kernelSelf ) const
  89. {
  90. FullVector scores ( 2 );
  91. scores[0] = 0.0;
  92. if(this->mode==MEAN_DETECTION_MODE)
  93. {
  94. // kernelSelf is not needed for the regression type of GP
  95. if ( kernelVector.size() != this->vecSetLabels.size() )
  96. fthrow(Exception, "KCGPApproxOneClass::classifyKernel: size of kernel value vector " <<
  97. kernelVector.size() << " does not match number of training points " << this->vecSetLabels.size() );
  98. double yEstimate = kernelVector.scalarProduct ( InvDY );
  99. scores[1] = yEstimate;
  100. }
  101. if(this->mode==VARIANCE_DETECTION_MODE)
  102. {
  103. if ( kernelVector.size() != this->vecSetLabels.size() )
  104. fthrow(Exception, "KCGPApproxOneClass::classifyKernel: size of kernel value vector " <<
  105. kernelVector.size() << " does not match number of training points " << this->vecSetLabels.size() );
  106. NICE::Vector rightPart (this->vecSetLabels.size());
  107. for (int i = 0; i < (int)this->vecSetLabels.size(); i++)
  108. {
  109. rightPart[i] = kernelVector[i] * this->matrixDInv[i];
  110. }
  111. double uncertainty = kernelSelf - kernelVector.scalarProduct ( rightPart );
  112. scores[1] = 1.0 - uncertainty;
  113. }
  114. ClassificationResult r ( scores[1]<0.5 ? 0 : 1, scores );
  115. return r;
  116. }
  117. KCGPApproxOneClass *KCGPApproxOneClass::clone() const
  118. {
  119. return new KCGPApproxOneClass ( *this );
  120. }
  121. void KCGPApproxOneClass::store(std::ostream& ofs, int type) const
  122. {
  123. ofs << this->matrixDInv << std::endl;
  124. ofs << this->InvDY << std::endl;
  125. ofs << this->mode << std::endl;
  126. ofs << this->staticNoise << std::endl;
  127. }
  128. void KCGPApproxOneClass::restore(std::istream& ifs, int type)
  129. {
  130. ifs >> this->matrixDInv;
  131. ifs >> this->InvDY;
  132. ifs >> this->mode;
  133. ifs >> this->staticNoise;
  134. }
  135. void KCGPApproxOneClass::clear()
  136. {
  137. }