TestGPHIKOnlineLearnable.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /**
  2. * @file TestGPHIKOnlineLearnable.cpp
  3. * @brief CppUnit-Testcase to verify that GPHIKClassifier methods herited from Persistent (store and restore) work as desired.
  4. * @author Alexander Freytag
  5. * @date 21-12-2013
  6. */
  7. #ifdef NICE_USELIB_CPPUNIT
  8. // STL includes
  9. #include <iostream>
  10. #include <vector>
  11. // NICE-core includes
  12. #include <core/basics/Config.h>
  13. #include <core/basics/Timer.h>
  14. // gp-hik-core includes
  15. #include "gp-hik-core/GPHIKClassifier.h"
  16. #include "TestGPHIKOnlineLearnable.h"
  17. using namespace std; //C basics
  18. using namespace NICE; // nice-core
  19. const bool verboseStartEnd = true;
  20. const bool verbose = false;
  21. const bool writeClassifiersForVerification = false;
  22. CPPUNIT_TEST_SUITE_REGISTRATION( TestGPHIKOnlineLearnable );
  23. void TestGPHIKOnlineLearnable::setUp() {
  24. }
  25. void TestGPHIKOnlineLearnable::tearDown() {
  26. }
  27. void readData ( const std::string filename, NICE::Matrix & data, NICE::Vector & yBin, NICE::Vector & yMulti )
  28. {
  29. std::ifstream ifs ( filename.c_str() , ios::in );
  30. if ( ifs.good() )
  31. {
  32. ifs >> data;
  33. ifs >> yBin;
  34. ifs >> yMulti;
  35. ifs.close();
  36. }
  37. else
  38. {
  39. std::cerr << "Unable to read data from file " << filename << " -- aborting." << std::endl;
  40. CPPUNIT_ASSERT ( ifs.good() );
  41. }
  42. }
  43. void prepareLabelMappings (std::map<int,int> & mapClNoToIdxTrain, const GPHIKClassifier * classifier, std::map<int,int> & mapClNoToIdxTest, const NICE::Vector & yMultiTest)
  44. {
  45. // determine classes known during training and corresponding mapping
  46. // thereby allow for non-continous class labels
  47. std::set<int> classesKnownTraining = classifier->getKnownClassNumbers();
  48. int noClassesKnownTraining ( classesKnownTraining.size() );
  49. std::set<int>::const_iterator clTrIt = classesKnownTraining.begin();
  50. for ( int i=0; i < noClassesKnownTraining; i++, clTrIt++ )
  51. mapClNoToIdxTrain.insert ( std::pair<int,int> ( *clTrIt, i ) );
  52. // determine classes known during testing and corresponding mapping
  53. // thereby allow for non-continous class labels
  54. std::set<int> classesKnownTest;
  55. classesKnownTest.clear();
  56. // determine which classes we have in our label vector
  57. // -> MATLAB: myClasses = unique(y);
  58. for ( NICE::Vector::const_iterator it = yMultiTest.begin(); it != yMultiTest.end(); it++ )
  59. {
  60. if ( classesKnownTest.find ( *it ) == classesKnownTest.end() )
  61. {
  62. classesKnownTest.insert ( *it );
  63. }
  64. }
  65. int noClassesKnownTest ( classesKnownTest.size() );
  66. std::set<int>::const_iterator clTestIt = classesKnownTest.begin();
  67. for ( int i=0; i < noClassesKnownTest; i++, clTestIt++ )
  68. mapClNoToIdxTest.insert ( std::pair<int,int> ( *clTestIt, i ) );
  69. }
  70. void evaluateClassifier ( NICE::Matrix & confusionMatrix,
  71. const NICE::GPHIKClassifier * classifier,
  72. const NICE::Matrix & data,
  73. const NICE::Vector & yMulti,
  74. const std::map<int,int> & mapClNoToIdxTrain,
  75. const std::map<int,int> & mapClNoToIdxTest
  76. )
  77. {
  78. int i_loopEnd ( (int)data.rows() );
  79. for (int i = 0; i < i_loopEnd ; i++)
  80. {
  81. NICE::Vector example ( data.getRow(i) );
  82. NICE::SparseVector scores;
  83. int result;
  84. // classify with incrementally trained classifier
  85. classifier->classify( &example, result, scores );
  86. confusionMatrix( mapClNoToIdxTrain.find(result)->second, mapClNoToIdxTest.find(yMulti[i])->second ) += 1.0;
  87. }
  88. }
  89. void compareClassifierOutputs ( const NICE::GPHIKClassifier * classifier,
  90. const NICE::GPHIKClassifier * classifierScratch,
  91. const NICE::Matrix & data
  92. )
  93. {
  94. int i_loopEnd ( (int)data.rows() );
  95. for (int i = 0; i < i_loopEnd ; i++)
  96. {
  97. NICE::Vector example ( data.getRow(i) );
  98. NICE::SparseVector scores;
  99. int result;
  100. // classify with incrementally trained classifier
  101. classifier->classify( &example, result, scores );
  102. NICE::SparseVector scoresScratch;
  103. int resultScratch;
  104. classifierScratch->classify( &example, resultScratch, scoresScratch );
  105. bool equal(true);
  106. NICE::SparseVector::const_iterator itScores = scores.begin();
  107. NICE::SparseVector::const_iterator itScoresScratch = scoresScratch.begin();
  108. for ( ; itScores != scores.end(); itScores++, itScoresScratch++)
  109. {
  110. if ( fabs( itScores->second - itScores->second ) > 10e-3)
  111. {
  112. std::cerr << " itScores->second: " << itScores->second << " itScores->second: " << itScores->second << std::endl;
  113. equal = false;
  114. break;
  115. }
  116. }
  117. CPPUNIT_ASSERT_EQUAL ( equal, true );
  118. }
  119. }
  120. void TestGPHIKOnlineLearnable::testOnlineLearningStartEmpty()
  121. {
  122. if (verboseStartEnd)
  123. std::cerr << "================== TestGPHIKOnlineLearnable::testOnlineLearningStartEmpty ===================== " << std::endl;
  124. NICE::Config conf;
  125. conf.sB ( "GPHIKClassifier", "eig_verbose", false);
  126. conf.sS ( "GPHIKClassifier", "optimization_method", "downhillsimplex");
  127. std::string s_trainData = conf.gS( "main", "trainData", "toyExampleSmallScaleTrain.data" );
  128. //------------- read the training data --------------
  129. NICE::Matrix dataTrain;
  130. NICE::Vector yBinTrain;
  131. NICE::Vector yMultiTrain;
  132. readData ( s_trainData, dataTrain, yBinTrain, yMultiTrain );
  133. //----------------- convert data to sparse data structures ---------
  134. std::vector< const NICE::SparseVector *> examplesTrain;
  135. examplesTrain.resize( dataTrain.rows() );
  136. std::vector< const NICE::SparseVector *>::iterator exTrainIt = examplesTrain.begin();
  137. for (int i = 0; i < (int)dataTrain.rows(); i++, exTrainIt++)
  138. {
  139. *exTrainIt = new NICE::SparseVector( dataTrain.getRow(i) );
  140. }
  141. //create classifier object
  142. NICE::GPHIKClassifier * classifier;
  143. classifier = new NICE::GPHIKClassifier ( &conf );
  144. bool performOptimizationAfterIncrement ( true );
  145. // add training samples, but without running training method first
  146. classifier->addMultipleExamples ( examplesTrain,yMultiTrain, performOptimizationAfterIncrement );
  147. // create second object trained in the standard way
  148. NICE::GPHIKClassifier * classifierScratch = new NICE::GPHIKClassifier ( &conf );
  149. classifierScratch->train ( examplesTrain, yMultiTrain );
  150. // TEST both classifiers to produce equal results
  151. //------------- read the test data --------------
  152. NICE::Matrix dataTest;
  153. NICE::Vector yBinTest;
  154. NICE::Vector yMultiTest;
  155. std::string s_testData = conf.gS( "main", "testData", "toyExampleTest.data" );
  156. readData ( s_testData, dataTest, yBinTest, yMultiTest );
  157. // ------------------------------------------
  158. // ------------- PREPARATION --------------
  159. // ------------------------------------------
  160. // determine classes known during training/testing and corresponding mapping
  161. // thereby allow for non-continous class labels
  162. std::map<int,int> mapClNoToIdxTrain;
  163. std::map<int,int> mapClNoToIdxTest;
  164. prepareLabelMappings (mapClNoToIdxTrain, classifier, mapClNoToIdxTest, yMultiTest);
  165. NICE::Matrix confusionMatrix ( mapClNoToIdxTrain.size(), mapClNoToIdxTest.size(), 0.0);
  166. NICE::Matrix confusionMatrixScratch ( mapClNoToIdxTrain.size(), mapClNoToIdxTest.size(), 0.0);
  167. // ------------------------------------------
  168. // ------------- CLASSIFICATION --------------
  169. // ------------------------------------------
  170. evaluateClassifier ( confusionMatrix, classifier, dataTest, yMultiTest,
  171. mapClNoToIdxTrain,mapClNoToIdxTest );
  172. evaluateClassifier ( confusionMatrixScratch, classifierScratch, dataTest, yMultiTest,
  173. mapClNoToIdxTrain,mapClNoToIdxTest );
  174. // post-process confusion matrices
  175. confusionMatrix.normalizeColumnsL1();
  176. double arr ( confusionMatrix.trace()/confusionMatrix.cols() );
  177. confusionMatrixScratch.normalizeColumnsL1();
  178. double arrScratch ( confusionMatrixScratch.trace()/confusionMatrixScratch.cols() );
  179. if ( verbose )
  180. {
  181. std::cerr << "confusionMatrix: " << confusionMatrix << std::endl;
  182. std::cerr << "confusionMatrixScratch: " << confusionMatrixScratch << std::endl;
  183. }
  184. CPPUNIT_ASSERT_DOUBLES_EQUAL( arr, arrScratch, 1e-8);
  185. // don't waste memory
  186. delete classifier;
  187. delete classifierScratch;
  188. for (std::vector< const NICE::SparseVector *>::iterator exTrainIt = examplesTrain.begin(); exTrainIt != examplesTrain.end(); exTrainIt++)
  189. {
  190. delete *exTrainIt;
  191. }
  192. if (verboseStartEnd)
  193. std::cerr << "================== TestGPHIKOnlineLearnable::testOnlineLearningStartEmpty done ===================== " << std::endl;
  194. }
  195. void TestGPHIKOnlineLearnable::testOnlineLearningOCCtoBinary()
  196. {
  197. if (verboseStartEnd)
  198. std::cerr << "================== TestGPHIKOnlineLearnable::testOnlineLearningOCCtoBinary ===================== " << std::endl;
  199. NICE::Config conf;
  200. conf.sB ( "GPHIKClassifier", "eig_verbose", false);
  201. conf.sS ( "GPHIKClassifier", "optimization_method", "downhillsimplex");
  202. std::string s_trainData = conf.gS( "main", "trainData", "toyExampleSmallScaleTrain.data" );
  203. //------------- read the training data --------------
  204. NICE::Matrix dataTrain;
  205. NICE::Vector yBinTrain;
  206. NICE::Vector yMultiTrain;
  207. readData ( s_trainData, dataTrain, yBinTrain, yMultiTrain );
  208. //----------------- convert data to sparse data structures ---------
  209. std::vector< const NICE::SparseVector *> examplesTrain;
  210. std::vector< const NICE::SparseVector *> examplesTrainPlus;
  211. std::vector< const NICE::SparseVector *> examplesTrainMinus;
  212. examplesTrain.resize( dataTrain.rows() );
  213. // to check whether non-consecutive and even wrongly odered class numbers work as well
  214. int clNoFirst ( 2 );
  215. int clNoSecond ( 0 );
  216. std::vector< const NICE::SparseVector *>::iterator exTrainIt = examplesTrain.begin();
  217. for (int i = 0; i < (int)dataTrain.rows(); i++, exTrainIt++)
  218. {
  219. *exTrainIt = new NICE::SparseVector( dataTrain.getRow(i) );
  220. if ( yBinTrain[i] == 1 )
  221. {
  222. examplesTrainPlus.push_back ( *exTrainIt );
  223. yBinTrain[i] = clNoFirst;
  224. }
  225. else
  226. {
  227. examplesTrainMinus.push_back ( *exTrainIt );
  228. yBinTrain[i] = clNoSecond;
  229. }
  230. }
  231. NICE::Vector yBinPlus ( examplesTrainPlus.size(), clNoFirst ) ;
  232. NICE::Vector yBinMinus ( examplesTrainMinus.size(), clNoSecond );
  233. //create classifier object
  234. NICE::GPHIKClassifier * classifier;
  235. classifier = new NICE::GPHIKClassifier ( &conf );
  236. bool performOptimizationAfterIncrement ( true );
  237. // training with examples for positive class only
  238. classifier->train ( examplesTrainPlus, yBinPlus );
  239. // add samples for negative class, thereby going from OCC to binary setting
  240. classifier->addMultipleExamples ( examplesTrainMinus, yBinMinus, performOptimizationAfterIncrement );
  241. // create second object trained in the standard way
  242. NICE::GPHIKClassifier * classifierScratch = new NICE::GPHIKClassifier ( &conf );
  243. classifierScratch->train ( examplesTrain, yBinTrain );
  244. // TEST both classifiers to produce equal results
  245. //------------- read the test data --------------
  246. NICE::Matrix dataTest;
  247. NICE::Vector yBinTest;
  248. NICE::Vector yMultiTest;
  249. std::string s_testData = conf.gS( "main", "testData", "toyExampleTest.data" );
  250. readData ( s_testData, dataTest, yBinTest, yMultiTest );
  251. // ------------------------------------------
  252. // ------------- PREPARATION --------------
  253. // ------------------------------------------
  254. // determine classes known during training/testing and corresponding mapping
  255. // thereby allow for non-continous class labels
  256. std::map<int,int> mapClNoToIdxTrain;
  257. std::map<int,int> mapClNoToIdxTest;
  258. prepareLabelMappings (mapClNoToIdxTrain, classifier, mapClNoToIdxTest, yMultiTest);
  259. NICE::Matrix confusionMatrix ( mapClNoToIdxTrain.size(), mapClNoToIdxTest.size(), 0.0);
  260. NICE::Matrix confusionMatrixScratch ( mapClNoToIdxTrain.size(), mapClNoToIdxTest.size(), 0.0);
  261. // ------------------------------------------
  262. // ------------- CLASSIFICATION --------------
  263. // ------------------------------------------
  264. evaluateClassifier ( confusionMatrix, classifier, dataTest, yBinTest,
  265. mapClNoToIdxTrain,mapClNoToIdxTest );
  266. evaluateClassifier ( confusionMatrixScratch, classifierScratch, dataTest, yBinTest,
  267. mapClNoToIdxTrain,mapClNoToIdxTest );
  268. // post-process confusion matrices
  269. confusionMatrix.normalizeColumnsL1();
  270. double arr ( confusionMatrix.trace()/confusionMatrix.cols() );
  271. confusionMatrixScratch.normalizeColumnsL1();
  272. double arrScratch ( confusionMatrixScratch.trace()/confusionMatrixScratch.cols() );
  273. if ( verbose )
  274. {
  275. std::cerr << "confusionMatrix: " << confusionMatrix << std::endl;
  276. std::cerr << "confusionMatrixScratch: " << confusionMatrixScratch << std::endl;
  277. }
  278. CPPUNIT_ASSERT_DOUBLES_EQUAL( arr, arrScratch, 1e-8);
  279. // don't waste memory
  280. delete classifier;
  281. delete classifierScratch;
  282. for (std::vector< const NICE::SparseVector *>::iterator exTrainIt = examplesTrain.begin(); exTrainIt != examplesTrain.end(); exTrainIt++)
  283. {
  284. delete *exTrainIt;
  285. }
  286. if (verboseStartEnd)
  287. std::cerr << "================== TestGPHIKOnlineLearnable::testOnlineLearningOCCtoBinary done ===================== " << std::endl;
  288. }
  289. void TestGPHIKOnlineLearnable::testOnlineLearningBinarytoMultiClass()
  290. {
  291. if (verboseStartEnd)
  292. std::cerr << "================== TestGPHIKOnlineLearnable::testOnlineLearningBinarytoMultiClass ===================== " << std::endl;
  293. NICE::Config conf;
  294. conf.sB ( "GPHIKClassifier", "eig_verbose", false);
  295. conf.sS ( "GPHIKClassifier", "optimization_method", "downhillsimplex");
  296. // conf.sS ( "GPHIKClassifier", "optimization_method", "none");
  297. std::string s_trainData = conf.gS( "main", "trainData", "toyExampleSmallScaleTrain.data" );
  298. //------------- read the training data --------------
  299. NICE::Matrix dataTrain;
  300. NICE::Vector yBinTrain;
  301. NICE::Vector yMultiTrain;
  302. readData ( s_trainData, dataTrain, yBinTrain, yMultiTrain );
  303. //----------------- convert data to sparse data structures ---------
  304. std::vector< const NICE::SparseVector *> examplesTrain;
  305. std::vector< const NICE::SparseVector *> examplesTrain12;
  306. std::vector< const NICE::SparseVector *> examplesTrain3;
  307. NICE::Vector yMulti12 ( yMultiTrain.size(), 1 ) ;
  308. NICE::Vector yMulti3 ( yMultiTrain.size(), 1 ) ;
  309. int cnt12 ( 0 );
  310. int cnt3 ( 0 );
  311. examplesTrain.resize( dataTrain.rows() );
  312. std::vector< const NICE::SparseVector *>::iterator exTrainIt = examplesTrain.begin();
  313. for (int i = 0; i < (int)dataTrain.rows(); i++, exTrainIt++)
  314. {
  315. *exTrainIt = new NICE::SparseVector( dataTrain.getRow(i) );
  316. if ( ( yMultiTrain[i] == 0 ) || ( yMultiTrain[i] == 1 ) )
  317. {
  318. examplesTrain12.push_back ( *exTrainIt );
  319. yMulti12[ cnt12 ] = yMultiTrain[i];
  320. cnt12++;
  321. }
  322. else
  323. {
  324. examplesTrain3.push_back ( *exTrainIt );
  325. yMulti3[cnt3] = 2;
  326. cnt3++;
  327. }
  328. }
  329. yMulti12.resize ( examplesTrain12.size() );
  330. yMulti3.resize ( examplesTrain3.size() );
  331. //create classifier object
  332. NICE::GPHIKClassifier * classifier;
  333. classifier = new NICE::GPHIKClassifier ( &conf );
  334. bool performOptimizationAfterIncrement ( true );
  335. // training with examples for first and second class only
  336. classifier->train ( examplesTrain12, yMulti12 );
  337. // add samples for third class, thereby going from binary to multi-class setting
  338. classifier->addMultipleExamples ( examplesTrain3, yMulti3, performOptimizationAfterIncrement );
  339. // create second object trained in the standard way
  340. NICE::GPHIKClassifier * classifierScratch = new NICE::GPHIKClassifier ( &conf );
  341. classifierScratch->train ( examplesTrain, yMultiTrain );
  342. // TEST both classifiers to produce equal results
  343. //------------- read the test data --------------
  344. NICE::Matrix dataTest;
  345. NICE::Vector yBinTest;
  346. NICE::Vector yMultiTest;
  347. std::string s_testData = conf.gS( "main", "testData", "toyExampleTest.data" );
  348. readData ( s_testData, dataTest, yBinTest, yMultiTest );
  349. // ------------------------------------------
  350. // ------------- PREPARATION --------------
  351. // ------------------------------------------
  352. // determine classes known during training/testing and corresponding mapping
  353. // thereby allow for non-continous class labels
  354. std::map<int,int> mapClNoToIdxTrain;
  355. std::map<int,int> mapClNoToIdxTest;
  356. prepareLabelMappings (mapClNoToIdxTrain, classifier, mapClNoToIdxTest, yMultiTest);
  357. NICE::Matrix confusionMatrix ( mapClNoToIdxTrain.size(), mapClNoToIdxTest.size(), 0.0);
  358. NICE::Matrix confusionMatrixScratch ( mapClNoToIdxTrain.size(), mapClNoToIdxTest.size(), 0.0);
  359. // ------------------------------------------
  360. // ------------- CLASSIFICATION --------------
  361. // ------------------------------------------
  362. compareClassifierOutputs ( classifier, classifierScratch, dataTest );
  363. evaluateClassifier ( confusionMatrix, classifier, dataTest, yMultiTest,
  364. mapClNoToIdxTrain,mapClNoToIdxTest );
  365. evaluateClassifier ( confusionMatrixScratch, classifierScratch, dataTest, yMultiTest,
  366. mapClNoToIdxTrain,mapClNoToIdxTest );
  367. // post-process confusion matrices
  368. confusionMatrix.normalizeColumnsL1();
  369. double arr ( confusionMatrix.trace()/confusionMatrix.cols() );
  370. confusionMatrixScratch.normalizeColumnsL1();
  371. double arrScratch ( confusionMatrixScratch.trace()/confusionMatrixScratch.cols() );
  372. if ( verbose )
  373. {
  374. std::cerr << "confusionMatrix: " << confusionMatrix << std::endl;
  375. std::cerr << "confusionMatrixScratch: " << confusionMatrixScratch << std::endl;
  376. }
  377. CPPUNIT_ASSERT_DOUBLES_EQUAL( arr, arrScratch, 1e-8);
  378. // don't waste memory
  379. delete classifier;
  380. delete classifierScratch;
  381. for (std::vector< const NICE::SparseVector *>::iterator exTrainIt = examplesTrain.begin(); exTrainIt != examplesTrain.end(); exTrainIt++)
  382. {
  383. delete *exTrainIt;
  384. }
  385. if (verboseStartEnd)
  386. std::cerr << "================== TestGPHIKOnlineLearnable::testOnlineLearningBinarytoMultiClass done ===================== " << std::endl;
  387. }
  388. void TestGPHIKOnlineLearnable::testOnlineLearningMultiClass()
  389. {
  390. if (verboseStartEnd)
  391. std::cerr << "================== TestGPHIKOnlineLearnable::testOnlineLearningMultiClass ===================== " << std::endl;
  392. NICE::Config conf;
  393. conf.sB ( "GPHIKClassifier", "eig_verbose", false);
  394. conf.sS ( "GPHIKClassifier", "optimization_method", "downhillsimplex");//downhillsimplex greedy
  395. std::string s_trainData = conf.gS( "main", "trainData", "toyExampleSmallScaleTrain.data" );
  396. //------------- read the training data --------------
  397. NICE::Matrix dataTrain;
  398. NICE::Vector yBinTrain;
  399. NICE::Vector yMultiTrain;
  400. readData ( s_trainData, dataTrain, yBinTrain, yMultiTrain );
  401. //----------------- convert data to sparse data structures ---------
  402. std::vector< const NICE::SparseVector *> examplesTrain;
  403. examplesTrain.resize( dataTrain.rows()-1 );
  404. std::vector< const NICE::SparseVector *>::iterator exTrainIt = examplesTrain.begin();
  405. for (int i = 0; i < (int)dataTrain.rows()-1; i++, exTrainIt++)
  406. {
  407. *exTrainIt = new NICE::SparseVector( dataTrain.getRow(i) );
  408. }
  409. // TRAIN INITIAL CLASSIFIER FROM SCRATCH
  410. NICE::GPHIKClassifier * classifier;
  411. classifier = new NICE::GPHIKClassifier ( &conf );
  412. //use all but the first example for training and add the first one lateron
  413. NICE::Vector yMultiRelevantTrain ( yMultiTrain.getRangeRef( 0, yMultiTrain.size()-2 ) );
  414. classifier->train ( examplesTrain , yMultiRelevantTrain );
  415. // RUN INCREMENTAL LEARNING
  416. bool performOptimizationAfterIncrement ( true );
  417. NICE::SparseVector * exampleToAdd = new NICE::SparseVector ( dataTrain.getRow( (int)dataTrain.rows()-1 ) );
  418. classifier->addExample ( exampleToAdd, yMultiTrain[ (int)dataTrain.rows()-2 ], performOptimizationAfterIncrement );
  419. if ( verbose )
  420. std::cerr << "label of example to add: " << yMultiTrain[ (int)dataTrain.rows()-1 ] << std::endl;
  421. // TRAIN SECOND CLASSIFIER FROM SCRATCH USING THE SAME OVERALL AMOUNT OF EXAMPLES
  422. examplesTrain.push_back( exampleToAdd );
  423. NICE::GPHIKClassifier * classifierScratch = new NICE::GPHIKClassifier ( &conf );
  424. classifierScratch->train ( examplesTrain, yMultiTrain );
  425. if ( verbose )
  426. std::cerr << "trained both classifiers - now start evaluating them" << std::endl;
  427. // TEST that both classifiers produce equal store-files
  428. if ( writeClassifiersForVerification )
  429. {
  430. std::string s_destination_save_IL ( "myClassifierIL.txt" );
  431. std::filebuf fbOut;
  432. fbOut.open ( s_destination_save_IL.c_str(), ios::out );
  433. std::ostream os (&fbOut);
  434. //
  435. classifier->store( os );
  436. //
  437. fbOut.close();
  438. std::string s_destination_save_scratch ( "myClassifierScratch.txt" );
  439. std::filebuf fbOutScratch;
  440. fbOutScratch.open ( s_destination_save_scratch.c_str(), ios::out );
  441. std::ostream osScratch (&fbOutScratch);
  442. //
  443. classifierScratch->store( osScratch );
  444. //
  445. fbOutScratch.close();
  446. }
  447. // TEST both classifiers to produce equal results
  448. //------------- read the test data --------------
  449. NICE::Matrix dataTest;
  450. NICE::Vector yBinTest;
  451. NICE::Vector yMultiTest;
  452. std::string s_testData = conf.gS( "main", "testData", "toyExampleTest.data" );
  453. readData ( s_testData, dataTest, yBinTest, yMultiTest );
  454. // ------------------------------------------
  455. // ------------- PREPARATION --------------
  456. // ------------------------------------------
  457. // determine classes known during training/testing and corresponding mapping
  458. // thereby allow for non-continous class labels
  459. std::map<int,int> mapClNoToIdxTrain;
  460. std::map<int,int> mapClNoToIdxTest;
  461. prepareLabelMappings (mapClNoToIdxTrain, classifier, mapClNoToIdxTest, yMultiTest);
  462. NICE::Matrix confusionMatrix ( mapClNoToIdxTrain.size(), mapClNoToIdxTest.size(), 0.0);
  463. NICE::Matrix confusionMatrixScratch ( mapClNoToIdxTrain.size(), mapClNoToIdxTest.size(), 0.0);
  464. // ------------------------------------------
  465. // ------------- CLASSIFICATION --------------
  466. // ------------------------------------------
  467. evaluateClassifier ( confusionMatrix, classifier, dataTest, yMultiTest,
  468. mapClNoToIdxTrain,mapClNoToIdxTest );
  469. evaluateClassifier ( confusionMatrixScratch, classifierScratch, dataTest, yMultiTest,
  470. mapClNoToIdxTrain,mapClNoToIdxTest );
  471. // post-process confusion matrices
  472. confusionMatrix.normalizeColumnsL1();
  473. double arr ( confusionMatrix.trace()/confusionMatrix.cols() );
  474. confusionMatrixScratch.normalizeColumnsL1();
  475. double arrScratch ( confusionMatrixScratch.trace()/confusionMatrixScratch.cols() );
  476. if ( verbose )
  477. {
  478. std::cerr << "confusionMatrix: " << confusionMatrix << std::endl;
  479. std::cerr << "confusionMatrixScratch: " << confusionMatrixScratch << std::endl;
  480. }
  481. CPPUNIT_ASSERT_DOUBLES_EQUAL( arr, arrScratch, 1e-8);
  482. // don't waste memory
  483. delete classifier;
  484. delete classifierScratch;
  485. for (std::vector< const NICE::SparseVector *>::iterator exTrainIt = examplesTrain.begin(); exTrainIt != examplesTrain.end(); exTrainIt++)
  486. {
  487. delete *exTrainIt;
  488. }
  489. if (verboseStartEnd)
  490. std::cerr << "================== TestGPHIKOnlineLearnable::testOnlineLearningMultiClass done ===================== " << std::endl;
  491. }
  492. #endif