Add support for scikit-learn training and prediction
Rationale
Currently, iota2 only supports the use of Machine Learning algorithms available through OTB applications. It may be interesting to have a wider choice of ML algorithms for classification and regression. scikit-learn is the most popular and richer ML library of the Python ecosystem and supporting its API would improve iota2 a lot. Added to the richness of choice, it would also be easier for contributors to provide new ML approaches by following the scikit-learn API which has become a de facto standard even for algorithms not included in scikit-learn.
In order to support the scikit-learn API, iota2 needs the addition of 2 alternate paths, one for the training step and another for the prediction (classification or regression). These paths will be taken when the corresponding choice of algorithm is made in the configuration file.
Training
The training will be very similar to the current one. After the vector sampler step, the sample files can be fed to the scikit-learn algorithm in order to produce a model which is saved to a file so that it can be used in the prediction step. A function with the same API as the current training based on OTB's TrainVectorClassifier needs to be implemented.
Prediction
The prediction step is trickier, since we need to avoid writing the feature image stacks to disk. Also, streaming capabilities are needed since a whole image stack will not fit into RAM when read as a numpy array. One solution is to manually stream regions at the output of the feature extraction step using the ExtractROI OTB application. The output of the ExtractROI application can be obtained as a numpy array using the OTB Applications API. This numpy array can be passed to the scikit-learn algorithm which will return another numpy array. This output numpy array will have only one band (the label) or maybe 2 if we get confidence or probability values and can be mosaicked in memory or directly streamed to disk using the gdal python API.
Configuration file
We will need to refactor the corresponding section of the configuration file so that the choice of the algorihtm and its parameters is straightforward for the user and without the need of having a static list of available algorithms.
Proposed steps
Since we are not experts in the use of scikit learn, it will be easier to start by implementing a simple example, like a Random Forest, as a proof of concept before going completely generic in terms of algorithms.