Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkVigraRandomForestTest.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include <mitkTestingMacros.h>
18 #include <mitkTestFixture.h>
19 #include "mitkIOUtil.h"
20 #include "itkArray2D.h"
21 
22 #include <itkCSVArray2DFileReader.h>
23 #include <itkCSVArray2DDataObject.h>
25 #include <itkLabelSampler.h>
26 #include <itkAddImageFilter.h>
27 #include <mitkImageCast.h>
29 
30 class mitkVigraRandomForestTestSuite : public mitk::TestFixture
31 {
32  CPPUNIT_TEST_SUITE(mitkVigraRandomForestTestSuite );
33  // MITK_TEST(Load_RandomForestBaseDataUsingIOUtil_shouldReturnTrue);
34  // MITK_TEST(Save_RandomForestBaseDataUsingIOUtil_shouldReturnTrue);
35 
36  // MITK_TEST(LoadWithMitkOptions_RandomForestBaseDataUsingIOUtil_shouldReturnTrue);
37  // MITK_TEST(SaveWithMitkOptions_RandomForestBaseDataUsingIOUtil_shouldReturnTrue);
38 
39  MITK_TEST(TrainThreadedDecisionForest_MatlabDataSet_shouldReturnTrue);
40  MITK_TEST(PredictWeightedDecisionForest_SetWeightsToZero_shouldReturnTrue);
41  MITK_TEST(TrainThreadedDecisionForest_BreastCancerDataSet_shouldReturnTrue);
42  CPPUNIT_TEST_SUITE_END();
43 
44 private:
45 
46  typedef Eigen::Matrix<double ,Eigen::Dynamic,Eigen::Dynamic> MatrixDoubleType;
47  typedef Eigen::Matrix<int, Eigen::Dynamic,Eigen::Dynamic> MatrixIntType;
48 
49  std::pair<MatrixDoubleType, MatrixDoubleType> FeatureData_Cancer;
50  std::pair<MatrixIntType, MatrixIntType> LabelData_Cancer;
51 
52  std::pair<MatrixDoubleType, MatrixDoubleType> FeatureData_Matlab;
53  std::pair<MatrixIntType, MatrixIntType> LabelData_Matlab;
54 
56 
57 public:
58 
59  // ------------------------------------------------------------------------------------------------------
60  // ------------------------------------------------------------------------------------------------------
61 
62 
63  void setUp()
64  {
65  FeatureData_Cancer = convertCSVToMatrix<double>(GetTestDataFilePath("Classification/FeaturematrixBreastcancer.csv"),';',0.5,true);
66  LabelData_Cancer = convertCSVToMatrix<int>(GetTestDataFilePath("Classification/LabelmatrixBreastcancer.csv"),';',0.5,false);
67  FeatureData_Matlab = convertCSVToMatrix<double>(GetTestDataFilePath("Classification/FeaturematrixMatlab.csv"),';',0.5,true);
68  LabelData_Matlab = convertCSVToMatrix<int>(GetTestDataFilePath("Classification/LabelmatrixMatlab.csv"),';',0.5,false);
70  }
71 
72  void tearDown()
73  {
74  classifier = nullptr;
75  }
76 
77  // ------------------------------------------------------------------------------------------------------
78  // ------------------------------------------------------------------------------------------------------
79  /*
80  Train the classifier with an exampledataset of mattlab.
81  Note: The included data are gaußan normaldistributed.
82  */
83  void TrainThreadedDecisionForest_MatlabDataSet_shouldReturnTrue()
84  {
85 
86  auto & Features_Training = FeatureData_Matlab.first;
87  auto & Labels_Training = LabelData_Matlab.first;
88 
89  auto & Features_Testing = FeatureData_Matlab.second;
90  auto & Labels_Testing = LabelData_Matlab.second;
91 
92  /* Train the classifier, by giving trainingdataset for the labels and features.
93  The result in an colunmvector of the labels.*/
94  classifier->Train(Features_Training,Labels_Training);
95  Eigen::MatrixXi classes = classifier->Predict(Features_Testing);
96 
97  /* Testing the matching between the calculated colunmvector and the result of the RandomForest */
98  unsigned int testmatrix_rows = classes.rows();
99 
100  unsigned int correctly_classified_rows = 0;
101  for(unsigned int i= 0; i < testmatrix_rows; i++){
102  if(classes(i,0) == Labels_Testing(i,0)){
103  correctly_classified_rows++;
104  }
105  }
106 
107  MITK_TEST_CONDITION(correctly_classified_rows == testmatrix_rows, "Matlab Data correctly classified");
108  }
109 
110  // ------------------------------------------------------------------------------------------------------
111  // ------------------------------------------------------------------------------------------------------
112  /*
113  Train the classifier with the dataset of breastcancer patients from the
114  LibSVM Libary
115  */
116  void TrainThreadedDecisionForest_BreastCancerDataSet_shouldReturnTrue()
117  {
118 
119  auto & Features_Training = FeatureData_Cancer.first;
120  auto & Features_Testing = FeatureData_Cancer.second;
121  auto & Labels_Training = LabelData_Cancer.first;
122  auto & Labels_Testing = LabelData_Cancer.second;
123 
124 
125  /* Train the classifier, by giving trainingdataset for the labels and features.
126  The result in an colunmvector of the labels.*/
127  classifier->Train(Features_Training,Labels_Training);
128  Eigen::MatrixXi classes = classifier->Predict(Features_Testing);
129 
130  /* Testing the matching between the calculated colunmvector and the result of the RandomForest */
131  unsigned int maxrows = classes.rows();
132 
133  bool isYPredictVector = false;
134  int count = 0;
135 
136  for(unsigned int i= 0; i < maxrows; i++){
137  if(classes(i,0) == Labels_Testing(i,0)){
138  isYPredictVector = true;
139  count++;
140  }
141  }
142  MITK_TEST_CONDITION(isIntervall<int>(Labels_Testing,classes,98,99),"Testvalue of cancer data set is in range.");
143  }
144 
145  // ------------------------------------------------------------------------------------------------------
146  // ------------------------------------------------------------------------------------------------------
147 
148  void PredictWeightedDecisionForest_SetWeightsToZero_shouldReturnTrue()
149  {
150 
151  auto & Features_Training = FeatureData_Matlab.first;
152  auto & Features_Testing = FeatureData_Matlab.second;
153  auto & Labels_Training = LabelData_Matlab.first;
154 // auto & Labels_Testing = LabelData_Matlab.second;
155 
156  classifier->Train(Features_Training,Labels_Training);
157 
158  // get weights type resize it and set all weights to zero
159  auto weights = classifier->GetTreeWeights();
160  weights.resize(classifier->GetRandomForest().tree_count(),1);
161  weights.fill(0);
162 
163  classifier->SetTreeWeights(weights);
164 
165  // if all wieghts zero the missclassification rate mus be high
166  Eigen::MatrixXi classes = classifier->PredictWeighted(Features_Testing);
167 
168  /* Testing the matching between the calculated colunmvector and the result of the RandomForest */
169  unsigned int maxrows = classes.rows();
170  unsigned int count = 0;
171 
172  // check if all predictions are of class 1
173  for(unsigned int i= 0; i < maxrows; i++)
174  if(classes(i,0) == 1)
175  count++;
176 
177  MITK_TEST_CONDITION( (count == maxrows) ,"Weighted prediction - weights applied (all weights = 0).");
178  }
179 
180 
181  // ------------------------------------------------------------------------------------------------------
182  // ------------------------------------------------------------------------------------------------------
183  /*Reading an file, which includes the trainingdataset and the testdataset, and convert the
184  content of the file into an 2dim matrixpair.
185  There are an delimiter, which separates the matrix into an trainingmatrix and testmatrix */
186  template<typename T>
187  std::pair<Eigen::Matrix<T ,Eigen::Dynamic,Eigen::Dynamic>,Eigen::Matrix<T ,Eigen::Dynamic,Eigen::Dynamic> >convertCSVToMatrix(const std::string &path, char delimiter,double range, bool isXMatrix)
188  {
190  fr->SetFileName(path);
191  fr->SetFieldDelimiterCharacter(delimiter);
192  fr->HasColumnHeadersOff();
193  fr->HasRowHeadersOff();
194  fr->Parse();
195  try{
196  fr->Update();
197  }catch(itk::ExceptionObject& ex){
198  cout << "Exception caught!" << std::endl;
199  cout << ex << std::endl;
200  }
201 
202  typename itk::CSVArray2DDataObject<T>::Pointer p = fr->GetOutput();
203  unsigned int maxrowrange = p->GetMatrix().rows();
204  unsigned int c = p->GetMatrix().cols();
205  unsigned int percentRange = (unsigned int)(maxrowrange*range);
206 
207  if(isXMatrix == true){
208  Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> trainMatrixX(percentRange,c);
209  Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> testMatrixXPredict(maxrowrange-percentRange,c);
210 
211  for(unsigned int row = 0; row < percentRange; row++){
212  for(unsigned int col = 0; col < c; col++){
213  trainMatrixX(row,col) = p->GetData(row,col);
214  }
215  }
216 
217  for(unsigned int row = percentRange; row < maxrowrange; row++){
218  for(unsigned int col = 0; col < c; col++){
219  testMatrixXPredict(row-percentRange,col) = p->GetData(row,col);
220  }
221  }
222 
223  return std::make_pair(trainMatrixX,testMatrixXPredict);
224  }
225  else{
226  Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> trainLabelMatrixY(percentRange,c);
227  Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> testMatrixYPredict(maxrowrange-percentRange,c);
228 
229  for(unsigned int row = 0; row < percentRange; row++){
230  for(unsigned int col = 0; col < c; col++){
231  trainLabelMatrixY(row,col) = p->GetData(row,col);
232  }
233  }
234 
235  for(unsigned int row = percentRange; row < maxrowrange; row++){
236  for(unsigned int col = 0; col < c; col++){
237  testMatrixYPredict(row-percentRange,col) = p->GetData(row,col);
238  }
239  }
240  return std::make_pair(trainLabelMatrixY,testMatrixYPredict);
241  }
242 
243  }
244 
245  /*
246  Reading an csv-data and transfer the included datas into an matrix.
247  */
248  template<typename T>
249  Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> readCsvData(const std::string &path, char delimiter)
250  {
252  fr->SetFileName(path);
253  fr->SetFieldDelimiterCharacter(delimiter);
254  fr->HasColumnHeadersOff();
255  fr->HasRowHeadersOff();
256  fr->Parse();
257  try{
258  fr->Update();
259  }catch(itk::ExceptionObject& ex){
260  cout << "Exception caught!" << std::endl;
261  cout << ex << std::endl;
262  }
263 
264  typename itk::CSVArray2DDataObject<T>::Pointer p = fr->GetOutput();
265  unsigned int maxrowrange = p->GetMatrix().rows();
266  unsigned int maxcols = p->GetMatrix().cols();
267  Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> matrix(maxrowrange,maxcols);
268 
269  for(unsigned int rows = 0; rows < maxrowrange; rows++){
270  for(unsigned int cols = 0; cols < maxcols; cols++ ){
271  matrix(rows,cols) = p->GetData(rows,cols);
272  }
273  }
274 
275  return matrix;
276  }
277 
278  /*
279  Write the content of the array into an own csv-data in the following sequence:
280  root.csv: 1 2 3 0 0 4
281  writen.csv: 1 1:2 2:3 3:0 4:0 5:4
282  */
283  template<typename T>
284  void writeMatrixToCsv(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> paramMatrix,const std::string &path)
285  {
286  std::ofstream outputstream (path,std::ofstream::out); // 682
287 
288  if(outputstream.is_open()){
289  for(int i = 0; i < paramMatrix.rows(); i++){
290  outputstream << paramMatrix(i,0);
291  for(int j = 1; j < 11; j++){
292  outputstream << " " << j << ":" << paramMatrix(i,j);
293  }
294  outputstream << endl;
295  }
296  outputstream.close();
297  }
298  else{
299  cout << "Unable to write into CSV" << endl;
300  }
301  }
302 
303  // Method for intervalltesting
304  template<typename T>
305  bool isIntervall(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> expected, Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> actual, double lowrange, double toprange)
306  {
307  bool isInIntervall = false;
308  int count = 0;
309  unsigned int rowRange = expected.rows();
310  unsigned int colRange = expected.cols();
311  for(unsigned int i = 0; i < rowRange; i++){
312  for(unsigned int j = 0; j < colRange; j++){
313  if(expected(i,j) == actual(i,j)){
314  count++;
315  }
316  }
317 
318  double valueOfMatch = 100*count/(double)(rowRange);
319  if((lowrange <= valueOfMatch) && (toprange >= valueOfMatch)){
320  isInIntervall = true;
321  }
322  }
323  return isInIntervall;
324  }
325 
326 
327 };
328 
329 MITK_TEST_SUITE_REGISTRATION(mitkVigraRandomForest)
itk::SmartPointer< Self > Pointer
MITK_TEST_SUITE_REGISTRATION(mitkImageToItk)
#define MITK_TEST(TESTMETHOD)
Adds a test to the current test suite.
static std::string GetTestDataFilePath(const std::string &testData)
Get the absolute path for test data.
#define MITK_TEST_CONDITION(COND, MSG)
Test fixture for parameterized tests.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.