112 lines
6.0 KiB
C++
112 lines
6.0 KiB
C++
// Sample app based on the Windows ML App Tutorial.
|
|
// Quickly shows how to you create a machine learning app using mlpack/C++.
|
|
|
|
#include "stdafx.h"
|
|
|
|
using namespace arma;
|
|
using namespace mlpack;
|
|
using namespace mlpack::tree;
|
|
using namespace mlpack::cv;
|
|
|
|
/*
|
|
This sample app covers a brief end-to-end ML workflow
|
|
as you would do in a real-life application. Including:
|
|
- Loading and preparing a dataset
|
|
- Training (Random Forest as example)
|
|
- Computing the training accuracy
|
|
- Cross-Validation using K-Fold
|
|
- Metrics gathering (accuracy, precision, recall, F1)
|
|
- Saving the trained model
|
|
- Loading the model
|
|
- Classifying a new sample
|
|
|
|
Assumptions:
|
|
- No labels normalization required
|
|
*/
|
|
int main()
|
|
{
|
|
printf("[SAMPLE:BEGIN]");
|
|
|
|
// (1) Load the dataset
|
|
printf("\nLoading dataset...");
|
|
|
|
mat dataset;
|
|
|
|
// CSV is loaded transposed (columns are samples, rows are dimensions)
|
|
bool loaded = mlpack::data::Load("data/german.csv", dataset);
|
|
if (!loaded)
|
|
return -1;
|
|
|
|
Row<size_t> labels;
|
|
|
|
// Extract the labels from the last dimension of the training set
|
|
labels = conv_to<Row<size_t>>::from(dataset.row(dataset.n_rows - 1));
|
|
|
|
// Remove the labels from the training set
|
|
dataset.shed_row(dataset.n_rows - 1);
|
|
|
|
// (2) Training
|
|
printf("\nTraining...");
|
|
const size_t numClasses = 2;
|
|
const size_t minimumLeafSize = 5;
|
|
const size_t numTrees = 10;
|
|
|
|
RandomForest<GiniGain, RandomDimensionSelect> rf;
|
|
|
|
rf = RandomForest<GiniGain, RandomDimensionSelect>(dataset, labels,
|
|
numClasses, numTrees, minimumLeafSize);
|
|
|
|
Row<size_t> predictions;
|
|
rf.Classify(dataset, predictions);
|
|
|
|
const size_t correct = arma::accu(predictions == labels);
|
|
|
|
printf("\nTraining Accuracy: %f", (double(correct) / double(labels.n_elem)));
|
|
|
|
// (3) Cross-Validation
|
|
printf("\nCross-Validating...");
|
|
const size_t k = 10;
|
|
|
|
KFoldCV<RandomForest<GiniGain, RandomDimensionSelect>, Accuracy> cv(k,
|
|
dataset, labels, numClasses);
|
|
|
|
double cvAcc = cv.Evaluate(numTrees, minimumLeafSize);
|
|
printf("\nKFoldCV Accuracy: %f", cvAcc);
|
|
|
|
double cvPrecision = Precision<Binary>::Evaluate(rf, dataset, labels);
|
|
printf("\nPrecision: %f", cvPrecision);
|
|
|
|
double cvRecall = Recall<Binary>::Evaluate(rf, dataset, labels);
|
|
printf("\nRecall: %f", cvRecall);
|
|
|
|
double cvF1 = F1<Binary>::Evaluate(rf, dataset, labels);
|
|
printf("\nF1: %f", cvF1);
|
|
|
|
// (4) Save the model
|
|
printf("\nSaving model...");
|
|
mlpack::data::Save("mymodel.xml", "model", rf, false,
|
|
mlpack::data::format::xml);
|
|
|
|
// (5) Load the model
|
|
printf("\nLoading model...");
|
|
mlpack::data::Load("mymodel.xml", "model", rf);
|
|
|
|
// (6) Classify a new sample
|
|
printf("\nClassifying a new sample...");
|
|
// Should classify as "1"
|
|
mat sample("2 12 2 13 1 2 2 1 3 24 3 1 1 1 1 1 0 1 0 1 0 0 0");
|
|
|
|
mat probabilities;
|
|
|
|
rf.Classify(sample, predictions, probabilities);
|
|
|
|
u64 result = predictions.at(0);
|
|
|
|
printf("\nClassification result: %i (Probabilities: %f/%f)", result,
|
|
probabilities.at(0), probabilities.at(1));
|
|
|
|
printf("\n[SAMPLE:END]\n");
|
|
return 0;
|
|
}
|
|
|