/** * @file sample-ml-app.cpp * @author German Lancioni * * Sample app based on the Windows ML App Tutorial. * Quickly shows how to create a machine learning app using mlpack/C++. * * mlpack is free software; you may redistribute it and/or modify it under the * terms of the 3-clause BSD license. You should have received a copy of the * 3-clause BSD license along with mlpack. If not, see * http://www.opensource.org/licenses/BSD-3-Clause for more information. */ #include "stdafx.h" using namespace arma; using namespace mlpack; using namespace std; /* 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() { cout << "[SAMPLE:BEGIN]"; // (1) Load the dataset cout << "\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 labels; // Extract the labels from the last dimension of the training set labels = conv_to>::from(dataset.row(dataset.n_rows - 1)); // Remove the labels from the training set dataset.shed_row(dataset.n_rows - 1); // (2) Training cout << "\nTraining..."; const size_t numClasses = 2; const size_t minimumLeafSize = 5; const size_t numTrees = 10; RandomForest rf; rf = RandomForest(dataset, labels, numClasses, numTrees, minimumLeafSize); Row predictions; rf.Classify(dataset, predictions); const size_t correct = arma::accu(predictions == labels); cout << "\nTraining Accuracy: " << (double(correct) / double(labels.n_elem)); // (3) Cross-Validation cout << "\nCross-Validating..."; const size_t k = 10; KFoldCV, Accuracy> cv(k, dataset, labels, numClasses); double cvAcc = cv.Evaluate(numTrees, minimumLeafSize); cout << "\nKFoldCV Accuracy: " << cvAcc; double cvPrecision = Precision::Evaluate(rf, dataset, labels); cout << "\nPrecision: " << cvPrecision; double cvRecall = Recall::Evaluate(rf, dataset, labels); cout << "\nRecall: " << cvRecall; double cvF1 = F1::Evaluate(rf, dataset, labels); cout << "\nF1: " << cvF1; // (4) Save the model cout << "\nSaving model..."; mlpack::data::Save("mymodel.xml", "model", rf, false); // (5) Load the model cout << "\nLoading model..."; mlpack::data::Load("mymodel.xml", "model", rf); // (6) Classify a new sample cout << "\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); cout << "\nClassification result: " << result << " , Probabilities: " << probabilities.at(0) << "/" << probabilities.at(1); cout << "\n[SAMPLE:END]\n"; return 0; }