TestGPHIKOnlineLearnable.cpp 23 KB

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