Classification Model – Hands-On Machine Learning with ML.NET

Classification Model

With regression models behind us, it is now time to dive into classification models. In this chapter, we will examine the math behind classification models, as well as the various applications of classification models. In addition, we will build two new ML.NET classification applications: the first, a binary classification example that will predict if a car's price is a good deal or not, akin to what you would find on a car purchase website; the other application, a multi-class classification application that categorizes emails. Finally, we will explore how to evaluate a classification model with the properties ML.NET exposes in classification models.

In this chapter, we will cover the following topics:

  • Breaking down classification models
  • Creating a binary classification application
  • Creating a multi-class classification application
  • Evaluating a classification model

Breaking down classification models

As mentioned in Chapter 1, Getting Started with Machine Learning and ML.NET, classification is broken down into two main categories—two-class and multi-class. In a two-class classifier, also known as a binary classifier, the prediction simply returns 0 or 1. In a multi-class problem, a pre-selected range of return labels, such as virus types or car types, is returned.  

There are several binary classification model types available in the machine learning ecosystem to choose from, as follows:

  • AveragedPerceptronTrainer
  • SdcaLogisticRegressionBinaryTrainer
  • SdcaNonCalibratedBinaryTrainer
  • SymbolicSgdLogisticRegressionBinaryTrainer
  • LbfgsLogisticRegressionBinaryTrainer
  • LightGbmBinaryTrainer
  • FastTreeBinaryTrainer
  • FastForestBinaryTrainer
  • GamBinaryTrainer
  • FieldAwareFactorizationMachineTrainer
  • PriorTrainer
  • LinearSvmTrainer

The car-value application we will be creating later in this chapter utilizes the FastTreeBinaryTrainer model.

ML.NET also provides the following multi-class classifiers:

  • LightGbmMulticlassTrainer
  • SdcaMaximumEntropyMulticlassTrainer
  • SdcaNonCalibratedMulticlassTrainer
  • LbfgsMaximumEntropyMulticlassTrainer
  • NaiveBayesMulticlassTrainer
  • OneVersusAllTrainer
  • PairwiseCouplingTrainer

For the multi-class classifier example application, we will be using the SdcaMaximumEntropyMulticlassTrainer model. The reason for this is that Stochastic Dual Coordinate Ascents (SDCAs) can provide a good default performance without tuning.

Choosing a classification trainer

Given the two types of classification, which should you choose? As stated earlier in this chapter, compared to regression models, your prediction output type will decide between binary and multi-class classification. Does your problem simply predict a value of true or false, or does it provide a more varied output based on a pre-defined value set? If your answer is the former, you need to use a binary classification. If the latter, you will need to use a multi-class classification. In this chapter, we will demonstrate both model prediction types.

For specific binary classification trainers, SDCA, LightGBM, and FastTree are the most popular options, as well as the most documented.

For specific multi-class classification trainers, LightGBM and SDCA are the most popular and best-documented options. 

Creating a binary classification application

As mentioned earlier, the application we will be creating is a car-value predictor. Given a set of attributes tied to a car, one can predict if the price is a good deal or not. The attributes included in this example aren't a definitive list of attributes, nor should they be used as-is in a production environment. However, one could use this as a starting point for predicting a simple true-or-false answer based on several attributes.

As with previous chapters, the complete project code, sample dataset, and project files can be downloaded here: https://github.com/PacktPublishing/Hands-On-Machine-Learning-With-ML.NET/tree/master/chapter04.

Diving into the trainer

As previously mentioned, for this binary classification application, we will be using the FastTree trainer.   

FastTree is based on the Multiple Additive Regression Trees (MART) gradient boosting algorithm. Gradient boosting is a very popular technique, in which a series of trees are built in a step-wise manner before ultimately selecting the best tree. MART takes this approach a step further by learning an ensemble of regression trees that use scalar values in their leaves.

The FastTree trainer doesn't require normalization but does require all of the feature columns to use a float variable type and the label column to be a bool variable type.

If you are curious about MART, Cornell University has a paper from 2015 on the subject: https://arxiv.org/abs/1505.01866.

Exploring the project architecture

Building on the project architecture and code we created in Chapter 3, Regression Model, the major change architecturally in this example is the mechanism for input. For this application, since we are using the FastTree algorithm, this requires referencing the Microsoft.ML.FastTree NuGet package (version 1.3.1 is the latest at the time of this writing). If you are building this project from scratch and do not remember how to add a NuGet reference, please refer back to Chapter 2Setting Up the ML.NET Environment

In the following screenshot, you will find the Visual Studio Solution Explorer view of the project. The new addition to the solution is the testdata.csv file, which we will review here:

The sampledata.csv file contains 18 rows of random data. Feel free to adjust the data to fit your own observations or to adjust the trained model. Here is a snippet of the data:

0,0,0,4000,0
1,1,1,4500,1
0,1,0,5000,0
0,0,1,4500,0
0,0,0,3000,1
0,1,0,3100,1
0,1,1,3500,1
1,1,1,5500,0
1,1,1,4200,1

Each of these rows contains the value for the properties in the newly created CarInventory class that we will review later on in this chapter.

In addition, in this chapter, we added the testdata.csv file that contains additional data points to test the newly trained model against and evaluate. Here is a snippet of the data inside of testdata.csv:

0,0,0,2010,1
1,0,0,2600,1
1,0,0,3700,0
1,1,0,3100,1
1,1,0,3600,0
0,1,0,3500,0
0,0,1,3400,1
0,0,1,5100,0

Diving into the code

For this application, as noted in the previous section, we are building on top of the work completed in Chapter 3, Regression Model. For this deep dive, we are going to focus solely on the code that was changed for this application.

Classes that were changed or added are as follows:

  • CarInventory
  • CarInventoryPrediction
  • Predictor
  • Trainer
  • Program

The CarInventory class

The CarInventory class is the container class that contains the data to both predict and train our model. These columns map in order of the sample data reviewed previously. If you begin experimenting with new features and add to the following class, ensure you increment the array index appropriately, as follows:

using Microsoft.ML.Data;

namespace chapter04.ML.Objects
{
public class CarInventory
{
[LoadColumn(0)]
public float HasSunroof { get; set; }

[LoadColumn(1)]
public float HasAC { get; set; }

[LoadColumn(2)]
public float HasAutomaticTransmission { get; set; }

[LoadColumn(3)]
public float Amount { get; set; }

[LoadColumn(4)]
public bool Label { get; set; }
}
}

The CarInventoryPrediction class

The CarInventoryPrediction class contains the properties mapped to our prediction output, in addition to the Score and Probability properties used for model evaluation. The PredictedLabel property contains our classification result, not the label as in previous chapters, as shown in the following code block:

namespace chapter04.ML.Objects
{
public class CarInventoryPrediction
{
public bool Label { get; set; }

public bool PredictedLabel { get; set; }

public float Score { get; set; }

public float Probability { get; set; }
}
}

The Predictor class

There are a couple of changes in this class to handle the employment-prediction scenario, as follows:

  1. The first change is in the prediction call itself. As you probably guessed, the TSrc and TDst arguments need to be adjusted to utilize both of the new classes we created, CarInventory and CarInventoryPrediction, like this:
var predictionEngine = MlContext.Model.CreatePredictionEngine<CarInventory, CarInventoryPrediction>(mlModel);            
  1. Given that we are no longer simply passing in the string and building an object on the fly, we need to first read in the file as text. We then deserialize the JSON into our CarInventory object, as follows:
var prediction = 
predictionEngine.Predict(JsonConvert.DeserializeObject<CarInventory>
(json));
  1. Lastly, we need to adjust the output of our prediction to match our new CarInventoryPrediction properties, like this:
Console.WriteLine(
$"Based on input json:
{System.Environment.NewLine}" +
$"{json}{System.Environment.NewLine}" +
$"The car price is a
{(prediction.PredictedLabel ? "good" : "bad")} deal,
with a {prediction.Probability:P0} confidence");

The Trainer class

Inside the Trainer class, several modifications need to be made to support binary classification, as follows:

  1. The first change is the check to ensure the test filename exists, shown in the following code block:
if (!File.Exists(testFileName))
{
Console.WriteLine($"Failed to find test data file
({testFileName}");

return;
}
  1. We then build the data process pipeline using the NormalizeMeanVariance transform method we used in Chapter 3, Regression Model, on the inputted values, like this:
IEstimator<ITransformer> dataProcessPipeline =
MlContext.Transforms.Concatenate("Features",
typeof(CarInventory).ToPropertyList<CarInventory>
(nameof(CarInventory.Label)))
.Append(MlContext.Transforms.NormalizeMeanVariance(inputColumnName: "Features", outputColumnName: "FeaturesNormalizedByMeanVar"));
  1. We can then create the FastTree trainer with the label from the CarInventory class and the normalized mean variance, as follows:
var trainer = MlContext.BinaryClassification.Trainers.FastTree(
labelColumnName: nameof(CarInventory.Label),
featureColumnName: "FeaturesNormalizedByMeanVar",
numberOfLeaves: 2,
numberOfTrees: 1000,
minimumExampleCountPerLeaf: 1,
learningRate: 0.2);
Later on, after you have run the application, consider tweaking the number of leaves and the number of trees to see how both the model metrics and your prediction probability percentage change.
  1. Lastly, we call the Regression.Evaluate method to provide regression-specific metrics, followed by a Console.WriteLine call to provide these metrics to your console output. We will go into detail about what each of these means in the last section of the chapter, but for now, the code can be seen here:
var trainingPipeline = dataProcessPipeline.Append(trainer);

var trainedModel = trainingPipeline.Fit(trainingDataView);

MlContext.Model.Save(trainedModel, trainingDataView.Schema, ModelPath);

Now, we evaluate the model we just trained, like this:

var evaluationPipeline = trainedModel.Append(MlContext.Transforms
.CalculateFeatureContribution(trainedModel.LastTransformer)
.Fit(dataProcessPipeline.Fit(trainingDataView).Transform(trainingDataView)));

var testDataView = MlContext.Data.LoadFromTextFile<CarInventory>(testFileName, ',', hasHeader: false);

var testSetTransform = evaluationPipeline.Transform(testDataView);

var modelMetrics = MlContext.BinaryClassification.Evaluate(data: testSetTransform,
labelColumnName: nameof(CarInventory.Label),
scoreColumnName: "Score");

Finally, we output all of the classification metrics. We will detail each of these in the next section, but for now, the code can be seen here:

Console.WriteLine($"Accuracy: {modelMetrics.Accuracy:P2}");
Console.WriteLine($"Area Under Curve: {modelMetrics.AreaUnderRocCurve:P2}");
Console.WriteLine($"Area under Precision recall Curve: {modelMetrics.AreaUnderPrecisionRecallCurve:P2}");
Console.WriteLine($"F1Score: {modelMetrics.F1Score:P2}");
Console.WriteLine($"LogLoss: {modelMetrics.LogLoss:#.##}");
Console.WriteLine($"LogLossReduction: {modelMetrics.LogLossReduction:#.##}");
Console.WriteLine($"PositivePrecision: {modelMetrics.PositivePrecision:#.##}");
Console.WriteLine($"PositiveRecall: {modelMetrics.PositiveRecall:#.##}");
Console.WriteLine($"NegativePrecision: {modelMetrics.NegativePrecision:#.##}");
Console.WriteLine($"NegativeRecall: {modelMetrics.NegativeRecall:P2}");

The Program class

The only change in the Program class is the help text to indicate usage for the trainer to accept the test file, shown in the following code block:

if (args.Length < 2)
{
Console.WriteLine(
$"Invalid arguments passed in, exiting.{Environment.NewLine}
{Environment.NewLine}Usage:{Environment.NewLine}" +
$"predict <path to input json file>{Environment.NewLine}" +
$"or {Environment.NewLine}" +
$"train <path to training data file><path to test data file>
{Environment.NewLine}");

return;
}

Finally, we modify the switch/case statement to support the additional parameter to the Train method, as follows:

switch (args[0])
{
case "predict":
new Predictor().Predict(args[1]);
break;
case "train":
new Trainer().Train(args[1], args[2]);
break;
default:
Console.WriteLine($"{args[0]} is an invalid option");
break;
}

Running the application

To run the application, the process is nearly identical to the sample application in Chapter 3, Regression Model, with the addition of passing in the test dataset when training, described as follows:

  1. To run the training on the command line, as we did in Chapter 1, Getting Started with Machine Learning and ML.NET, we simply pass in the following command (assuming you are using the included sample dataset and test dataset):
PS chapter04\bin\Debug\netcoreapp3.0> .\chapter04.exe train ..\..\..\Data\sampledata.csv ..\..\..\Data\testdata.csv
Accuracy: 88.89%
Area Under Curve: 100.00%
Area under Precision recall Curve: 100.00%
F1Score: 87.50%
LogLoss: 2.19
LogLossReduction: -1.19
PositivePrecision: 1
PositiveRecall: .78
NegativePrecision: .82
NegativeRecall: 100.00%

Note the expanded output to include several metric data points—we will go through what each one of these means at the end of this chapter.

  1. After training the model, build a sample JSON file and save it as input.json, as follows:
{
"HasSunroof":0,
"HasAC":0,
"HasAutomaticTransmission":0,
"Amount":1300
}
  1. To run the model with this file, simply pass in the filename to the built application, and the predicted output will appear, as follows:
PS chapter04\bin\Debug\netcoreapp3.0> .\chapter04.exe predict .\input.json
Based on input json:
{
"HasSunroof":0,"HasAC":0,"HasAutomaticTransmission":0,"Amount":1300
}
The car price is a good deal, with a 100% confidence

Feel free to modify the values and see how the prediction changes based on the dataset on which the model was trained. A few areas of experimentation from this point might be as follows:

  • Add some additional features based on your own car-buying experiences
  • Modify the sampledata.csv file to include your own car-buying experiences
  • Modify the sample application to have a graphical user interface (GUI) to make running predictions easier

Creating a multi-class classification application

As mentioned earlier, we will now create a multi-class classification application, categorizing email into one of three categories:

  • Orders
  • Spam
  • Friend

Flushing out this example for a production application would more than likely include significantly more categories in addition to more features. However, this is a good starting point to demonstrate a multi-class classification use case.

As with other examples, the complete project code, sample dataset, and project files can be downloaded here: https://github.com/PacktPublishing/Hands-On-Machine-Learning-With-ML.NET/tree/master/chapter04-multiclass.

Diving into the trainer

As previously mentioned, for this multi-class classification application we will be using the SdcaMaximumEntropy trainer.   

The SdcaMaximumEntropy class, as the name implies, is based on the SDCA we deep dove into in Chapter 3Regression Modeland uses empirical risk minimization, which optimizes based on the training data. This does leave a potential for outliers or anomalies to greatly affect the predict performance. Therefore, when using this trainer, provide the trainer with ample sampling of expected data, to avoid both overfitting and potential errors when predicting data.

The SdcaMaximumEntropy trainer, unlike the previous binary classification example, does require normalization. In addition, caching is not required; however, we do utilize caching when building the pipeline.

Exploring the project architecture

Building on the project architecture and code created earlier in this chapter, there are no new NuGet packages to include in this project, as SDCA trainers are considered core trainers. The major change is in the Training pipeline, which we will go into in further detail later on in this section. 

In the following screenshot, you will find the Visual Studio Solution Explorer view of the project:

The sampledata.csv file contains six rows of random data. Feel free to adjust the data to fit your own observations or to adjust the trained model. Here is a snippet of the data:

"Order #1234", "Thank you for ordering a new CPU", "order@cpulandia.com", "orders"
"Get Free Free", "Click here for everything free", "freefree@asasdasd.com", "spam"
"Checking in", "How is it going?", "johndough@gmail.com", "friend"
"Order 4444", "Thank you for ordering a pizza", "order@pizzalandia.com", "orders"
"Unlock Free", "Click here to unlock your spam", "spammer@asasdasd.com", "spam"
"Hello", "Did you see my last message?", "janedough@gmail.com", "friend"

Each of these rows contains the value for the properties in the newly created Email class that we will review later on in this chapter.

In addition, in this chapter, we added the testdata.csv file that contains additional data points to test the newly trained model against. Here is a snippet of the data:

"Order 955", "Thank you for ordering a new gpu", "order@gpulandia.com", "orders"
"Win Free Money", "Lottery winner, click here", "nowfree@asasdasd.com", "spam"
"Yo", "Hey man?", "john@gmail.com", "friend"

Diving into the code

For this application, as noted earlier, we are building on top of the work completed in Chapter 3, Regression Model. For this deep dive, we are going to focus solely on the code that was changed for this application.

Classes that were changed or added are as follows:

  • Email
  • EmailPrediction
  • Predictor
  • Trainer
  • Program

The Email class

The Email class is the container class that contains the data to both predict and train our model. These columns map in order to the sample data reviewed previously. If you begin experimenting with new features and add to this list, ensure you increment the array index appropriately, as shown in the following code block:

using Microsoft.ML.Data;

namespace chapter04_multiclass.ML.Objects
{
public class Email
{
[LoadColumn(0)]
public string Subject { get; set; }

[LoadColumn(1)]
public string Body { get; set; }

[LoadColumn(2)]
public string Sender { get; set; }

[LoadColumn(3)]
public string Category { get; set; }
}
}

The EmailPrediction class

The EmailPrediction class contains the property mapped to our prediction output used for model evaluation. In the following code block, we are returning the Category value (string value):

using Microsoft.ML.Data;

namespace chapter04_multiclass.ML.Objects
{
public class EmalPrediction
{
[ColumnName("PredictedLabel")]
public string Category;
}
}

The Predictor class

There are a couple of changes in this class to handle the email categorization prediction scenario, as follows:

  1. The first change is in the prediction call itself. As you probably guessed, the TSrc and TDst arguments need to be adjusted to utilize both of the new classes we created, Email and EmailPrediction, as follows:
var predictionEngine = MlContext.Model.CreatePredictionEngine<Email, EmailPrediction>(mlModel);            
  1. Given that we are no longer simply passing in the string and building an object on the fly, we need to first read in the file as text. We then deserialize the JSON into our Email object, like this:
var prediction = predictionEngine.Predict(JsonConvert.DeserializeObject<Email>(json));
  1. Lastly, we need to adjust the output of our prediction to match our new EmailPrediction properties, as follows:
Console.WriteLine(
$"Based on input json:{System.Environment.NewLine}" +
$"{json}{System.Environment.NewLine}" +
$"The email is predicted to be a {prediction.Category}");

The Trainer class

There are a couple of changes in this class to handle the email categorization prediction scenario, as follows:

  1. First, we read in the trainingFileName string and typecast it to an Email object, like this:
var trainingDataView = MlContext.Data.LoadFromTextFile<Email>(trainingFileName, ',', hasHeader: false);           
  1. Next, we will create our pipeline mapping our input properties to FeaturizeText transformations before appending our SDCA trainer, as follows:
var dataProcessPipeline = MlContext.Transforms.Conversion.MapValueToKey(inputColumnName: nameof(Email.Category), outputColumnName: "Label")
.Append(MlContext.Transforms.Text.FeaturizeText(inputColumnName: nameof(Email.Subject), outputColumnName: "SubjectFeaturized"))
.Append(MlContext.Transforms.Text.FeaturizeText(inputColumnName: nameof(Email.Body), outputColumnName: "BodyFeaturized"))
.Append(MlContext.Transforms.Text.FeaturizeText(inputColumnName: nameof(Email.Sender), outputColumnName: "SenderFeaturized"))
.Append(MlContext.Transforms.Concatenate("Features", "SubjectFeaturized", "BodyFeaturized", "SenderFeaturized"))
.AppendCacheCheckpoint(MlContext);

var trainingPipeline = dataProcessPipeline
.Append(MlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy("Label", "Features"))
.Append(MlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
  1. Lastly, we load in our test data, run the MultiClassClassification evaluation, and then output the four model evaluation properties, like this:
var testDataView = MlContext.Data.LoadFromTextFile<Email>(testFileName, ',', hasHeader: false);

var modelMetrics = MlContext.MulticlassClassification.Evaluate(trainedModel.Transform(testDataView));

Console.WriteLine($"MicroAccuracy: {modelMetrics.MicroAccuracy:0.###}");
Console.WriteLine($"MacroAccuracy: {modelMetrics.MacroAccuracy:0.###}");
Console.WriteLine($"LogLoss: {modelMetrics.LogLoss:#.###}");
Console.WriteLine($"LogLossReduction: {modelMetrics.LogLossReduction:#.###}");

Running the application

To run the application, the process is nearly identical to the sample application in Chapter 3, Regression Model, with the addition of passing in the test dataset when training:

  1. To run the training on the command line as we did in Chapter 1, Getting Started with Machine Learning and ML.NET, simply pass in the following command (assuming you are using the included sample dataset and test dataset):
PS chapter04-multiclass\bin\Debug\netcoreapp3.0> .\chapter04-multiclass.exe train ..\..\..\Data\sampledata.csv ..\..\..\Data\testdata.csv
MicroAccuracy: 1
MacroAccuracy: 1
LogLoss: .1
LogLossReduction: .856

Note the expanded output to include several metric data points—we will go through what each one of these means at the end of this chapter.

  1. After training the model, build a sample JSON file and save it as input.json, as follows:
{
"Subject":"hello",
"Body":"how is it?",
"Sender":"joe@gmail.com"
}
  1. To run the model with this file, simply pass in the filename to the built application, and the predicted output will show, as follows:
PS chapter04-multiclass\bin\Debug\netcoreapp3.0> .\chapter04-multiclass.exe predict .\input.json
Based on input json:
{
"Subject":"hello",
"Body":"how is it?",
"Sender":"joe@gmail.com"
}
The email is predicted to be a "friend"

Feel free to modify the values and see how the prediction changes based on the dataset on which the model was trained. A few areas of experimentation from this point might be to:

  • Add more sample and test data based on your own emails.
  • Add more categories based on your own emails.
  • Expand the features, such as the date of sending, and the IP address of the sender.

Evaluating a classification model

As discussed in previous chapters, evaluating a model is a critical part of the overall model-building process. A poorly trained model will only provide inaccurate predictions. Fortunately, ML.NET provides many popular attributes to calculate model accuracy, based on a test set at the time of training, to give you an idea of how well your model will perform in a production environment. 

In ML.NET, as noted earlier in the sample applications, there are several properties that comprise the CalibratedBinaryClassificationMetrics class object. In Chapter 2, Setting Up the ML.NET Environment, we reviewed some of these properties. However, now that we have a more complex example and have learned how to evaluate regression models, let us dive into the following properties:

  • Accuracy
  • Area Under ROC Curve
  • F1 Score
  • Area Under Precision-Recall Curve

In addition, we will also look at the following four metrics returned by the MulticlassClassificationMetrics object used in the multi-class classification application:

  • Micro Accuracy
  • Macro Accuracy
  • Log Loss
  • Log-Loss Reduction

In the next sections, we will break down how these values are calculated, and detail the ideal values to look for.

Accuracy

Accuracy is the proportion of correct predictions to incorrect predictions in the test dataset.

You will want to be as close to a value of 100%, but not exactly 100%. As seen in our binary classification example, we received 88.89%—close to 100%, but not quite. If you see a 100% score when experimenting, you are more than likely seeing a case of overfitting.

Area Under ROC Curve

Area Under ROC Curve, also commonly referred to as AUC, is the measurement of the area under the curve.

As with Accuracy, a value close to 100% is ideal. If you are seeing values of less than 50%, your model either needs more features and/or more training data.

F1 Score

F1 Score is the harmonic mean of both precision and recall.

A value close to or equal to 100% is preferred. A value of 0 indicates your precision is completely inaccurate. As shown in our binary classification example, we received 87.50%.

Area Under Precision-Recall Curve

Area Under Precision-Recall Curve, also commonly referred to as AUPRC, is the measure of successful prediction. This value should be inspected when your dataset is imbalanced into one classification.

As with AUC and Accuracy, a value close to 100% is preferred, as this indicates you have a high recall. As shown in our binary classification example, we received a 100% AUPRC value. 

Micro Accuracy

Micro Accuracy evaluates if every sample-class pair contributes equally to the accuracy metric.

A value close to or equal to 1 is preferred. As shown in our example application with the sample and test datasets, a value of 1 was achieved.

Macro Accuracy

Macro Accuracy evaluates if every class pair contributes equally to the accuracy metric.

A value close to or equal to 1 is preferred. As shown in our example application with the sample and test datasets, a value of 1 was achieved.

Log Loss

Log Loss is an evaluation metric describing the accuracy of the classifier. Log Loss takes into account the difference between the model's prediction and the actual classification.

A value close to 0 is preferred, as a value of 0 indicates the model's prediction on the test set is perfect. As shown in our example application with the sample and test datasets, a value of .1 was achieved.

Log-Loss Reduction

Log-Loss Reduction is simply an evaluation metric describing the accuracy of the classifier as compared to a random prediction.

A value close to or equal to 1 is preferred, as the model's relative accuracy improves as the value approaches 1. As shown in our example application with the sample and test datasets, a value of .856 was achieved, meaning the probability of guessing the correct answer is 85.6%.

Summary

Over the course of this chapter, we have deep-dived into classification models. We have also created and trained our first binary classification application, using FastTree and ML.NET, to predict how good a car's price is. We also created our first multi-class classification application using an SDCA trainer to categorize emails. Lastly, we also dove into how to evaluate a classification model and the various properties that ML.NET exposes to achieve a proper evaluation of your classification models.

In the next chapter, we will deep dive into clustering algorithms with ML.NET and creating a file-type classifier.