What Will I Learn?
You will learn how to leverage a decision tree using your data sets and C#
Requirements
nuML https://github.com/NuML/NuML
Difficulty
Intermediate
Tutorial Contents
- What's a Decision Tree?
- Getting Started
- Data Gathering
- Training
- Predictions
Using nuML Decision Trees to Predict Outcomes
What's a Decision Tree?
Wikipedia defines decision trees as:
A decision tree is a decision support tool that uses a tree-like graph or model of decisions and their possible consequences, including chance event outcomes, resource costs, and utility. It is one way to display an algorithm. Decision trees are commonly used in operations research, specifically in decision analysis, to help identify a strategy most likely to reach a goal.
A decision tree is essentially a big if-else tree. A visual makes it a lot easier to understand.To get more examples, visit the wikipedia page. The point of this tutorial is to show you how to leverage a decision tree using your data sets and C#.
Getting Started
For this post, we will use a library on NuGet call nuML. You can install it by typing the following into your package manager console.
PM> Install-Package numl
You can also read the documentation here
Step 1 : Data Gathering
Decision trees have to be first trained with existing data, and this usually comes in tabular form. The particular library we are using supports plain old C# objects (POCOS), so it makes it very easy to turn existing objects into decision trees. In this particular example, we will create a decision tree to help predict whether we will play tennis or choose to hold off play for another day.
Let's look at what a class looks like:
public class Tennis
{
[Feature]
public Outlook Outlook { get; set; }
[Feature]
public Temperature Temperature { get; set; }
[Feature]
public bool Windy { get; set; }
[Label]
public bool Play { get; set; }
public override string ToString()
{
return string.Format("The result is {0}", Play);
}
}
public enum Outlook
{
Sunny,
Overcast,
Rainy
}
public enum Temperature
{
Low,
High
}
Notice the attributes on our class. A Feature is a property in our dataset that could determine the outcome, and the Label attribute defines what our outcome is.Next let's just create some arbitrary data to train our model.
public static Tennis[] GetData()
{
return new Tennis[] {
new Tennis { Play = true, Outlook=Outlook.Sunny, Temperature = Temperature.Low, Windy=true},
new Tennis { Play = false, Outlook=Outlook.Sunny, Temperature = Temperature.High, Windy=true},
new Tennis { Play = false, Outlook=Outlook.Sunny, Temperature = Temperature.High, Windy=false},
new Tennis { Play = true, Outlook=Outlook.Overcast, Temperature = Temperature.Low, Windy=true},
new Tennis { Play = true, Outlook=Outlook.Overcast, Temperature = Temperature.High, Windy= false},
new Tennis { Play = true, Outlook=Outlook.Overcast, Temperature = Temperature.Low, Windy=false},
new Tennis { Play = false, Outlook=Outlook.Rainy, Temperature = Temperature.Low, Windy=true},
new Tennis { Play = true, Outlook=Outlook.Rainy, Temperature = Temperature.Low, Windy=false}
};
}
Notice that our data already has outcomes, this is important in training our model. It needs to know prior outcomes to enable us to predict future ones.
Step 2 : Training
We need to pass the data found in step 1 into our decision tree generator. Decision Trees are derived mathematically, so if they might look a little goofy or arbitrary to an observer. The root node is derived to give the best possible accuracy.
Let's look at how we train our model.
var data = GetData();
var d = Descriptor.Create<Tennis>();
var g = new DecisionTreeGenerator(d);
g.SetHint(false);
var model = Learner.Learn(data, 0.80, 1000, g);
Console.WriteLine(model);
Console.ReadKey();
Some of the variables passed to learner are percentage of data to use (80%) and the amount of times to repeat the the data (1000). When we run this code we get this decision tree.
Our root node is Outlook. Each outlook is a branch (Sunny, Overcast, and Rainy), leading to the next node of either Temperature or Windy. We also know this model is 100% accurate at predicting play given our data. A fun thing to realize about our data is that we always play if it is overcast. Nothing else is a determining factor there.
So how do we use our decision tree to predict play?
Step 3: Predictions
We have trained our model. If we pass any object that looks like our training data, our Label will be set with the result. The great thing about a decision tree is you can follow the logic pretty easily and test these prediction scenarios.
var result = model.Model.Predict(new Tennis
{
Outlook = Outlook.Rainy,
Windy = true
});
Console.WriteLine(result);
Console.ReadKey();
The result here is going to be False. Since our decision tree says that if it is Rainy and Windy we don't play. Awesome right?!
Conclusion
Decision Trees shouldn't only be used for making predictions. Predictions are important, but the decision tree in itself is important as well. You can see why outcomes are happening. Take the example of online advertising for a startup. A decision tree can show you which of your advertising outlets are performing better and why. Knowing what features are causing certain outcomes could help you spend your advertising dollars more wisely. If you run on an online store, you can use a decision tree to determine where conversions are falling off and hopefully correct the issue. There is so much you can do with decision trees and I'm so happy that nuML is around to make it a lot easier for C# developers.
Posted on Utopian.io - Rewarding Open Source Contributors