Skip to content
Snippets Groups Projects
Commit b07eca54 authored by Charles Peyrega's avatar Charles Peyrega
Browse files

ENH: Modification of the template of the ConfusionMatrixToMassOfBelief class...

ENH: Modification of the template of the ConfusionMatrixToMassOfBelief class and its corresponding tests
parent 88488484
Branches
Tags
No related merge requests found
......@@ -23,8 +23,9 @@
// gets integrated into the main directories.
#include "itkConfigure.h"
#include "itkListSample.h"
#include "otbConfusionMatrixCalculator.h"
#include "itkProcessObject.h"
#include "itkVariableSizeMatrix.h"
#include "otbConfusionMatrixMeasurements.h"
namespace otb
......@@ -35,50 +36,94 @@ namespace otb
* This class converts a confusion matrix into a std::map<ClassLabelType, MassType> with MassType being
* the type of the Mass of Belief of each label to be used in the Dempster-Shafer theory.
*
* TConfusionMatrixCalculator is the type of the confusion matrix calculator
* which generates the confusion matrix from reference and classified samples.
* TConfusionMatrix is the type of the confusion matrix from which the measurements will be computed.
* N.B.: The confusion matrix indices are expected to be organized the following way:
* confusionMatrix[itReference][itClassified], with itClassified the indice
* over the columns representing the classified labels compared to the reference
* labels (i.e. the reference truth) organized over the lines of the confusion matrix.
*
* The MassOfBeliefDefinitionMethod indicates which parameter of the confusion matrix will
* stand for the mass of belief of each label.
* stand for the mass of belief of each label (PRECISION, RECALL, ACCURACY, KAPPA).
*
*/
template < class TConfusionMatrixCalculator >
class ITK_EXPORT ConfusionMatrixToMassOfBelief : public itk::DataObject
template <class TConfusionMatrix = itk::VariableSizeMatrix<double> >
class ITK_EXPORT ConfusionMatrixToMassOfBelief :
public itk::ProcessObject
{
public:
/** Standard class typedefs */
typedef ConfusionMatrixToMassOfBelief Self;
typedef itk::DataObject Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef ConfusionMatrixToMassOfBelief Self;
typedef itk::ProcessObject Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods). */
itkTypeMacro(ConfusionMatrixToMassOfBelief, itk::ProcessObject);
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(ConfusionMatrixToMassOfBelief, DataObject);
typedef TConfusionMatrixCalculator ConfusionMatrixCalculatorType;
typedef typename TConfusionMatrixCalculator::Pointer ConfusionMatrixCalculatorPointerType;
typedef typename TConfusionMatrixCalculator::ClassLabelType ClassLabelType;
typedef std::map<int, ClassLabelType> MapOfIndicesType;
typedef double MassType;
typedef std::map<ClassLabelType, MassType> SingleClassLabelMassMapType;
/** Type for the confusion matrix */
typedef TConfusionMatrix ConfusionMatrixType;
enum MassOfBeliefDefinitionMethod {PRECISION, RECALL};
/** Type for the confusion matrix measurements calculator*/
typedef otb::ConfusionMatrixMeasurements<ConfusionMatrixType> ConfusionMatrixMeasurementsType;
typedef typename ConfusionMatrixMeasurementsType::ClassLabelType ClassLabelType;
typedef typename ConfusionMatrixMeasurementsType::MapOfClassesType MapOfClassesType;
typedef typename ConfusionMatrixMeasurementsType::MapOfIndicesType MapOfIndicesType;
typedef double MassType;
typedef std::map<ClassLabelType, MassType> SingleClassLabelMassMapType;
enum MassOfBeliefDefinitionMethod {PRECISION, RECALL, ACCURACY, KAPPA};
virtual void Update();
/** Accessors */
itkSetMacro(ConfusionMatrixCalculator, ConfusionMatrixCalculatorPointerType);
itkSetMacro(ConfusionMatrix, ConfusionMatrixType);
itkSetMacro(DefinitionMethod, MassOfBeliefDefinitionMethod);
/* Gives the correspondence between a class label
* and its index in the confusion matrix
*/
virtual void SetMapOfClasses(const MapOfClassesType _arg)
{
m_MapOfClasses = _arg;
typename MapOfClassesType::iterator itMapOfClasses;
m_MapOfIndices.clear();
for (itMapOfClasses = m_MapOfClasses.begin(); itMapOfClasses != m_MapOfClasses.end(); ++itMapOfClasses)
{
m_MapOfIndices[itMapOfClasses->second] = itMapOfClasses->first;
}
}
MapOfClassesType GetMapOfClasses() const
{
return m_MapOfClasses;
}
/* Gives the correspondence between an index in the
* confusion matrix and the class label
*/
virtual void SetMapOfIndices(const MapOfIndicesType _arg)
{
m_MapOfIndices = _arg;
typename MapOfIndicesType::iterator itMapOfIndices;
m_MapOfClasses.clear();
for (itMapOfIndices = m_MapOfIndices.begin(); itMapOfIndices != m_MapOfIndices.end(); ++itMapOfIndices)
{
m_MapOfClasses[itMapOfIndices->second] = itMapOfIndices->first;
}
}
MapOfIndicesType GetMapOfIndices() const
{
return m_MapOfIndices;
}
SingleClassLabelMassMapType GetMapMassOfBelief() const
{
return m_MapMassOfBelief;
......@@ -99,7 +144,12 @@ private:
ConfusionMatrixToMassOfBelief(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
ConfusionMatrixCalculatorPointerType m_ConfusionMatrixCalculator;
ConfusionMatrixType m_ConfusionMatrix;
typename ConfusionMatrixMeasurementsType::Pointer m_ConfMatMeasurements;
MapOfClassesType m_MapOfClasses;
MapOfIndicesType m_MapOfIndices;
MassOfBeliefDefinitionMethod m_DefinitionMethod;
SingleClassLabelMassMapType m_MapMassOfBelief;
};
......
......@@ -27,8 +27,10 @@ template<class TConfusionMatrix>
ConfusionMatrixToMassOfBelief<TConfusionMatrix>
::ConfusionMatrixToMassOfBelief()
{
m_ConfusionMatrixCalculator = ConfusionMatrixCalculatorType::New();
m_DefinitionMethod = this->PRECISION;
this->SetNumberOfRequiredInputs(2);
this->SetNumberOfRequiredOutputs(1);
this->m_ConfMatMeasurements = ConfusionMatrixMeasurementsType::New();
this->m_DefinitionMethod = this->PRECISION;
}
template <class TConfusionMatrix>
......@@ -44,27 +46,41 @@ void
ConfusionMatrixToMassOfBelief<TConfusionMatrix>
::GenerateData()
{
MapOfIndicesType mapOfIndices = m_ConfusionMatrixCalculator->GetMapOfIndices();
this->m_ConfMatMeasurements->SetConfusionMatrix(m_ConfusionMatrix);
this->m_ConfMatMeasurements->Update();
typename MapOfIndicesType::iterator itMapOfIndices;
MassType currentMass = 0;
for (itMapOfIndices = mapOfIndices.begin(); itMapOfIndices != mapOfIndices.end(); ++itMapOfIndices)
MassType currentMass = 0.;
this->m_MapMassOfBelief.clear();
for (itMapOfIndices = m_MapOfIndices.begin(); itMapOfIndices != m_MapOfIndices.end(); ++itMapOfIndices)
{
// Masses of Belief = Precision Rate of each label (TP/[TP + FP])
if (m_DefinitionMethod == this->PRECISION)
{
currentMass = m_ConfusionMatrixCalculator->GetPrecisions()[itMapOfIndices->first];
}
else
switch (m_DefinitionMethod)
{
// Masses of Belief = Recall Rate of each label (TP/[TP + FN])
if (m_DefinitionMethod == this->RECALL)
{
currentMass = m_ConfusionMatrixCalculator->GetRecalls()[itMapOfIndices->first];
}
}
m_MapMassOfBelief[itMapOfIndices->second] = currentMass;
case PRECISION:
// Masses of Belief = Precision Rate of each label (TP / [TP + FP])
currentMass = m_ConfMatMeasurements->GetPrecisions()[itMapOfIndices->first];
break;
case RECALL:
// Masses of Belief = Recall Rate of each label (TP / [TP + FN])
currentMass = m_ConfMatMeasurements->GetRecalls()[itMapOfIndices->first];
break;
case ACCURACY:
// Masses of Belief = Overall Accuracy of the confusion matrix (SUM[TP] / nbSamples)
currentMass = m_ConfMatMeasurements->GetOverallAccuracy();
break;
case KAPPA:
// Masses of Belief = Kappa Index of the confusion matrix
currentMass = m_ConfMatMeasurements->GetKappaIndex();
break;
default:
// Masses of Belief = Precision Rate of each label (TP / [TP + FP]
currentMass = m_ConfMatMeasurements->GetPrecisions()[itMapOfIndices->first];
break;
}// END switch (m_DefinitionMethod)
this->m_MapMassOfBelief[itMapOfIndices->second] = currentMass;
}
}
} // end namespace otb
......
......@@ -155,6 +155,14 @@ ADD_TEST(fzTvConfusionMatrixToMassOfBeliefTestPrecision ${Fuzzy_TESTS3}
ADD_TEST(fzTvConfusionMatrixToMassOfBeliefTestRecall ${Fuzzy_TESTS3}
otbConfusionMatrixToMassOfBeliefTest
RECALL)
ADD_TEST(fzTvConfusionMatrixToMassOfBeliefTestAccuracy ${Fuzzy_TESTS3}
otbConfusionMatrixToMassOfBeliefTest
ACCURACY)
ADD_TEST(fzTvConfusionMatrixToMassOfBeliefTestKappa ${Fuzzy_TESTS3}
otbConfusionMatrixToMassOfBeliefTest
KAPPA)
......@@ -182,7 +190,6 @@ otbStandardDSCostFunction.cxx
SET(BasicFuzzy_SRCS3
otbFuzzyTests3.cxx
otbDempsterShaferFusionTests.cxx
otbConfusionMatrixToMassOfBeliefNew.cxx
otbConfusionMatrixToMassOfBeliefTest.cxx
)
......
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "itkMacro.h"
#include <iostream>
#include "otbConfusionMatrixToMassOfBelief.h"
int otbConfusionMatrixToMassOfBeliefNew(int argc, char* argv[])
{
typedef unsigned int LabelType;
typedef itk::VariableLengthVector<LabelType> RefLabelType;
typedef itk::Statistics::ListSample<RefLabelType> RefListLabelType;
typedef itk::VariableLengthVector<LabelType> ProdLabelType;
typedef itk::Statistics::ListSample<ProdLabelType> ProdListLabelType;
typedef otb::ConfusionMatrixCalculator<RefListLabelType, ProdListLabelType> ConfusionMatrixCalculatorType;
// filter type
typedef otb::ConfusionMatrixToMassOfBelief<ConfusionMatrixCalculatorType> ConfusionMatrixToMassOfBeliefType;
// filter
ConfusionMatrixToMassOfBeliefType::Pointer ConfMatToMOB = ConfusionMatrixToMassOfBeliefType::New();
std::cout<<ConfMatToMOB<<std::endl;
return EXIT_SUCCESS;
}
......@@ -20,73 +20,48 @@
#include "otbConfusionMatrixToMassOfBelief.h"
int otbConfusionMatrixToMassOfBeliefTest(int argc, char* argv[])
int otbConfusionMatrixToMassOfBeliefNew(int argc, char* argv[])
{
// Filling the Confusion Matrix
typedef unsigned int LabelType;
typedef itk::FixedArray<LabelType, 1> RLabelType;
typedef itk::Statistics::ListSample<RLabelType> RListLabelType;
typedef itk::FixedArray<LabelType, 1> PLabelType;
typedef itk::Statistics::ListSample<PLabelType> PListLabelType;
typedef otb::ConfusionMatrixCalculator<RListLabelType, PListLabelType> ConfusionMatrixCalculatorType;
//Filling the Confusion Matrix from samples
ConfusionMatrixCalculatorType::Pointer confusionMatrixCalculator = ConfusionMatrixCalculatorType::New();
RListLabelType::Pointer refLabels = RListLabelType::New();
PListLabelType::Pointer prodLabels = PListLabelType::New();
RListLabelType::Iterator itRefLabels;
PListLabelType::Iterator itProdLabels;
int nbSamples = 12;
int nbClasses = 4;
// Reference samples: 1 2 3 4 1 2 3 4 1 2 3 4
// Classified reference samples: 1 3 3 4 4 2 3 4 4 4 4 3
std::vector<LabelType> labelsClassified;
labelsClassified.push_back(1);
labelsClassified.push_back(3);
labelsClassified.push_back(3);
labelsClassified.push_back(4);
labelsClassified.push_back(4);
labelsClassified.push_back(2);
labelsClassified.push_back(3);
labelsClassified.push_back(4);
labelsClassified.push_back(4);
labelsClassified.push_back(4);
labelsClassified.push_back(4);
labelsClassified.push_back(3);
for (int i = 0; i < nbSamples; ++i)
{
int label = (i % nbClasses) + 1;
refLabels->PushBack(label);
prodLabels->PushBack(labelsClassified[i]);
}
typedef itk::VariableSizeMatrix<double> ConfusionMatrixType;
int k = 0;
for (itRefLabels = refLabels->Begin(), itProdLabels = prodLabels->Begin(); itRefLabels != refLabels->End(); ++itRefLabels, ++itProdLabels)
{
std::cout << "refLabels[" << k << "] = " << itRefLabels.GetMeasurementVector()[0] << "; prodLabels[" << k << "] = "
<< itProdLabels.GetMeasurementVector()[0] << std::endl;
++k;
}
// filter type
typedef otb::ConfusionMatrixToMassOfBelief<ConfusionMatrixType> ConfusionMatrixToMassOfBeliefType;
confusionMatrixCalculator->SetReferenceLabels(refLabels);
confusionMatrixCalculator->SetProducedLabels(prodLabels);
confusionMatrixCalculator->Update();
// filter
ConfusionMatrixToMassOfBeliefType::Pointer confMatToMOB = ConfusionMatrixToMassOfBeliefType::New();
std::cout << confMatToMOB << std::endl;
ConfusionMatrixCalculatorType::ConfusionMatrixType confusionMatrix = confusionMatrixCalculator->GetConfusionMatrix();
std::cout << std::endl;
std::cout << "confusion matrix" << std::endl << confusionMatrix << std::endl;
return EXIT_SUCCESS;
}
// Converting the Confusion Matrix into a std::map<ClassLabelType, MassType> of Masses of Belief for each label
typedef otb::ConfusionMatrixToMassOfBelief<ConfusionMatrixCalculatorType> ConfusionMatrixToMassOfBeliefType;
int otbConfusionMatrixToMassOfBeliefTest(int argc, char* argv[])
{
typedef itk::VariableSizeMatrix<double> ConfusionMatrixType;
// filter type
typedef otb::ConfusionMatrixToMassOfBelief<ConfusionMatrixType> ConfusionMatrixToMassOfBeliefType;
typedef ConfusionMatrixToMassOfBeliefType::MapOfClassesType MapOfClassesType;
typedef ConfusionMatrixToMassOfBeliefType::MassOfBeliefDefinitionMethod MassOfBeliefDefinitionMethod;
typedef ConfusionMatrixToMassOfBeliefType::SingleClassLabelMassMapType SingleClassLabelMassMapType;
// mapOfClasses[label] = index in the rows/columns of the confusion matrix
MapOfClassesType mapOfClasses;
mapOfClasses[1] = 0;
mapOfClasses[2] = 1;
mapOfClasses[3] = 2;
mapOfClasses[4] = 3;
unsigned int nbClasses = mapOfClasses.size();
ConfusionMatrixType confMat = ConfusionMatrixType(nbClasses, nbClasses);
confMat(0, 0) = 1, confMat(0, 1) = 0, confMat(0, 2) = 0, confMat(0, 3) = 2;
confMat(1, 0) = 0, confMat(1, 1) = 1, confMat(1, 2) = 1, confMat(1, 3) = 1;
confMat(2, 0) = 0, confMat(2, 1) = 0, confMat(2, 2) = 2, confMat(2, 3) = 1;
confMat(3, 0) = 0, confMat(3, 1) = 0, confMat(3, 2) = 1, confMat(3, 3) = 2;
std::cout << "confusion matrix = " << std::endl << confMat << std::endl;
// Converting the Confusion Matrix into a std::map<ClassLabelType, MassType> of Masses of Belief for each label
ConfusionMatrixToMassOfBeliefType::Pointer confMatToMass = ConfusionMatrixToMassOfBeliefType::New();
MassOfBeliefDefinitionMethod massOfBeliefDefMethod;
......@@ -101,9 +76,24 @@ int otbConfusionMatrixToMassOfBeliefTest(int argc, char* argv[])
{
massOfBeliefDefMethod = ConfusionMatrixToMassOfBeliefType::RECALL;
}
else
{
if (massOfBeliefDefMethodStr.compare("ACCURACY") == 0)
{
massOfBeliefDefMethod = ConfusionMatrixToMassOfBeliefType::ACCURACY;
}
else
{
if (massOfBeliefDefMethodStr.compare("KAPPA") == 0)
{
massOfBeliefDefMethod = ConfusionMatrixToMassOfBeliefType::KAPPA;
}
}
}
}
confMatToMass->SetConfusionMatrixCalculator(confusionMatrixCalculator);
confMatToMass->SetConfusionMatrix(confMat);
confMatToMass->SetMapOfClasses(mapOfClasses);
confMatToMass->SetDefinitionMethod(massOfBeliefDefMethod);
confMatToMass->Update();
SingleClassLabelMassMapType mapMOB = confMatToMass->GetMapMassOfBelief();
......@@ -119,7 +109,7 @@ int otbConfusionMatrixToMassOfBeliefTest(int argc, char* argv[])
// Baselines for the different measurements
//******************************************
SingleClassLabelMassMapType mapMOBBLPrecision, mapMOBBLRecall;
SingleClassLabelMassMapType mapMOBBLPrecision, mapMOBBLRecall, mapMOBBLAccuracy, mapMOBBLKappa;
SingleClassLabelMassMapType::iterator itMapMOBBL;
mapMOBBLPrecision[1] = 1;
......@@ -132,6 +122,16 @@ int otbConfusionMatrixToMassOfBeliefTest(int argc, char* argv[])
mapMOBBLRecall[3] = 2.0 / 3.0;
mapMOBBLRecall[4] = 2.0 / 3.0;
mapMOBBLAccuracy[1] = 1.0 / 2.0;
mapMOBBLAccuracy[2] = 1.0 / 2.0;
mapMOBBLAccuracy[3] = 1.0 / 2.0;
mapMOBBLAccuracy[4] = 1.0 / 2.0;
mapMOBBLKappa[1] = 1.0 / 3.0;
mapMOBBLKappa[2] = 1.0 / 3.0;
mapMOBBLKappa[3] = 1.0 / 3.0;
mapMOBBLKappa[4] = 1.0 / 3.0;
if ((mapMOB != mapMOBBLPrecision) && (massOfBeliefDefMethodStr.compare("PRECISION") == 0))
{
std::cout << std::endl;
......@@ -158,5 +158,31 @@ int otbConfusionMatrixToMassOfBeliefTest(int argc, char* argv[])
return EXIT_FAILURE;
}
if ((mapMOB != mapMOBBLAccuracy) && (massOfBeliefDefMethodStr.compare("ACCURACY") == 0))
{
std::cout << std::endl;
std::cout << "ERROR in Map Mass of Belief Accuracy" << std::endl;
for (itMapMOBBL = mapMOBBLAccuracy.begin(), itMapMOB = mapMOB.begin();
itMapMOBBL != mapMOBBLAccuracy.end(); ++itMapMOBBL, ++itMapMOB)
{
std::cout << "mapMOBBLAccuracy[" << itMapMOBBL->first << "] = " << itMapMOBBL->second << "; ";
std::cout << "mapMOB[" << itMapMOB->first << "] = " << itMapMOB->second << std::endl;
}
return EXIT_FAILURE;
}
if ((mapMOB != mapMOBBLKappa) && (massOfBeliefDefMethodStr.compare("KAPPA") == 0))
{
std::cout << std::endl;
std::cout << "ERROR in Map Mass of Belief Kappa" << std::endl;
for (itMapMOBBL = mapMOBBLKappa.begin(), itMapMOB = mapMOB.begin();
itMapMOBBL != mapMOBBLKappa.end(); ++itMapMOBBL, ++itMapMOB)
{
std::cout << "mapMOBBLKappa[" << itMapMOBBL->first << "] = " << itMapMOBBL->second << "; ";
std::cout << "mapMOB[" << itMapMOB->first << "] = " << itMapMOB->second << std::endl;
}
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
......@@ -28,8 +28,8 @@ int otbConfusionMatrixMeasurementsNew(int argc, char* argv[])
typedef otb::ConfusionMatrixMeasurements<ConfusionMatrixType> ConfusionMatrixMeasurementsType;
// filter
ConfusionMatrixMeasurementsType::Pointer ConfMatMeasurements = ConfusionMatrixMeasurementsType::New();
std::cout << ConfMatMeasurements << std::endl;
ConfusionMatrixMeasurementsType::Pointer confMatMeasurements = ConfusionMatrixMeasurementsType::New();
std::cout << confMatMeasurements << std::endl;
return EXIT_SUCCESS;
}
......@@ -54,18 +54,18 @@ int otbConfusionMatrixMeasurementsTest(int argc, char* argv[])
mapOfClasses[4] = 3;
unsigned int nbClasses = mapOfClasses.size();
ConfusionMatrixType ConfMat = ConfusionMatrixType(nbClasses, nbClasses);
ConfMat(0, 0) = 1, ConfMat(0, 1) = 0, ConfMat(0, 2) = 0, ConfMat(0, 3) = 2;
ConfMat(1, 0) = 0, ConfMat(1, 1) = 1, ConfMat(1, 2) = 1, ConfMat(1, 3) = 1;
ConfMat(2, 0) = 0, ConfMat(2, 1) = 0, ConfMat(2, 2) = 2, ConfMat(2, 3) = 1;
ConfMat(3, 0) = 0, ConfMat(3, 1) = 0, ConfMat(3, 2) = 1, ConfMat(3, 3) = 2;
std::cout << "confusion matrix = " << std::endl << ConfMat << std::endl;
ConfusionMatrixType confMat = ConfusionMatrixType(nbClasses, nbClasses);
confMat(0, 0) = 1, confMat(0, 1) = 0, confMat(0, 2) = 0, confMat(0, 3) = 2;
confMat(1, 0) = 0, confMat(1, 1) = 1, confMat(1, 2) = 1, confMat(1, 3) = 1;
confMat(2, 0) = 0, confMat(2, 1) = 0, confMat(2, 2) = 2, confMat(2, 3) = 1;
confMat(3, 0) = 0, confMat(3, 1) = 0, confMat(3, 2) = 1, confMat(3, 3) = 2;
std::cout << "confusion matrix = " << std::endl << confMat << std::endl;
// filter
ConfusionMatrixMeasurementsType::Pointer confMatMeasurements = ConfusionMatrixMeasurementsType::New();
confMatMeasurements->SetMapOfClasses(mapOfClasses);
confMatMeasurements->SetConfusionMatrix(ConfMat);
confMatMeasurements->SetConfusionMatrix(confMat);
confMatMeasurements->Update();
// mapOfIndices[index] = label associated to the rows/columns of the confusion matrix
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment