TestGPHIKOnlineLearnable.cpp 24 KB

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