diff --git a/Modules/Classification/CLLibSVM/test/mitkLibSVMClassifierTest.cpp b/Modules/Classification/CLLibSVM/test/mitkLibSVMClassifierTest.cpp index f706bf9cda..424174dadf 100644 --- a/Modules/Classification/CLLibSVM/test/mitkLibSVMClassifierTest.cpp +++ b/Modules/Classification/CLLibSVM/test/mitkLibSVMClassifierTest.cpp @@ -1,322 +1,314 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include "mitkIOUtil.h" #include "itkArray2D.h" #include #include #include #include #include #include #include //#include class mitkLibSVMClassifierTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkLibSVMClassifierTestSuite); MITK_TEST(TrainSVMClassifier_MatlabDataSet_shouldReturnTrue); MITK_TEST(TrainSVMClassifier_BreastCancerDataSet_shouldReturnTrue); CPPUNIT_TEST_SUITE_END(); private: typedef Eigen::Matrix MatrixDoubleType; typedef Eigen::Matrix MatrixIntType; Eigen::MatrixXd m_TrainingMatrixX; Eigen::MatrixXi m_TrainingLabelMatrixY; Eigen::MatrixXd m_TestXPredict; Eigen::MatrixXi m_TestYPredict; mitk::LibSVMClassifier::Pointer classifier; public: /*Reading an file, which includes the trainingdataset and the testdataset, and convert the content of the file into an 2dim matrixpair. There are an delimiter, which separates the matrix into an trainingmatrix and testmatrix */ template std::pair,Eigen::Matrix >convertCSVToMatrix(const std::string &path, char delimiter,double range, bool isXMatrix) { typename itk::CSVArray2DFileReader::Pointer fr = itk::CSVArray2DFileReader::New(); fr->SetFileName(path); fr->SetFieldDelimiterCharacter(delimiter); fr->HasColumnHeadersOff(); fr->HasRowHeadersOff(); fr->Parse(); try{ fr->Update(); }catch(itk::ExceptionObject& ex){ cout << "Exception caught!" << std::endl; cout << ex << std::endl; } typename itk::CSVArray2DDataObject::Pointer p = fr->GetOutput(); unsigned int maxrowrange = p->GetMatrix().rows(); unsigned int c = p->GetMatrix().cols(); unsigned int percentRange = (unsigned int)(maxrowrange*range); if(isXMatrix == true) { Eigen::Matrix trainMatrixX(percentRange,c); Eigen::Matrix testMatrixXPredict(maxrowrange-percentRange,c); for(unsigned int row = 0; row < percentRange; row++){ for(unsigned int col = 0; col < c; col++){ trainMatrixX(row,col) = p->GetData(row,col); } } for(unsigned int row = percentRange; row < maxrowrange; row++){ for(unsigned int col = 0; col < c; col++){ testMatrixXPredict(row-percentRange,col) = p->GetData(row,col); } } return std::make_pair(trainMatrixX,testMatrixXPredict); } else { Eigen::Matrix trainLabelMatrixY(percentRange,c); Eigen::Matrix testMatrixYPredict(maxrowrange-percentRange,c); for(unsigned int row = 0; row < percentRange; row++){ for(unsigned int col = 0; col < c; col++){ trainLabelMatrixY(row,col) = p->GetData(row,col); } } for(unsigned int row = percentRange; row < maxrowrange; row++){ for(unsigned int col = 0; col < c; col++){ testMatrixYPredict(row-percentRange,col) = p->GetData(row,col); } } return std::make_pair(trainLabelMatrixY,testMatrixYPredict); } } /* Reading an csv-data and transfer the included datas into an matrix. */ template Eigen::Matrix readCsvData(const std::string &path, char delimiter) { typename itk::CSVArray2DFileReader::Pointer fr = itk::CSVArray2DFileReader::New(); fr->SetFileName(path); fr->SetFieldDelimiterCharacter(delimiter); fr->HasColumnHeadersOff(); fr->HasRowHeadersOff(); fr->Parse(); try{ fr->Update(); }catch(itk::ExceptionObject& ex){ cout << "Exception caught!" << std::endl; cout << ex << std::endl; } typename itk::CSVArray2DDataObject::Pointer p = fr->GetOutput(); unsigned int maxrowrange = p->GetMatrix().rows(); unsigned int maxcols = p->GetMatrix().cols(); Eigen::Matrix matrix(maxrowrange,maxcols); for(int rows = 0; rows < maxrowrange; rows++){ for(int cols = 0; cols < maxcols; cols++ ){ matrix(rows,cols) = p->GetData(rows,cols); } } return matrix; } /* Write the content of the array into an own csv-data in the following sequence: root.csv: 1 2 3 0 0 4 writen.csv: 1 1:2 2:3 3:0 4:0 5:4 */ template void writeMatrixToCsv(Eigen::Matrix paramMatrix,const std::string &path) { std::ofstream outputstream (path,std::ofstream::out); // 682 if(outputstream.is_open()){ for(int i = 0; i < paramMatrix.rows(); i++){ outputstream << paramMatrix(i,0); for(int j = 1; j < 11; j++){ outputstream << " " << j << ":" << paramMatrix(i,j); } outputstream << endl; } outputstream.close(); } else{ cout << "Unable to write into CSV" << endl; } } /* Train the classifier with an exampledataset of mattlab. Note: The included data are gaußan normaldistributed. */ void TrainSVMClassifier_MatlabDataSet_shouldReturnTrue() { /* Declarating an featurematrixdataset, the first matrix of the matrixpair is the trainingmatrix and the second one is the testmatrix.*/ std::pair matrixDouble; matrixDouble = convertCSVToMatrix(GetTestDataFilePath("Classification/FeaturematrixMatlab.csv"),';',0.5,true); m_TrainingMatrixX = matrixDouble.first; m_TestXPredict = matrixDouble.second; /* The declaration of the labelmatrixdataset is equivalent to the declaration of the featurematrixdataset.*/ std::pair matrixInt; matrixInt = convertCSVToMatrix(GetTestDataFilePath("Classification/LabelmatrixMatlab.csv"),';',0.5,false); m_TrainingLabelMatrixY = matrixInt.first; m_TestYPredict = matrixInt.second; classifier = mitk::LibSVMClassifier::New(); /* Setting of the SVM-Parameters*/ classifier->SetGamma(1/(double)(m_TrainingMatrixX.cols())); classifier->SetSvmType(0); classifier->SetKernelType(0); /* Train the classifier, by giving trainingdataset for the labels and features. The result in an colunmvector of the labels.*/ classifier->Train(m_TrainingMatrixX,m_TrainingLabelMatrixY); Eigen::MatrixXi classes = classifier->Predict(m_TestXPredict); /* Testing the matching between the calculated colunmvector and the result of the SVM */ unsigned int maxrows = classes.rows(); - bool isYPredictVector = false; int count = 0; for (unsigned int i = 0; i < maxrows; i++) { if(classes(i, 0) == m_TestYPredict(i, 0)) - { - isYPredictVector = true; ++count; - } } MITK_INFO << 100*count/(double)(maxrows) << "%"; MITK_TEST_CONDITION(isEqual(m_TestYPredict,classes),"Expected vector and occured vector match."); } // Method of testing for assertions. template bool isEqual(Eigen::Matrix expected, Eigen::Matrix actual) { bool isSimilar = true; unsigned int mrow = expected.rows(); unsigned int mcol = expected.cols(); for(unsigned int i = 0; i < mrow; i++){ for(unsigned int j = 0; j < mcol; j++){ if(expected(i,j) != actual(i,j)){ isSimilar = false; } } } return isSimilar; } // Method of intervalltesting template bool isIntervall(Eigen::Matrix expected, Eigen::Matrix actual, double lowrange, double toprange) { bool isInIntervall = false; int count = 0; unsigned int rowRange = expected.rows(); unsigned int colRange = expected.cols(); for(unsigned int i = 0; i < rowRange; i++){ for(unsigned int j = 0; j < colRange; j++){ if(expected(i,j) == actual(i,j)){ count++; } } double valueOfMatch = 100*count/(double)(rowRange); if((lowrange <= valueOfMatch) && (toprange >= valueOfMatch)){ isInIntervall = true; } } return isInIntervall; } /* Train the classifier with the dataset of breastcancer patients from the LibSVM Libary */ void TrainSVMClassifier_BreastCancerDataSet_shouldReturnTrue() { /* Declarating an featurematrixdataset, the first matrix of the matrixpair is the trainingmatrix and the second one is the testmatrix.*/ std::pair matrixDouble; matrixDouble = convertCSVToMatrix(GetTestDataFilePath("Classification/FeaturematrixBreastcancer.csv"),';',0.5,true); m_TrainingMatrixX = matrixDouble.first; m_TestXPredict = matrixDouble.second; /* The declaration of the labelmatrixdataset is equivalent to the declaration of the featurematrixdataset.*/ std::pair matrixInt; matrixInt = convertCSVToMatrix(GetTestDataFilePath("Classification/LabelmatrixBreastcancer.csv"),';',0.5,false); m_TrainingLabelMatrixY = matrixInt.first; m_TestYPredict = matrixInt.second; /* Setting of the SVM-Parameters*/ classifier = mitk::LibSVMClassifier::New(); classifier->SetGamma(1/(double)(m_TrainingMatrixX.cols())); classifier->SetSvmType(0); classifier->SetKernelType(2); /* Train the classifier, by giving trainingdataset for the labels and features. The result in an colunmvector of the labels.*/ classifier->Train(m_TrainingMatrixX,m_TrainingLabelMatrixY); Eigen::MatrixXi classes = classifier->Predict(m_TestXPredict); /* Testing the matching between the calculated colunmvector and the result of the SVM */ unsigned int maxrows = classes.rows(); - bool isYPredictVector = false; int count = 0; for (unsigned int i = 0; i < maxrows; i++) { if (classes(i, 0) == m_TestYPredict(i, 0)) - { - isYPredictVector = true; ++count; - } } MITK_INFO << 100*count/(double)(maxrows) << "%"; MITK_TEST_CONDITION(isIntervall(m_TestYPredict,classes,75,100),"Testvalue is in range."); } void TestThreadedDecisionForest() { } }; -MITK_TEST_SUITE_REGISTRATION(mitkLibSVMClassifier) \ No newline at end of file +MITK_TEST_SUITE_REGISTRATION(mitkLibSVMClassifier)