OpenNN  2.2
Open Neural Networks Library
testing_analysis.cpp
1 /****************************************************************************************************************/
2 /* */
3 /* OpenNN: Open Neural Networks Library */
4 /* www.artelnics.com/opennn */
5 /* */
6 /* T E S T I N G A N A L Y S I S C L A S S */
7 /* */
8 /* Roberto Lopez */
9 /* Artelnics - Making intelligent use of data */
11 /* */
12 /****************************************************************************************************************/
13 
14 // OpenNN includes
15 
16 #include "testing_analysis.h"
17 
18 namespace OpenNN
19 {
20 
21 // DEFAULT CONSTRUCTOR
22 
26 
28  : neural_network_pointer(NULL),
29  data_set_pointer(NULL),
30  mathematical_model_pointer(NULL)
31 {
32  set_default();
33 }
34 
35 
36 // NEURAL NETWORK CONSTRUCTOR
37 
42 
43 TestingAnalysis::TestingAnalysis(NeuralNetwork* new_neural_network_pointer)
44 : neural_network_pointer(new_neural_network_pointer),
45  data_set_pointer(NULL),
46  mathematical_model_pointer(NULL)
47 {
48  set_default();
49 }
50 
51 
52 // MATHEMATICAL MODEL CONSTRUCTOR
53 
58 
59 TestingAnalysis::TestingAnalysis(MathematicalModel* new_mathematical_model_pointer)
60 : neural_network_pointer(NULL),
61  data_set_pointer(NULL),
62  mathematical_model_pointer(new_mathematical_model_pointer)
63 {
64  set_default();
65 }
66 
67 
68 // DATA SET CONSTRUCTOR
69 
74 
76 : neural_network_pointer(NULL),
77  data_set_pointer(new_data_set_pointer),
78  mathematical_model_pointer(NULL)
79 {
80  set_default();
81 }
82 
83 
84 // NEURAL NETWORK AND MATHEMATICAL MODEL CONSTRUCTOR
85 
91 
92 TestingAnalysis::TestingAnalysis(NeuralNetwork* new_neural_network_pointer, MathematicalModel* new_mathematical_model_pointer)
93  : neural_network_pointer(new_neural_network_pointer),
94  data_set_pointer(NULL),
95  mathematical_model_pointer(new_mathematical_model_pointer)
96 {
97  set_default();
98 }
99 
100 
101 // NEURAL NETWORK AND DATA SET CONSTRUCTOR
102 
108 
109 TestingAnalysis::TestingAnalysis(NeuralNetwork* new_neural_network_pointer, DataSet* new_data_set_pointer)
110  : neural_network_pointer(new_neural_network_pointer),
111  data_set_pointer(new_data_set_pointer),
112  mathematical_model_pointer(NULL)
113 {
114  set_default();
115 }
116 
117 
118 // NEURAL NETWORK, MATHEMATICAL MODEL AND DATA SET CONSTRUCTOR
119 
126 
127 TestingAnalysis::TestingAnalysis(NeuralNetwork* new_neural_network_pointer, DataSet* new_data_set_pointer, MathematicalModel* new_mathematical_model_pointer)
128  : neural_network_pointer(new_neural_network_pointer),
129  data_set_pointer(new_data_set_pointer),
130  mathematical_model_pointer(new_mathematical_model_pointer)
131 {
132  set_default();
133 }
134 
135 
136 // XML CONSTRUCTOR
137 
142 
143 TestingAnalysis::TestingAnalysis(const tinyxml2::XMLDocument& testing_analysis_document)
144  : neural_network_pointer(NULL),
145  data_set_pointer(NULL),
146  mathematical_model_pointer(NULL)
147 {
148  set_default();
149 
150  from_XML(testing_analysis_document);
151 }
152 
153 
154 // FILE CONSTRUCTOR
155 
160 
161 TestingAnalysis::TestingAnalysis(const std::string& file_name)
162  : neural_network_pointer(NULL),
163  data_set_pointer(NULL),
164  mathematical_model_pointer(NULL)
165 {
166  set_default();
167 
168  load(file_name);
169 }
170 
171 // DESTRUCTOR
172 
175 
177 {
178 }
179 
180 
181 // METHODS
182 
183 // NeuralNetwork* get_neural_network_pointer(void) const method
184 
186 
188 {
189  #ifndef NDEBUG
190 
192  {
193  std::ostringstream buffer;
194 
195  buffer << "OpenNN Exception: TestingAnalysis class.\n"
196  << "NeuralNetwork* get_neural_network_pointer(void) const method.\n"
197  << "Neural network pointer is NULL.\n";
198 
199  throw std::logic_error(buffer.str());
200  }
201 
202  #endif
203 
204  return(neural_network_pointer);
205 }
206 
207 
208 // DataSet* get_data_set_pointer(void) const method
209 
211 
213 {
214  #ifndef NDEBUG
215 
216  if(!data_set_pointer)
217  {
218  std::ostringstream buffer;
219 
220  buffer << "OpenNN Exception: TestingAnalysis class.\n"
221  << "DataSet* get_data_set_pointer(void) const method.\n"
222  << "Data set pointer is NULL.\n";
223 
224  throw std::logic_error(buffer.str());
225  }
226 
227  #endif
228 
229  return(data_set_pointer);
230 }
231 
232 
233 // MathematicalModel* get_mathematical_model_pointer(void) const method
234 
236 
238 {
239  #ifndef NDEBUG
240 
242  {
243  std::ostringstream buffer;
244 
245  buffer << "OpenNN Exception: TestingAnalysis class.\n"
246  << "MathematicalModel* get_mathematical_model_pointer(void) const method.\n"
247  << "Mathematical model pointer is NULL.\n";
248 
249  throw std::logic_error(buffer.str());
250  }
251 
252  #endif
253 
255 }
256 
257 
258 // const bool& get_display(void) const method
259 
262 
263 const bool& TestingAnalysis::get_display(void) const
264 {
265  return(display);
266 }
267 
268 
269 // void set_default(void) method
270 
275 
277 {
278  display = true;
279 }
280 
281 
282 // void set_neural_network_pointer(NeuralNetwork*) method
283 
286 
288 {
289  neural_network_pointer = new_neural_network_pointer;
290 }
291 
292 
293 // void set_mathematical_model_pointer(MathematicalModel*) method
294 
297 
299 {
300  mathematical_model_pointer = new_mathematical_model_pointer;
301 }
302 
303 
304 // void set_data_set_pointer(DataSet*) method
305 
308 
310 {
311  data_set_pointer = new_data_set_pointer;
312 }
313 
314 
315 // void set_display(const bool&) method
316 
321 
322 void TestingAnalysis::set_display(const bool& new_display)
323 {
324  display = new_display;
325 }
326 
327 
328 // void check(void) const method
329 
335 
336 void TestingAnalysis::check(void) const
337 {
338  std::ostringstream buffer;
339 
341  {
342  buffer << "OpenNN Exception: TestingAnalysis class.\n"
343  << "void check(void) const method.\n"
344  << "Neural network pointer is NULL.\n";
345 
346  throw std::logic_error(buffer.str());
347  }
348 
349  if(!data_set_pointer)
350  {
351  buffer << "OpenNN Exception: TestingAnalysis class.\n"
352  << "void check(void) const method.\n"
353  << "Data set pointer is NULL.\n";
354 
355  throw std::logic_error(buffer.str());
356  }
357 }
358 
359 
360 // Vector< Matrix<double> > calculate_target_output_data(void) const method
361 
364 
366 {
367  // Control sentence (if debug)
368 
369  #ifndef NDEBUG
370 
371  check();
372 
373  #endif
374 
375  // Data set stuff
376 
377  const Instances& instances = data_set_pointer->get_instances();
378 
379  const size_t testing_instances_number = instances.count_testing_instances_number();
380 
381  const Matrix<double> testing_input_data = data_set_pointer->arrange_testing_input_data();
382 
384 
385  // Neural network stuff
386 
387  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
388 
389  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
390 
391  const Matrix<double> output_data = neural_network_pointer->calculate_output_data(testing_input_data);
392 
393  // Function regression testing stuff
394 
395  Vector< Matrix<double> > target_output_data(outputs_number);
396 
397  for(size_t i = 0; i < outputs_number; i++)
398  {
399  target_output_data[i].set(testing_instances_number, 2);
400 
401  target_output_data[i].set_column(0, target_data.arrange_column(i));
402  target_output_data[i].set_column(1, output_data.arrange_column(i));
403  }
404 
405  return(target_output_data);
406 }
407 
408 
409 
410 // Vector< LinearRegressionParameters<double> > calculate_linear_regression_parameters(void) const method
411 
418 
420 {
421  // Control sentence (if debug)
422 
423  #ifndef NDEBUG
424 
425  check();
426 
427  #endif
428 
429  // Data set stuff
430 
431  const Instances& instances = data_set_pointer->get_instances();
432 
433  const size_t testing_instances_number = instances.count_testing_instances_number();
434 
435  // Neural network stuff
436 
437  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
438 
439  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
440 
441  #ifndef NDEBUG
442 
443  std::ostringstream buffer;
444 
445  if(testing_instances_number == 0)
446  {
447  buffer << "OpenNN Exception: TestingAnalysis class.\n"
448  << "Vector< LinearRegressionParameters<double> > calculate_linear_regression_parameters(void) const method.\n"
449  << "Number of testing instances is zero.\n";
450 
451  throw std::logic_error(buffer.str());
452  }
453 
454  #endif
455 
456  // Calculate regression parameters
457 
460  const Matrix<double> output_data = neural_network_pointer->calculate_output_data(input_data);
461 
462  Vector<double> target_variable(testing_instances_number);
463  Vector<double> output_variable(testing_instances_number);
464 
465  Vector< LinearRegressionParameters<double> > linear_regression_parameters(outputs_number);
466 
467  for(size_t i = 0; i < outputs_number; i++)
468  {
469  target_variable = target_data.arrange_column(i);
470  output_variable = output_data.arrange_column(i);
471 
472  linear_regression_parameters[i] = output_variable.calculate_linear_regression_parameters(target_variable);
473  }
474 
475  return(linear_regression_parameters);
476 }
477 
478 
479 // TestingAnalysis::LinearRegressionResults TestingAnalysis::perform_linear_regression_analysis(void) const
480 
487 
489 {
490  check();
491 
492  const Instances& instances = data_set_pointer->get_instances();
493 
494  const size_t testing_instances_number = instances.count_testing_instances_number();
495 
496  if(testing_instances_number == 0)
497  {
498  std::ostringstream buffer;
499 
500  buffer << "OpenNN Exception: TestingAnalysis class.\n"
501  << "LinearRegressionResults perform_linear_regression_analysis(void) const method.\n"
502  << "Number of testing instances is zero.\n";
503 
504  throw std::logic_error(buffer.str());
505  }
506 
507  LinearRegressionResults linear_regression_results;
508 
509  linear_regression_results.target_output_data = calculate_target_output_data();
511 
512  return(linear_regression_results);
513 }
514 
515 
516 // void LinearRegressionResults::save(const std::string&) const method
517 
520 
521 void TestingAnalysis::LinearRegressionResults::save(const std::string& file_name) const
522 {
523  std::ofstream file(file_name.c_str());
524 
526  << "Target-output data:\n"
528 
529  file.close();
530 }
531 
532 
533 // Matrix<double> calculate_error_data(void) const method
534 
544 
546 {
547  // Data set stuff
548 
549  #ifndef NDEBUG
550 
551  check();
552 
553  #endif
554 
555  const size_t testing_instances_number = data_set_pointer->get_instances().count_testing_instances_number();
556 
557  #ifndef NDEBUG
558 
559  std::ostringstream buffer;
560 
561  if(testing_instances_number == 0)
562  {
563  buffer << "OpenNN Exception: TestingAnalysis class.\n"
564  << "Vector< Matrix<double> > calculate_error_data(void) const.\n"
565  << "Number of testing instances is zero.\n";
566 
567  throw std::logic_error(buffer.str());
568  }
569 
570  #endif
571 
572 
574 
576 
577  // Neural network stuff
578 
579  const Matrix<double> output_data = neural_network_pointer->calculate_output_data(input_data);
580 
581  const UnscalingLayer* unscaling_layer_pointer = neural_network_pointer->get_unscaling_layer_pointer();
582 
583  #ifndef NDEBUG
584 
585  if(!unscaling_layer_pointer)
586  {
587  buffer << "OpenNN Exception: TestingAnalysis class.\n"
588  << "Vector< Matrix<double> > calculate_error_data(void) const.\n"
589  << "Unscaling layer is NULL.\n";
590 
591  throw std::logic_error(buffer.str());
592  }
593 
594  #endif
595 
596  const Vector<double>& outputs_minimum = unscaling_layer_pointer->arrange_minimums();
597  const Vector<double>& outputs_maximum = unscaling_layer_pointer->arrange_maximums();
598 
599  const size_t outputs_number = unscaling_layer_pointer->get_unscaling_neurons_number();
600 
601  // Error data
602 
603  Vector< Matrix<double> > error_data(outputs_number);
604 
605  Vector<double> targets(testing_instances_number);
606  Vector<double> outputs(testing_instances_number);
607 
608  for(size_t i = 0; i < outputs_number; i++)
609  {
610  error_data[i].set(testing_instances_number, 3, 0.0);
611 
612  // Absolute error
613 
614  targets = target_data.arrange_column(i);
615  outputs = output_data.arrange_column(i);
616 
617  error_data[i].set_column(0, (targets - outputs).calculate_absolute_value());
618 
619  // Relative error
620 
621  error_data[i].set_column(1, (targets - outputs).calculate_absolute_value()/(outputs_maximum[i]-outputs_minimum[i]));
622 
623  // Percentage error
624 
625  error_data[i].set_column(2, (targets - outputs).calculate_absolute_value()*100.0/(outputs_maximum[i]-outputs_minimum[i]));
626  }
627 
628  return(error_data);
629 }
630 
631 
632 // Vector< Vector< Statistics<double> > > calculate_error_data_statistics(void) const method
633 
641 
643 {
644  // Neural network stuff
645 
646  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
647 
648  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
649 
650  // Testing analysis stuff
651 
652  Vector< Vector< Statistics<double> > > statistics(outputs_number);
653 
654  const Vector< Matrix<double> > error_data = calculate_error_data();
655 
656  for(size_t i = 0; i < outputs_number; i++)
657  {
658  statistics[i] = error_data[i].calculate_statistics();
659  }
660 
661  return(statistics);
662 }
663 
664 
665 // Vector< Matrix<double> > calculate_error_data_statistics_matrices(void) const method
666 
671 
673 {
674  const Vector< Vector< Statistics<double> > > error_data_statistics = calculate_error_data_statistics();
675 
676  const size_t outputs_number = error_data_statistics.size();
677 
678  Vector< Matrix<double> > statistics(outputs_number);
679 
680  for(size_t i = 0; i < outputs_number; i++)
681  {
682  statistics[i].set(3, 4);
683  statistics[i].set_row(0, error_data_statistics[i][0].to_vector());
684  statistics[i].set_row(1, error_data_statistics[i][1].to_vector());
685  statistics[i].set_row(2, error_data_statistics[i][2].to_vector());
686  }
687 
688  return(statistics);
689 }
690 
691 
692 // Vector< Histogram<double> > calculate_error_data_histograms(const size_t&) const method
693 
697 
699 {
700  const Vector< Matrix<double> > error_data = calculate_error_data();
701 
702  const size_t outputs_number = error_data.size();
703 
704  Vector< Histogram<double> > histograms(outputs_number);
705 
706  for(size_t i = 0; i < outputs_number; i++)
707  {
708  histograms[i] = error_data[i].arrange_column(0).calculate_histogram(bins_number);
709  }
710 
711  return(histograms);
712 }
713 
714 
715 // Vector< Vector<size_t> > calculate_maximal_errors(const size_t&) const method
716 
720 
722 {
723  const Vector< Matrix<double> > error_data = calculate_error_data();
724 
725  const size_t outputs_number = error_data.size();
726 
727  Vector< Vector<size_t> > maximal_errors(outputs_number);
728 
729  for(size_t i = 0; i < outputs_number; i++)
730  {
731  maximal_errors[i] = error_data[i].arrange_column(0).calculate_maximal_indices(instances_number);
732  }
733 
734  return(maximal_errors);
735 }
736 
737 
738 // Matrix<size_t> calculate_confusion_binary_classification(const Matrix<double>&, const Matrix<double>&) const method
739 
743 
745 {
746  const size_t rows_number = actual_data.get_rows_number();
747 
748  Matrix<size_t> confusion(2, 2);
749 
750  size_t true_positive = 0;
751  size_t false_negative = 0;
752  size_t false_positive = 0;
753  size_t true_negative = 0;
754 
755 
756 
757 
758  for(size_t i = 0; i < rows_number; i++)
759  {
760  // True positive
761 
762  if(actual_data(i,0) > 0.5 && predicted_data(i,0) > 0.5)
763  {
764  true_positive++;
765  }
766 
767  // False negative
768 
769  if(actual_data(i,0) > 0.5 && predicted_data(i,0) < 0.5)
770  {
771  false_negative++;
772  }
773 
774  // False positive
775 
776  if(actual_data(i,0) < 0.5 && predicted_data(i,0) > 0.5)
777  {
778  false_positive++;
779  }
780 
781  // True negative
782 
783  if(actual_data(i,0) < 0.5 && predicted_data(i,0) < 0.5)
784  {
785  true_negative++;
786  }
787  }
788 
789  confusion(0,0) = true_positive;
790  confusion(0,1) = false_negative;
791  confusion(1,0) = false_positive;
792  confusion(1,1) = true_negative;
793 
794  return(confusion);
795 }
796 
797 
798 // Matrix<size_t> calculate_confusion_multiple_classification(const Matrix<double>&, const Matrix<double>&) const method
799 
803 
805 {
806  const size_t rows_number = actual_data.get_rows_number();
807  const size_t columns_number = actual_data.get_columns_number();
808 
809  Matrix<size_t> confusion(columns_number, columns_number, 0);
810 
811  size_t actual_index = 0;
812  size_t predicted_index = 0;
813 
814  for(size_t i = 0; i < rows_number; i++)
815  {
816  actual_index = actual_data.arrange_row(i).calculate_maximal_index();
817  predicted_index = predicted_data.arrange_row(i).calculate_maximal_index();
818 
819  confusion(actual_index,predicted_index)++;
820  }
821 
822  return(confusion);
823 }
824 
825 
826 // Matrix<size_t> calculate_confusion(void) const method
827 
831 
833 {
834 
835  #ifndef NDEBUG
836 
837  check();
838 
839  #endif
840 
841  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
842 
843  #ifndef NDEBUG
844 
845  if(!multilayer_perceptron_pointer)
846  {
847  std::ostringstream buffer;
848 
849  buffer << "OpenNN Exception: TestingAnalysis class.\n"
850  << "Matrix<size_t> calculate_confusion(void) const method.\n"
851  << "Pointer to multilayer perceptron in neural network is NULL.\n";
852 
853  throw std::logic_error(buffer.str());
854  }
855 
856  #endif
857 
858  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
859 
860  #ifndef NDEBUG
861 
862  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
863 
864  // Control sentence
865 
866  const Variables& variables = data_set_pointer->get_variables();
867 
868  if(inputs_number != variables.count_inputs_number())
869  {
870  std::ostringstream buffer;
871 
872  buffer << "OpenNN Exception: TestingAnalysis class." << std::endl
873  << "Matrix<size_t> calculate_confusion(void) const method." << std::endl
874  << "Number of inputs in neural network must be equal to number of inputs in data set." << std::endl;
875 
876  throw std::logic_error(buffer.str());
877  }
878 
879  if(outputs_number != variables.count_targets_number())
880  {
881  std::ostringstream buffer;
882 
883  buffer << "OpenNN Exception: TestingAnalysis class." << std::endl
884  << "Matrix<size_t> calculate_confusion(void) const method." << std::endl
885  << "Number of outputs in neural network must be equal to number of targets in data set." << std::endl;
886 
887  throw std::logic_error(buffer.str());
888  }
889 
890  #endif
891 
894 
895  const Matrix<double> output_data = neural_network_pointer->calculate_output_data(input_data);
896 
897  if(outputs_number == 1)
898  {
899  return(calculate_confusion_binary_classification(target_data, output_data));
900  }
901  else
902  {
903  return(calculate_confusion_multiple_classification(target_data, output_data));
904 
905  }
906 }
907 
908 
909 // Vector<double> calculate_binary_classification_tests(void) method
910 
922 
924 {
925  // Control sentence (if debug)
926 
927  #ifndef NDEBUG
928 
929  const MultilayerPerceptron* multilayer_perceptron_pointer = neural_network_pointer->get_multilayer_perceptron_pointer();
930 
931  const size_t inputs_number = multilayer_perceptron_pointer->get_inputs_number();
932 
933  if(!data_set_pointer)
934  {
935  std::ostringstream buffer;
936 
937  buffer << "OpenNN Exception: TestingAnalysis class." << std::endl
938  << "Vector<double> calculate_binary_classification_tests(void) const." << std::endl
939  << "Data set is NULL." << std::endl;
940 
941  throw std::logic_error(buffer.str());
942  }
943 
944  const Variables& variables = data_set_pointer->get_variables();
945 
946  const size_t targets_number = variables.count_targets_number();
947 
948  const size_t outputs_number = multilayer_perceptron_pointer->get_outputs_number();
949 
950  // Control sentence
951 
952  if(inputs_number != variables.count_inputs_number())
953  {
954  std::ostringstream buffer;
955 
956  buffer << "OpenNN Exception: TestingAnalysis class." << std::endl
957  << "Vector<double> calculate_binary_classification_tests(void) const." << std::endl
958  << "Number of inputs in neural network is not equal to number of inputs in data set." << std::endl;
959 
960  throw std::logic_error(buffer.str());
961  }
962  else if(outputs_number != 1)
963  {
964  std::ostringstream buffer;
965 
966  buffer << "OpenNN Exception: TestingAnalysis class." << std::endl
967  << "Vector<double> calculate_binary_classification_tests(void) const." << std::endl
968  << "Number of outputs in neural network must be one." << std::endl;
969 
970  throw std::logic_error(buffer.str());
971  }
972  else if(targets_number != 1)
973  {
974  std::ostringstream buffer;
975 
976  buffer << "OpenNN Exception: TestingAnalysis class." << std::endl
977  << "Vector<double> calculate_binary_classification_tests(void) const." << std::endl
978  << "Number of targets in data set must be one." << std::endl;
979 
980  throw std::logic_error(buffer.str());
981  }
982 
983  #endif
984 
985  // Confusion matrix
986 
987  const Matrix<size_t> confusion = calculate_confusion();
988 
989  const size_t true_positive = confusion(0,0);
990  const size_t false_positive = confusion(0,1);
991  const size_t false_negative = confusion(1,0);
992  const size_t true_negative = confusion(1,1);
993 
994  // Classification accuracy
995 
996  double classification_accuracy;
997 
998  if(true_positive + true_negative + false_positive + false_negative == 0)
999  {
1000  classification_accuracy = 0.0;
1001  }
1002  else
1003  {
1004  classification_accuracy = (double)(true_positive + true_negative)/double(true_positive + true_negative + false_positive + false_negative);
1005  }
1006 
1007  // Error rate
1008 
1009  double error_rate;
1010 
1011  if(true_positive + true_negative + false_positive + false_negative == 0)
1012  {
1013  error_rate = 0.0;
1014  }
1015  else
1016  {
1017  error_rate = (double)(false_positive + false_negative)/(double)(true_positive + true_negative + false_positive + false_negative);
1018  }
1019 
1020  // Sensitivity
1021 
1022  double sensitivity;
1023 
1024  if(true_positive + false_negative == 0)
1025  {
1026  sensitivity = 0.0;
1027  }
1028  else
1029  {
1030  sensitivity = (double)true_positive/(double)(true_positive + false_negative);
1031  }
1032 
1033  // Specificity
1034 
1035  double specificity;
1036 
1037  if(true_negative + false_positive == 0)
1038  {
1039  specificity = 0.0;
1040  }
1041  else
1042  {
1043  specificity = (double)true_negative/(double)(true_negative + false_positive);
1044  }
1045 
1046  // Positive likelihood
1047 
1048  double positive_likelihood;
1049 
1050  if(classification_accuracy == 1.0)
1051  {
1052  positive_likelihood = 1.0;
1053  }
1054  else if(1.0 - specificity == 0.0)
1055  {
1056  positive_likelihood = 0.0;
1057  }
1058  else
1059  {
1060  positive_likelihood = sensitivity/(1.0 - specificity);
1061  }
1062 
1063  // Negative likelihood
1064 
1065  double negative_likelihood;
1066 
1067  if(classification_accuracy == 1.0)
1068  {
1069  negative_likelihood = 1.0;
1070  }
1071  else if(1.0 - sensitivity == 0.0)
1072  {
1073  negative_likelihood = 0.0;
1074  }
1075  else
1076  {
1077  negative_likelihood = specificity/(1.0 - sensitivity);
1078  }
1079 
1080  // Arrange vector
1081 
1082  Vector<double> binary_classification_test(6);
1083  binary_classification_test[0] = classification_accuracy;
1084  binary_classification_test[1] = error_rate;
1085  binary_classification_test[2] = sensitivity;
1086  binary_classification_test[3] = specificity;
1087  binary_classification_test[4] = positive_likelihood;
1088  binary_classification_test[5] = negative_likelihood;
1089 
1090  return(binary_classification_test);
1091 }
1092 
1093 
1094 // std::string to_string(void) const method
1095 
1097 
1098 std::string TestingAnalysis::to_string(void) const
1099 {
1100  std::ostringstream buffer;
1101 
1102  buffer << "Testing analysis\n"
1103  << "Display: " << display << "\n";
1104 
1105  return(buffer.str());
1106 }
1107 
1108 
1109 // void print(void) const method
1110 
1112 
1113 void TestingAnalysis::print(void) const
1114 {
1115  std::cout << to_string();
1116 }
1117 
1118 
1119 // tinyxml2::XMLDocument* to_XML(void) const method
1120 
1123 
1124 tinyxml2::XMLDocument* TestingAnalysis::to_XML(void) const
1125 {
1126  tinyxml2::XMLDocument* document = new tinyxml2::XMLDocument;
1127 
1128  std::ostringstream buffer;
1129 
1130  // Root element
1131 
1132  tinyxml2::XMLElement* testing_analysis_element = document->NewElement("TestingAnalysis");
1133 
1134  document->InsertFirstChild(testing_analysis_element);
1135 
1136  // Display
1137 
1138  tinyxml2::XMLElement* display_element = document->NewElement("Display");
1139  testing_analysis_element->LinkEndChild(display_element);
1140 
1141  buffer.str("");
1142  buffer << display;
1143 
1144  tinyxml2::XMLText* display_text = document->NewText(buffer.str().c_str());
1145  testing_analysis_element->LinkEndChild(display_text);
1146 
1147  return(document);
1148 }
1149 
1150 
1151 // void from_XML(const tinyxml2::XMLDocument&) method
1152 
1155 
1156 void TestingAnalysis::from_XML(const tinyxml2::XMLDocument& document)
1157 {
1158  std::ostringstream buffer;
1159 
1160  const tinyxml2::XMLElement* root_element = document.FirstChildElement("TestingAnalysis");
1161 
1162  if(!root_element)
1163  {
1164  buffer << "OpenNN Exception: TestingAnalysis class.\n"
1165  << "void from_XML(const tinyxml2::XMLDocument&) method.\n"
1166  << "Testing analysis element is NULL.\n";
1167 
1168  throw std::logic_error(buffer.str());
1169  }
1170 
1171  // Display
1172 
1173  const tinyxml2::XMLElement* element = root_element->FirstChildElement("Display");
1174 
1175  if(element)
1176  {
1177  std::string new_display_string = element->GetText();
1178 
1179  try
1180  {
1181  set_display(new_display_string != "0");
1182  }
1183  catch(const std::logic_error& e)
1184  {
1185  std::cout << e.what() << std::endl;
1186  }
1187  }
1188 }
1189 
1190 
1191 // void save(const std::string&) const method
1192 
1195 
1196 void TestingAnalysis::save(const std::string& file_name) const
1197 {
1198  tinyxml2::XMLDocument* document = to_XML();
1199 
1200  document->SaveFile(file_name.c_str());
1201 
1202  delete document;
1203 }
1204 
1205 
1206 // void load(const std::string&) method
1207 
1210 
1211 void TestingAnalysis::load(const std::string& file_name)
1212 {
1213  set_default();
1214 
1215  tinyxml2::XMLDocument document;
1216 
1217  if(document.LoadFile(file_name.c_str()))
1218  {
1219  std::ostringstream buffer;
1220 
1221  buffer << "OpenNN Exception: Testing analysis class.\n"
1222  << "void load(const std::string&) method.\n"
1223  << "Cannot load XML file " << file_name << ".\n";
1224 
1225  throw std::logic_error(buffer.str());
1226  }
1227 
1228  from_XML(document);
1229 }
1230 
1231 }
1232 
1233 
1234 // OpenNN: Open Neural Networks Library.
1235 // Copyright (c) 2005-2015 Roberto Lopez.
1236 //
1237 // This library is free software; you can redistribute it and/or
1238 // modify it under the terms of the GNU Lesser General Public
1239 // License as published by the Free Software Foundation; either
1240 // version 2.1 of the License, or any later version.
1241 //
1242 // This library is distributed in the hope that it will be useful,
1243 // but WITHOUT ANY WARRANTY; without even the implied warranty of
1244 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1245 // Lesser General Public License for more details.
1246 
1247 // You should have received a copy of the GNU Lesser General Public
1248 // License along with this library; if not, write to the Free Software
1249 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
DataSet * get_data_set_pointer(void) const
Returns a pointer to the data set object on which the neural network is tested.
Vector< T > arrange_column(const size_t &) const
Definition: matrix.h:1580
void print(void) const
Prints to the standard output the string representation of this testing analysis object.
const Variables & get_variables(void) const
Returns a constant reference to the variables object composing this data set object.
Definition: data_set.cpp:202
Vector< double > arrange_minimums(void) const
bool display
Display messages to screen.
size_t get_inputs_number(void) const
Returns the number of inputs to the multilayer perceptron.
NeuralNetwork * get_neural_network_pointer(void) const
Returns a pointer to the neural network object which is to be tested.
void set_mathematical_model_pointer(MathematicalModel *)
void set(void)
Sets the size of a vector to zero.
Definition: vector.h:656
Vector< size_t > calculate_maximal_indices(const size_t &) const
Definition: vector.h:1700
void set_display(const bool &)
std::string to_string(void) const
Returns a string representation of the testing analysis object.
Matrix< double > arrange_testing_target_data(void) const
Definition: data_set.cpp:669
Vector< LinearRegressionParameters< double > > linear_regression_parameters
Intercept, slope and correlation coefficient for each output variable.
size_t get_outputs_number(void) const
Returns the number of outputs neurons in the multilayer perceptron.
Vector< LinearRegressionParameters< double > > calculate_linear_regression_parameters(void) const
void set_data_set_pointer(DataSet *)
LinearRegressionParameters< T > calculate_linear_regression_parameters(const Vector< T > &) const
Definition: vector.h:2830
Histogram< T > calculate_histogram(const size_t &=10) const
Definition: vector.h:1445
Matrix< size_t > calculate_confusion_multiple_classification(const Matrix< double > &, const Matrix< double > &) const
size_t count_testing_instances_number(void) const
Returns the number of instances in the data set which will be used for testing.
Definition: instances.cpp:431
const size_t & get_columns_number(void) const
Returns the number of columns in the matrix.
Definition: matrix.h:1090
MathematicalModel * get_mathematical_model_pointer(void) const
Returns a pointer to the mathematical model object on which the neural network is tested...
Vector< Matrix< double > > calculate_error_data(void) const
Vector< Matrix< double > > calculate_error_data_statistics_matrices(void) const
MultilayerPerceptron * get_multilayer_perceptron_pointer(void) const
Returns a pointer to the multilayer perceptron composing this neural network.
size_t calculate_maximal_index(void) const
Returns the index of the largest element in the vector.
Definition: vector.h:1645
LinearRegressionResults perform_linear_regression_analysis(void) const
virtual tinyxml2::XMLDocument * to_XML(void) const
Vector< Vector< size_t > > calculate_maximal_errors(const size_t &=10) const
Matrix< double > calculate_output_data(const Matrix< double > &) const
void save(const std::string &) const
NeuralNetwork * neural_network_pointer
Pointer to the neural network object to be tested.
Matrix< size_t > calculate_confusion(void) const
Matrix< size_t > calculate_confusion_binary_classification(const Matrix< double > &, const Matrix< double > &) const
void set_neural_network_pointer(NeuralNetwork *)
Vector< Vector< Statistics< double > > > calculate_error_data_statistics(void) const
const size_t & get_rows_number(void) const
Returns the number of rows in the matrix.
Definition: matrix.h:1079
void load(const std::string &)
UnscalingLayer * get_unscaling_layer_pointer(void) const
Returns a pointer to the unscaling layer composing this neural network.
size_t get_unscaling_neurons_number(void) const
Returns the number of unscaling neurons in this layer.
Vector< Matrix< double > > target_output_data
Target data from data set and output data from neural network.
Matrix< double > arrange_testing_input_data(void) const
Definition: data_set.cpp:653
size_t count_inputs_number(void) const
Returns the number of input variables of the data set.
Definition: variables.cpp:249
Vector< double > calculate_binary_classification_tests(void) const
DataSet * data_set_pointer
Pointer to a data set object.
Statistics< T > calculate_statistics(void) const
Returns the minimum, maximum, mean and the standard deviation of the elements in the vector...
Definition: vector.h:2285
virtual void from_XML(const tinyxml2::XMLDocument &)
size_t count_targets_number(void) const
Returns the number of target variables of the data set.
Definition: variables.cpp:271
Vector< Matrix< double > > calculate_target_output_data(void) const
const bool & get_display(void) const
MathematicalModel * mathematical_model_pointer
Pointer to a mathematical model object.
Vector< double > arrange_maximums(void) const
Vector< T > arrange_row(const size_t &) const
Definition: matrix.h:1505
Vector< Histogram< double > > calculate_error_data_histograms(const size_t &=10) const
const Instances & get_instances(void) const
Returns a constant reference to the instances object composing this data set object.
Definition: data_set.cpp:222