\section{Introduction}\label{sample_ml_app_sample_intro}
This tutorial will help you create a sample machine learning app using mlpack/\+C++. Although this app does not cover all the mlpack capabilities, it will walkthrough several A\+P\+Is to understand how everything connects. This Windows sample app is created using Visual Studio, but you can easily adapt it to a different platform by following the provided source code.

\begin{DoxyNote}{Note}
Before starting, make sure you have built mlpack for Windows following this \doxyref{Windows guide}{p.}{build_windows}
\end{DoxyNote}
\section{Creating the V\+S project}\label{sample_ml_app_sample_create_project}

\begin{DoxyItemize}
\item Open Visual Studio and create a new project (Windows Console Application)
\item For this sample, the project is named “sample-\/ml-\/app”
\end{DoxyItemize}\section{Project Configuration}\label{sample_ml_app_sample_project_config}
There are different ways in which you can configure your project to link with dependencies. This configuration is for x64 Debug Mode. If you need Release Mode, please change the paths accordingly (assuming you have built mlpack and dependencies in Release Mode).


\begin{DoxyItemize}
\item Right click on the project and select Properties, select the x64 Debug profile
\item Under C/\+C++ $>$ General $>$ Additional Include Directories add\+: 
\begin{DoxyCode}
- C:\(\backslash\)boost\(\backslash\)boost\_1\_71\_0\(\backslash\)lib\(\backslash\)native\(\backslash\)include
- C:\(\backslash\)mlpack\(\backslash\)armadillo-9.800.3\(\backslash\)include
- C:\(\backslash\)mlpack\(\backslash\)mlpack-3.3.2\(\backslash\)build\(\backslash\)include
\end{DoxyCode}

\item Under Linker $>$ Input $>$ Additional Dependencies add\+: 
\begin{DoxyCode}
- C:\(\backslash\)mlpack\(\backslash\)mlpack-3.3.2\(\backslash\)build\(\backslash\)Debug\(\backslash\)mlpack.lib
- C:\(\backslash\)boost\(\backslash\)boost\_1\_71\_0\(\backslash\)lib64-msvc-14.2\(\backslash\)libboost\_serialization-vc142-mt-gd-x64-1\_71.lib
- C:\(\backslash\)boost\(\backslash\)boost\_1\_71\_0\(\backslash\)lib64-msvc-14.2\(\backslash\)libboost\_program\_options-vc142-mt-gd-x64-1\_71.lib
\end{DoxyCode}

\item Under Build Events $>$ Post-\/\+Build Event $>$ Command Line add\+: 
\begin{DoxyCode}
- xcopy /y \textcolor{stringliteral}{"C:\(\backslash\)mlpack\(\backslash\)mlpack-3.3.2\(\backslash\)build\(\backslash\)Debug\(\backslash\)mlpack.dll"} $(OutDir)
- xcopy /y \textcolor{stringliteral}{"C:\(\backslash\)mlpack\(\backslash\)mlpack-3.3.2\(\backslash\)packages\(\backslash\)OpenBLAS.0.2.14.1\(\backslash\)lib\(\backslash\)native\(\backslash\)bin\(\backslash\)x64\(\backslash\)*.dll"} $(OutDir)
\end{DoxyCode}

\end{DoxyItemize}

\begin{DoxyNote}{Note}
Recent versions of Visual Studio set \char`\"{}\+Conformance Mode\char`\"{} enabled by default. This causes some issues with the armadillo library. If you encounter this issue, disable \char`\"{}\+Conformance Mode\char`\"{} under C/\+C++ $>$ Language.
\end{DoxyNote}
\section{The app goal}\label{sample_ml_app_sample_app_goal}
This app aims to exercise an end-\/to-\/end machine learning workflow. We will cover\+:


\begin{DoxyItemize}
\item Loading and preparing a dataset
\item Training (using Random Forest as example)
\item Computing the training accuracy
\item Cross-\/\+Validation using K-\/\+Fold
\item Metrics gathering (accuracy, precision, recall, F1)
\item Saving the trained model to disk
\item Loading the model
\item Classifying a new sample
\end{DoxyItemize}\section{Headers and namespaces}\label{sample_ml_app_sample_headers_namespaces}
For this app, we will need to include the following headers (i.\+e. add into stdafx.\+h)\+:


\begin{DoxyCode}
\textcolor{preprocessor}{#include "mlpack/core.hpp"}
\textcolor{preprocessor}{#include "mlpack/methods/random_forest/random_forest.hpp"}
\textcolor{preprocessor}{#include "mlpack/methods/decision_tree/random_dimension_select.hpp"}
\textcolor{preprocessor}{#include "mlpack/core/cv/k_fold_cv.hpp"}
\textcolor{preprocessor}{#include "mlpack/core/cv/metrics/accuracy.hpp"}
\textcolor{preprocessor}{#include "mlpack/core/cv/metrics/precision.hpp"}
\textcolor{preprocessor}{#include "mlpack/core/cv/metrics/recall.hpp"}
\textcolor{preprocessor}{#include "mlpack/core/cv/metrics/F1.hpp"}
\end{DoxyCode}


Also, we will use the following namespaces\+:


\begin{DoxyCode}
\textcolor{keyword}{using namespace }arma;
\textcolor{keyword}{using namespace }mlpack;
\textcolor{keyword}{using namespace }mlpack::tree;
\textcolor{keyword}{using namespace }mlpack::cv;
\end{DoxyCode}
\section{Loading the dataset}\label{sample_ml_app_sample_load_dataset}
First step is about loading the dataset. Different dataset file formats are supported, but here we load a C\+SV dataset, and we assume the labels don\textquotesingle{}t require normalization.

\begin{DoxyNote}{Note}
Make sure you update the path to your dataset file. For this sample, you can simply copy \char`\"{}mlpack/tests/data/german.\+csv\char`\"{} and paste into a new \char`\"{}data\char`\"{} folder in your project directory.
\end{DoxyNote}

\begin{DoxyCode}
mat dataset;
\textcolor{keywordtype}{bool} loaded = mlpack::data::Load(\textcolor{stringliteral}{"data/german.csv"}, dataset);
\textcolor{keywordflow}{if} (!loaded)
  \textcolor{keywordflow}{return} -1;
\end{DoxyCode}


Then we need to extract the labels from the last dimension of the dataset and remove the labels from the training set\+:


\begin{DoxyCode}
Row<size\_t> labels;
labels = conv\_to<Row<size\_t>>::from(dataset.row(dataset.n\_rows - 1));
dataset.shed\_row(dataset.n\_rows - 1);
\end{DoxyCode}


We now have our dataset ready for training.\section{Training}\label{sample_ml_app_sample_training}
This app will use a Random Forest classifier. At first we define the classifier parameters and then we create the classifier to train it.


\begin{DoxyCode}
\textcolor{keyword}{const} \textcolor{keywordtype}{size\_t} numClasses = 2;
\textcolor{keyword}{const} \textcolor{keywordtype}{size\_t} minimumLeafSize = 5;
\textcolor{keyword}{const} \textcolor{keywordtype}{size\_t} numTrees = 10;

RandomForest<GiniGain, RandomDimensionSelect> rf;

rf = RandomForest<GiniGain, RandomDimensionSelect>(dataset, labels,
  numClasses, numTrees, minimumLeafSize);
\end{DoxyCode}


Now that the training is completed, we quickly compute the training accuracy\+:


\begin{DoxyCode}
Row<size\_t> predictions;
rf.Classify(dataset, predictions);
\textcolor{keyword}{const} \textcolor{keywordtype}{size\_t} correct = arma::accu(predictions == labels);
cout << \textcolor{stringliteral}{"\(\backslash\)nTraining Accuracy: "} << (double(correct) / double(labels.n\_elem));
\end{DoxyCode}
\section{Cross-\/\+Validating}\label{sample_ml_app_sample_crossvalidation}
Instead of training the Random Forest directly, we could also use K-\/fold cross-\/validation for training, which will give us a measure of performance on a held-\/out test set. This can give us a better estimate of how the model will perform when given new data. We also define which metric to use in order to assess the quality of the trained model.


\begin{DoxyCode}
\textcolor{keyword}{const} \textcolor{keywordtype}{size\_t} k = 10;
KFoldCV<RandomForest<GiniGain, RandomDimensionSelect>, Accuracy> cv(k, 
  dataset, labels, numClasses);
\textcolor{keywordtype}{double} cvAcc = cv.Evaluate(numTrees, minimumLeafSize);
cout << \textcolor{stringliteral}{"\(\backslash\)nKFoldCV Accuracy: "} << cvAcc;
\end{DoxyCode}


To compute other relevant metrics, such as Precision, Recall and F1\+:


\begin{DoxyCode}
\textcolor{keywordtype}{double} cvPrecision = Precision<Binary>::Evaluate(rf, dataset, labels);
cout << \textcolor{stringliteral}{"\(\backslash\)nPrecision: "} << cvPrecision;

\textcolor{keywordtype}{double} cvRecall = Recall<Binary>::Evaluate(rf, dataset, labels);
cout << \textcolor{stringliteral}{"\(\backslash\)nRecall: "} << cvRecall;

\textcolor{keywordtype}{double} cvF1 = F1<Binary>::Evaluate(rf, dataset, labels);
cout << \textcolor{stringliteral}{"\(\backslash\)nF1: "} << cvF1;
\end{DoxyCode}
\section{Saving the model}\label{sample_ml_app_sample_save_model}
Now that our model is trained and validated, we save it to a file so we can use it later. Here we save the model that was trained using the entire dataset. Alternatively, we could extract the model from the cross-\/validation stage by using {\ttfamily cv.\+Model()} 


\begin{DoxyCode}
mlpack::data::Save(\textcolor{stringliteral}{"mymodel.xml"}, \textcolor{stringliteral}{"model"}, rf, \textcolor{keyword}{false});
\end{DoxyCode}


We can also save the model in {\ttfamily bin} format (\char`\"{}mymodel.\+bin\char`\"{}) which would result in a smaller file.\section{Loading the model}\label{sample_ml_app_sample_load_model}
In a real-\/life application, you may want to load a previously trained model to classify new samples. We load the model from a file using\+:


\begin{DoxyCode}
mlpack::data::Load(\textcolor{stringliteral}{"mymodel.xml"}, \textcolor{stringliteral}{"model"}, rf);
\end{DoxyCode}
\section{Classifying a new sample}\label{sample_ml_app_sample_classify_sample}
Finally, the ultimate goal is to classify a new sample using the previously trained model. Since the Random Forest classifier provides both predictions and probabilities, we obtain both.


\begin{DoxyCode}
mat sample(\textcolor{stringliteral}{"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 << \textcolor{stringliteral}{"\(\backslash\)nClassification result: "} << result << \textcolor{stringliteral}{" , Probabilities: "} <<
    probabilities.at(0) << \textcolor{stringliteral}{"/"} << probabilities.at(1);
\end{DoxyCode}
\section{Final thoughts}\label{sample_ml_app_sample_app_conclussion}
Building real-\/life applications and services using machine learning can be challenging. Hopefully, this tutorial provides a good starting point that covers the basic workflow you may need to follow while developing it. You can take a look at the entire source code in the provided sample project located here\+: \char`\"{}doc/examples/sample-\/ml-\/app\char`\"{}. 