Introduction
In Build 2018, Microsoft introduced the preview of ML.NET (Machine Learning .NET) which is a cross platform, open source machine learning framework. Yes, now it's easy to develop our own Machine Learning application or develop a custom module using Machine Learning framework. ML.NET is a machine learning framework which was mainly developed for .NET developers. We can use C# or F# to develop ML.NET applications. ML.NET is an open source which can be run on Windows, Linux and macOS. The ML.NET is still in development and now we can use the preview version to work and play with ML.NET.
Reference link: Introducing ML.NET: Cross-platform, Proven and Open Source Machine Learning Framework
In this article, we will see how to develop our first ML.Net application to predict the Item stock quantity.
Machine Learning Regression
In this sample program, we will be using Machine Leaning Regression of ML.NET to predict the Item Stock. Regression is a statistical method to find the relation between variable, for example in our demo program, we will be predicting the stock item based on the existing stock dataset.
Reference link: Regression, Taxi fare predictor (regression)
Things to Know Before Staring ML.NET
Initialize the Model
For working with Machine Learning first, we need to pick our best fit machine learning algorithm. Machine learning has Clustering, regression, classification and anomaly detection modules. Here, in this article, we will be using the regression model for predicting the item stock.
Train
We need to train the machine learning model. Training is the process of analyzing input data by model. The training is mainly used for model to learn the pattern and save them as a trained model. For example, we will be creating a CSV file in our application and in the CSV file, we will be giving the stock details as ItemID
, Location
, InQTY
, OutQTY
, ItemType
and TotalStock
quantity. We give around 100 records in the CSV file as sample with all necessary details. We need to give this CSV file as input to our model. Our model needs to be trained and using this data, our model needs to analyze to predict the result. Once our model is trained and understands the pattern of the input, the resultant model needs to be saved to predict with the result.
Score
Score is also called as the prediction where score needs to have the same column as the train model. Score generates the result based on the trained model.
Evaluate
Evaluate will be performed after the model training completed. In evaluate, the trained model will be compared with the test data to compare and predict the final result to be produced.
Reference link: https://docs.microsoft.com/en-us/azure/machine-learning/studio-module-reference/machine-learning-modules
Background
Prerequisites
Make sure, you have installed all the prerequisites in your computer. If not, then download and install Visual Studio 2017 15.6 or later with the ".NET Core cross-platform development" workload installed.
Using the Code
Step 1 - Create C# Console Application
After installing the prerequisites, click Start >> Programs >> Visual Studio 2017 >> Visual Studio 2017 on your desktop. Click New >> Project. Select Visual C# >> Windows Desktop >> Console APP (.NET Framework). Enter your project name and click OK.
Step 2 – Add Microsoft ML package
Right click on your project and click on Manage NuGet Packages.
Select Browse tab and search for Microsoft.ML.
Click on Install, I Accept and wait till the installation is complete.
We can see as the Microsoft.ML
package was installed and all the references for Microsoft.ML
have been added in our project references.
Step 3 – Creating Train and Evaluate Data
Now we need to create a Model training and evaluate dataset. For creating this, we will add two CSV files, one for training and one for the evaluate. We will create a new folder called data in our project to add our CSV files.
Add Data Folder
Right click the project and Add New Folder and name the folder as “Data”.
Creating Train CSV File
Right click the Data folder, click on Add >> New Item >> select the text file and name it as “StockTrain.csv”.
Select the properties of the “StockTrain.csv”, change the Copy to Output Directory to “Copy always”.
Add your CSV file data like below:
Here, we have added the data with the following fields.
Note that we need to fix the label and the features.
Label
: Label
is the field which we need to predict in our sample here, TotalStockQty
is the Label
where we will be predicting the Total remaining Stock Quantity of an item. Other all fields we make it as features.
ItemID
- Stock Item ID (Feature
) Loccode
– Warehouse Location of the Item (Feature
) InQty
– Total Item received in location (Feature
) OutQty
– Total Item delivered from the location (Feature
) ItemType
- ItemType
“In
” means as local manufactured and “out
” means as outsourced (Feature
) TotalStockQty
- Total number of item stock in location (Label
)
Note: We need minimum 100 records of data to be added to train our Model.
Same like this, we add one more CSV file and add similar information for evaluate. We have created one more csv file name as “StockTest.csv”.
Step 4 – Creating Class for Input Data and Prediction
Now we need to create a class for Input Data and prediction, for doing this, right click our project and add new class and name it as “ItemStock.cs”.
In our class first, we need to import the Microsoft.ML.Runtime.Api
.
using Microsoft.ML.Runtime.Api;
Next, we need to add all our columns same like our CSV file in the same order in our class and set as the column 0
to 5
.
public class ItemStock
{
[Column("0")]
public string ItemID;
[Column("1")]
public float Loccode;
[Column("2")]
public float InQty;
[Column("3")]
public float OutQty;
[Column("4")]
public string ItemType;
[Column("5")]
public float TotalStockQty;
}
Creating prediction
class. Now, we need to create a prediction
class and, in this class, we need to add our Prediction
column. Prediction
column is the same as our label. Our label is “TotalStockQty
”. Our aim of this program is to predict and display the final result of the Total Stock quantity from the trained model. We add “TotalStockQty
” as prediction
column in our prediction
class.
Note: It is important to note that in the prediction column, we need to set the column name as the “Score
” also set the data type as the float
.
In the regression model, the score
column contains the predicted results.
public class itemStockQtyPrediction
{
[ColumnName("Score")]
public float TotalStockQty;
}
Step 5 – Program.cs
To work with ML.NET, we open our “program.cs” file and first, we import all the needed ML.NET references.
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Models;
using Microsoft.ML.Trainers;
using Microsoft.ML.Transforms;
Dataset Path
We set the Traincsv
data, Evaluate data and Model data path. For the traindata, we give “StockTrain.csv” path and same like that for the evaluate CSV file.
The final trained model needs to be saved for evaluating and producing results. For this, we set modelpath
with the “Model.zip” file. The trained model will be saved in the zip file automatically during runtime of the program our bin folder with all needed files.
static readonly string _Traindatapath =
Path.Combine(Environment.CurrentDirectory, "Data", "StockTrain.csv");
static readonly string _Evaluatedatapath =
Path.Combine(Environment.CurrentDirectory, "Data", "StockTest.csv");
static readonly string _modelpath =
Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");
Change the Main
method to async Task Main
method like below code:
static async Task Main(string[] args)
{
}
Before doing this, we need to perform 2 important tasks to successfully run our program:
First is to set Platform Target as x64. The ML.NET only runs in x64, for doing this, right click the project and select properties >> Select Build and change the Platform target to x64.
In order to run with our async Task Main
method, we need to change the Language version to C#7.1
In the Project Properties >> Build tab >> click on Advance button at the bottom and change the Language Version to C#7.1
Working with Training Model
First, we need to train the model and save the model to the zip file for this in our main
method we call the predictionModel
method and pass the ItemStock
and itemStockQtyPrediction
class and return the model to the main
method.
static async Task Main(string[] args)
{
PredictionModel<ItemStock, itemStockQtyPrediction> model = await TrainourModel();
}
public static async Task<PredictionModel<ItemStock, itemStockQtyPrediction>> TrainourModel()
{
}
Train and Save Model
In the above method, we add the function to train the model and save the model to the zip file.
LearningPipeline
In training, the first step will be working the LearningPipeline()
.
The LearningPipeline
loads all the training data to train the model.
TextLoader
The TextLoader
used to get all the data from tran CSV file for training and here, we set as the useHeader:true
to avoid reading the first row from the CSV file.
ColumnCopier
In the training model, the important part is the predicted values to be defined. In our example, we have set the TotalStockQty
as the label. In training model, we need to set the prediction label by using the ColumnCopier
. We can see in our below code part in ColumnCopier
, we have given the TotalStockQty
and Label
.
CategoricalOneHotVectorizer
The training model needs the numeric features we need to transform the categorical data like our ItemID
, ItemType
into numbers.
ColumnConcatenator
Next, we add all our features columns to be trained and evaluated.
Adding Learning Algorithm
FastTreeRegressor
The learner will train the model.We have selected the regression for our sample and we will be using FastTreeRegressor
learner. FastTreeRegressor
is one of the regression learners provided by the ML.NET. Here, we add the FastTreeRegressor
to our pipeline.
Train and Save Model
Finally, we will train and save the model from this method.
public static async Task<PredictionModel<ItemStock, itemStockQtyPrediction>> TrainourModel()
{
var pipeline = new LearningPipeline
{
new TextLoader(_Traindatapath).CreateFrom<ItemStock>(useHeader: true, separator: ','),
new ColumnCopier(("TotalStockQty", "Label")),
new CategoricalOneHotVectorizer(
"ItemID",
"ItemType"),
new ColumnConcatenator(
"Features",
"ItemID",
"Loccode",
"InQty",
"OutQty",
"ItemType"),
new FastTreeRegressor()
};
PredictionModel<ItemStock,
itemStockQtyPrediction> model = pipeline.Train<ItemStock, itemStockQtyPrediction>();
await model.WriteAsync(_modelpath);
return model;
}
Evaluate Model
Next, we need to evaluate the model by checking the model with the test data and predict the final results. For this, we call the method Evaluate
from our main
method and pass the trained model to this method.
static async Task Main(string[] args)
{
PredictionModel<ItemStock, itemStockQtyPrediction> model = await TrainourModel();
Evaluate(model);
}
In the Evaluate
method, we pass the trained model. We need to evaluate the model with our sample CSV test data. In this method using textloader
, we load all the data from test data CSV file for evaluating the model.
Using RegressionEvaluator
method, we evaluate the model with the testdata
and produce evaluation metrics.
We display both the RMS (Root mean Squared) and RSquared metrics value.
RMS is one of the evaluation metrics where the lower RMS value is treated as the better model.
RSquared
is another evaluation metrics where the value will be between 0
and 1
. If the value is closer to 1
, it is the better model.
private static void Evaluate(PredictionModel<ItemStock, itemStockQtyPrediction> model)
{
var testData = new TextLoader(_Evaluatedatapath).CreateFrom<ItemStock>
(useHeader: true, separator: ',');
var evaluator = new RegressionEvaluator();
RegressionMetrics metrics = evaluator.Evaluate(model, testData);
Console.WriteLine($"Rms = {metrics.Rms}");
Console.WriteLine($"RSquared = {metrics.RSquared}");
}
Prediction Results
Now it's time for us to produce the result of predicted results by model. For this, we will add one more class and, in this Class, we will give the inputs.
Create a new Class named as “ItemStocks.cs“.
We add the values to the ItemStock
Class which we already created and defined the columns for Model training. Here, we have created to stock input and we have given the values as below.
Note: In each Stock
, we didn’t give the input for the TotalStockQty
and we have set the TotalStockQty = 0
as the model needs to predict the result from the trained model and produce the result.
static class ItemStocks
{
internal static readonly ItemStock stock1 = new ItemStock
{
ItemID = "Item001",
Loccode = 1,
InQty = 100,
OutQty = 10,
ItemType = "IN",
TotalStockQty = 0
};
internal static readonly ItemStock stock2 = new ItemStock
{
ItemID = "Item003",
Loccode = 4,
InQty = 6000,
OutQty = 1200,
ItemType = "IN",
TotalStockQty = 0
};
}
We can see in our StockTrain.csv file that we have added the values of the above stock1
and we can see as we have given TotalStockQty
as 90
and the Model
needs to predict this result and produce the result.
Same like that for Stock2
also, we have added the values in the StockTrain.csv file, we can see as we have given TotalStockQty
as 4800
and the Model
needs to predict this result and produce the result.
Produce the Model Predicted Results
In our program main
method, we will add the below code at the bottom after Train
and Evaluate
method calling to predict the Stock Quantity details and display the final predicted results from model to users in command window.
Here, we display both Stock1
and Stock2
prediction results. The prediction.TotalStockQty
will have the model predicted results and we display the results to the end users of the predicted Stock Quantity with actual input given by us.
Console.WriteLine("-------First Prediction Vale : ----------------" );
itemStockQtyPrediction prediction = model.Predict(ItemStocks.stock1);
Console.WriteLine("Item ID {0}", ItemStocks.stock1.ItemID);
Console.WriteLine("Predicted Stock: {0}, actual Stock Qty: 90 ", prediction.TotalStockQty);
Console.WriteLine(" ");
Console.WriteLine("----------Next Prediction : -------------");
Console.WriteLine(" ");
prediction = model.Predict(ItemStocks.stock2);
Console.WriteLine("Item ID {0}", ItemStocks.stock2.ItemID);
Console.WriteLine("Predicted Stock: {0}, actual Stock Qty: 4800 ", prediction.TotalStockQty);
Console.ReadLine();
Build and Run
When we can run the program, we can see the result in the command window like below.
We can see the Rms value as: 0.052 as we already discussed in this article if the Rms value is near to 0, then the model is good in prediction and also, we can see the RSquared =0.999
as we already discussed in this article as if the RSquared
value is near to 1
then the model is good and we can see the predicted result of both the Stock1
and Stock2
as both have predicted same Stock
quantity as the actual. Our Model
is very good in prediction and the predicted value is exactly the same as the actual value.
Trained Model Information
After we build and run the program, we can see the Model.zip file in Data folder inside the Application root bin folder. We can also see our StockTrain
and StockTest
CSV file. The Model will be trained with this CSV file and trained model result will be stored in Model.zip file for predicting the result.
Points of Interest
ML.NET (Machine Learning DotNet) is a great framework for all the .NET lovers who are all looking to work with machine learning. Now only preview version of ML.NET is available and I can’t wait till the release of the public version of ML.NET. Here in this article, I have used the regression model to predict and display the Total Stock Quantity. If you are .NET lovers, not aware about Machine Learning and looking forward to work with machine learning, then ML.Net is for you all and it's a great framework to getting started with ML.NET. Hope you all enjoy reading this article and see you all soon with another post.
History