Commit 3e7f5be3 authored by Cédric Traizet's avatar Cédric Traizet

Merge branch 'app_vector_regression' into 'develop'

Application VectorRegression

See merge request !565
parents 0dde3bf4 0572dcd4
Pipeline #2461 passed with stages
in 10 minutes and 35 seconds
%YAML:1.0
my_tree: !!opencv-ml-tree
is_classifier: 0
var_all: 4
var_count: 4
ord_var_count: 4
cat_var_count: 0
training_params:
use_surrogates: 1
regression_accuracy: 9.9999997764825821e-03
max_depth: 25
min_sample_count: 10
cross_validation_folds: 0
var_type: [ 0, 0, 0, 0 ]
best_tree_idx: -1
nodes:
-
depth: 0
sample_count: 1185
value: 2.1434599156118144e+00
Tn: 0
complexity: 0
alpha: 0.
node_risk: 1.3156118143459917e+03
tree_risk: 0.
tree_error: 0.
splits:
- { var:3, quality:6.5841166992187500e+03,
le:2.3381726074218750e+02 }
-
depth: 1
sample_count: 593
value: 1.1635750421585160e+00
Tn: 0
complexity: 0
alpha: 0.
node_risk: 8.9133220910623891e+01
tree_risk: 0.
tree_error: 0.
splits:
- { var:3, quality:8.8817205810546875e+02,
le:1.6510346984863281e+02 }
-
depth: 2
sample_count: 500
value: 1.
Tn: 0
complexity: 0
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 2
sample_count: 93
value: 2.0430107526881720e+00
Tn: 0
complexity: 0
alpha: 0.
node_risk: 3.8279569892472978e+00
tree_risk: 0.
tree_error: 0.
splits:
- { var:0, quality:392., le:2.1638174438476562e+02 }
-
depth: 3
sample_count: 4
value: 3.
Tn: 0
complexity: 0
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 3
sample_count: 89
value: 2.
Tn: 0
complexity: 0
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 1
sample_count: 592
value: 3.1250000000000000e+00
Tn: 0
complexity: 0
alpha: 0.
node_risk: 8.6750000000000000e+01
tree_risk: 0.
tree_error: 0.
splits:
- { var:1, quality:5.8572387695312500e+03,
le:3.6126699829101562e+02 }
-
depth: 2
sample_count: 507
value: 2.9783037475345169e+00
Tn: 0
complexity: 0
alpha: 0.
node_risk: 1.0761341222879309e+01
tree_risk: 0.
tree_error: 0.
-
depth: 2
sample_count: 85
value: 4.
Tn: 0
complexity: 0
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
......@@ -115,6 +115,11 @@ otb_create_application(
SOURCES otbVectorClassifier.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
otb_create_application(
NAME VectorRegression
SOURCES otbVectorRegression.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
otb_create_application(
NAME SampleAugmentation
SOURCES otbSampleAugmentation.cxx
......
......@@ -37,11 +37,6 @@ namespace otb
{
namespace Wrapper
{
/** Utility function to negate std::isalnum */
bool IsNotAlphaNum(char c)
{
return !std::isalnum(c);
}
class ComputeConfusionMatrix : public Application
{
......@@ -198,7 +193,7 @@ private:
{
std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef();
key = item;
std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum);
std::string::iterator end = std::remove_if(key.begin(),key.end(), [](char c){return !std::isalnum(c);});
std::transform(key.begin(), end, key.begin(), tolower);
OGRFieldType fieldType = feature.ogr().GetFieldDefnRef(iField)->GetType();
......
......@@ -32,12 +32,6 @@ namespace otb
namespace Wrapper
{
/** Utility function to negate std::isalnum */
bool IsNotAlphaNum(char c)
{
return !std::isalnum(c);
}
class PolygonClassStatistics : public Application
{
public:
......@@ -141,7 +135,7 @@ private:
{
std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef();
key = item;
std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum);
std::string::iterator end = std::remove_if(key.begin(),key.end(), [](char c){return !std::isalnum(c);});
std::transform(key.begin(), end, key.begin(), tolower);
OGRFieldType fieldType = feature.ogr().GetFieldDefnRef(iField)->GetType();
......
......@@ -27,12 +27,6 @@ namespace otb
{
namespace Wrapper
{
/** Utility function to negate std::isalnum */
bool IsNotAlphaNum(char c)
{
return !std::isalnum(c);
}
class SampleExtraction : public Application
{
public:
......@@ -139,7 +133,7 @@ private:
{
std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef();
key = item;
std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum);
std::string::iterator end = std::remove_if(key.begin(),key.end(), [](char c){return !std::isalnum(c);});
std::transform(key.begin(), end, key.begin(), tolower);
OGRFieldType fieldType = feature.ogr().GetFieldDefnRef(iField)->GetType();
......
......@@ -32,13 +32,6 @@ namespace otb
{
namespace Wrapper
{
/** Utility function to negate std::isalnum */
bool IsNotAlphaNum(char c)
{
return !std::isalnum(c);
}
class SampleSelection : public Application
{
public:
......@@ -243,7 +236,7 @@ private:
{
std::string key, item = feature.ogr().GetFieldDefnRef(iField)->GetNameRef();
key = item;
std::string::iterator end = std::remove_if(key.begin(),key.end(),IsNotAlphaNum);
std::string::iterator end = std::remove_if(key.begin(), key.end(), [](char c){return !std::isalnum(c);});
std::transform(key.begin(), end, key.begin(), tolower);
OGRFieldType fieldType = feature.ogr().GetFieldDefnRef(iField)->GetType();
......
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "otbVectorPrediction.h"
namespace otb
{
namespace Wrapper
{
using VectorRegression = VectorPrediction<true>;
template <>
void VectorRegression::DoInitSpecialization()
{
SetName("VectorRegression");
SetDescription("Performs regression on the input vector data according to a model file.");
SetDocAuthors("OTB-Team");
SetDocLongDescription(
"This application performs a vector data regression "
"based on a model file produced by the TrainVectorRegression application."
"Features of the vector data output will contain the values predicted by the classifier. \n"
"There are two modes: \n"
"1) Update mode: add of the 'cfield' field containing the predicted value in the input file. \n"
"2) Write mode: copies the existing fields of the input file to the output file "
" and add the 'cfield' field containing the predicted value. \n"
"If you have declared the output file, the write mode applies. "
"Otherwise, the input file update mode will be applied.");
SetDocLimitations("Shapefiles are supported, but the SQLite format is only supported in update mode.");
SetDocSeeAlso("TrainVectorRegression");
AddDocTag(Tags::Learning);
AddParameter(ParameterType_InputFilename, "in", "Name of the input vector data");
SetParameterDescription("in", "The input vector data file to classify.");
AddParameter(ParameterType_InputFilename, "instat", "Statistics file");
SetParameterDescription("instat",
"A XML file containing mean and standard deviation to center"
"and reduce samples before classification, produced by ComputeImagesStatistics application.");
MandatoryOff("instat");
AddParameter(ParameterType_InputFilename, "model", "Model file");
SetParameterDescription("model", "Model file produced by TrainVectorRegression application.");
AddParameter(ParameterType_String, "cfield", "Output field");
SetParameterDescription("cfield",
"Field containing the predicted value."
"Only geometries with this field available will be taken into account.\n"
"The field is added either in the input file (if 'out' off) or in the output file.\n"
"Caution, the 'cfield' must not exist in the input file if you are updating the file.");
SetParameterString("cfield", "predicted");
AddParameter(ParameterType_ListView, "feat", "Field names to be calculated");
SetParameterDescription("feat",
"List of field names in the input vector data used as features for training. "
"Put the same field names as the TrainVectorRegression application.");
AddParameter(ParameterType_OutputFilename, "out", "Output vector data file");
MandatoryOff("out");
SetParameterDescription("out",
"Output vector data file storing sample values (OGR format)."
"If not given, the input vector data file is updated.");
MandatoryOff("out");
// Doc example parameter settings
SetDocExampleParameterValue("in", "vectorData.shp");
SetDocExampleParameterValue("instat", "meanVar.xml");
SetDocExampleParameterValue("model", "rfModel.rf");
SetDocExampleParameterValue("out", "vectorDataLabeledVector.shp");
SetDocExampleParameterValue("feat", "perimeter area width");
SetDocExampleParameterValue("cfield", "predicted");
SetOfficialDocLink();
}
// Confidence map computation is not supported for regression.
template <>
bool VectorRegression::shouldComputeConfidenceMap() const
{
return false;
}
}
}
OTB_APPLICATION_EXPORT(otb::Wrapper::VectorRegression)
......@@ -43,12 +43,6 @@ namespace otb
namespace Wrapper
{
/** Utility function to negate std::isalnum */
bool IsNotAlphaNum(char c)
{
return !std::isalnum( c );
}
template <class TInputValue, class TOutputValue>
class TrainVectorBase : public LearningApplicationBase<TInputValue, TOutputValue>
{
......
......@@ -124,7 +124,7 @@ TrainVectorBase<TInputValue, TOutputValue>
{
std::string key, item = feature.ogr().GetFieldDefnRef( iField )->GetNameRef();
key = item;
std::string::iterator end = std::remove_if( key.begin(), key.end(), IsNotAlphaNum );
std::string::iterator end = std::remove_if( key.begin(), key.end(), [](char c){return !std::isalnum(c);} );
std::transform( key.begin(), end, key.begin(), tolower );
OGRFieldType fieldType = feature.ogr().GetFieldDefnRef( iField )->GetType();
......
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbVectorPrediction_h
#define otbVectorPrediction_h
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbOGRDataSourceWrapper.h"
#include "otbOGRFeatureWrapper.h"
#include "itkVariableLengthVector.h"
#include "otbStatisticsXMLFileReader.h"
#include "itkListSample.h"
#include "otbShiftScaleSampleListFilter.h"
#include "otbMachineLearningModelFactory.h"
#include "otbMachineLearningModel.h"
#include <time.h>
namespace otb
{
namespace Wrapper
{
template <bool RegressionMode>
class VectorPrediction : public Application
{
public:
/** Standard class typedefs. */
using Self = VectorPrediction;
using Superclass = Application;
using Pointer = itk::SmartPointer<Self>;
using ConstPointer = itk::SmartPointer<const Self>;
/** Standard macro */
itkNewMacro(Self);
itkTypeMacro(Self, Application)
/** Filters typedef */
using ValueType = float;
// Label type is float for regression and unsigned int for classification
using LabelType = typename std::conditional<RegressionMode, float, unsigned int>::type;
using LabelSampleType = itk::FixedArray<LabelType, 1>;
using LabelListSampleType = itk::Statistics::ListSample<LabelSampleType>;
using MachineLearningModelType = otb::MachineLearningModel<ValueType, LabelType>;
using MachineLearningModelFactoryType = otb::MachineLearningModelFactory<ValueType, LabelType>;
using ModelPointerType = typename MachineLearningModelType::Pointer;
using ConfidenceListSampleType = typename MachineLearningModelType::ConfidenceListSampleType;
/** Statistics Filters typedef */
using MeasurementType = itk::VariableLengthVector<ValueType>;
using StatisticsReader = otb::StatisticsXMLFileReader<MeasurementType>;
using InputSampleType = itk::VariableLengthVector<ValueType>;
using ListSampleType = itk::Statistics::ListSample<InputSampleType>;
using ShiftScaleFilterType = otb::Statistics::ShiftScaleSampleListFilter<ListSampleType, ListSampleType>;
~VectorPrediction() override
{
MachineLearningModelFactoryType::CleanFactories();
}
private:
void DoInit() override;
/** Method defining the parameters used in the application and their documentation, specialized for RegressionMode=1 and RegrssionMode=0 */
void DoInitSpecialization();
void DoUpdateParameters() override;
void DoExecute() override;
/** Method returning whether the confidence map should be computed, depending on the regression mode and input parameters */
bool shouldComputeConfidenceMap() const;
/** Method returning the input list sample from the input layer */
typename ListSampleType::Pointer ReadInputListSample(otb::ogr::Layer const& layer);
/** Normalize a list sample using the statistic file given */
typename ListSampleType::Pointer NormalizeListSample(ListSampleType::Pointer input);
/** Create the output DataSource, in update mode the input layer is buffered and the input
* data source is re opened in update mode. */
otb::ogr::DataSource::Pointer CreateOutputDataSource(otb::ogr::DataSource::Pointer source,
otb::ogr::Layer & layer,
bool updateMode);
/** Add a prediction field in the output layer if it does not exist.
* If computeConfidenceMap evaluates to true a confidence field will be
* added. */
void AddPredictionField(otb::ogr::Layer & outLayer,
otb::ogr::Layer const& layer,
bool computeConfidenceMap);
/** Fill the output layer with the predicted values and optionnaly the confidence */
void FillOutputLayer(otb::ogr::Layer & outLayer,
otb::ogr::Layer const& layer,
typename LabelListSampleType::Pointer target,
typename ConfidenceListSampleType::Pointer quality,
bool updateMode,
bool computeConfidenceMap);
ModelPointerType m_Model;
/** Name used for the confidence field */
std::string confFieldName = "confidence";
};
}
}
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbVectorPrediction.hxx"
#endif
#endif
......@@ -716,11 +716,25 @@ if(OTB_USE_OPENCV)
-out ${TEMP}/apTvClSVMLabeledVector.shp
-feat meanB0 meanB1 meanB2 meanB3 varB0 varB1 varB2 varB3
-cfield class
VALID --compare-ogr 0.0
VALID --compare-ogr ${NOTOL}
${OTBAPP_BASELINE_FILES}/apTvClSVMLabeledVector.shp
${TEMP}/apTvClSVMLabeledVector.shp)
endif()
#----------- VectorRegression TESTS ----------------
if(OTB_USE_OPENCV)
otb_test_application(NAME apTvClDTVectorRegression
APP VectorRegression
OPTIONS -in ${INPUTDATA}/Classification/apTvClSampleExtractionOut.sqlite
-model ${INPUTDATA}/Classification/apTvClDTVectorRegression.dt
-out ${TEMP}/apTvClDTVectorRegression.sqlite
-feat value_0 value_1 value_2 value_3
-cfield predicted
VALID --compare-ogr ${NOTOL}
${OTBAPP_BASELINE_FILES}/apTvClDTVectorRegression.sqlite
${TEMP}/apTvClDTVectorRegression.sqlite)
endif()
#----------- ComputeImagesStatistics TESTS ----------------
otb_test_application(NAME apTvClComputeImagesStatisticsQB1
APP ComputeImagesStatistics
......
......@@ -32,13 +32,6 @@ namespace otb
{
namespace Wrapper
{
/** Utility function to negate std::isalnum */
bool IsNotAlphaNum(char c)
{
return !std::isalnum(c);
}
/**
* \class VectorDimensionalityReduction
*
......@@ -180,7 +173,7 @@ private:
{
std::string item = layerDefn.GetFieldDefn(iField)->GetNameRef();
std::string key(item);
std::string::iterator end = std::remove_if( key.begin(), key.end(), IsNotAlphaNum );
std::string::iterator end = std::remove_if( key.begin(), key.end(), [](char c){return !std::isalnum(c);});
std::transform( key.begin(), end, key.begin(), tolower );
std::string tmpKey = "feat." + key.substr( 0, static_cast<unsigned long>( end - key.begin() ) );
AddChoice(tmpKey,item);
......
......@@ -36,7 +36,7 @@ namespace Wrapper
template <class TImageType>
TImageType*
Application
::GetParameterImage(std::string parameter)
::GetParameterImage(std::string const& parameter)
{
typename TImageType::Pointer ret;
......@@ -57,7 +57,7 @@ Application
template <class TImageType>
void
Application
::SetParameterOutputImage(std::string parameter, TImageType* value)
::SetParameterOutputImage(std::string const& parameter, TImageType* value)
{
Parameter* param = GetParameterByKey(parameter);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment