
NOTE: We started with this example:
Predictive AI becomes much easier to understand when you stop talking about algorithms in the abstract and start experimenting with real data.
That is the idea behind a new hands-on ML.NET Predictive AI exercise I have published on GitHub.
The exercise starts with a straightforward business problem:
Given what we know about a taxi trip, how accurately can we predict the fare?
But the real objective is not taxi fares.
The objective is to demonstrate something much more important:
What actually improves a predictive model?
Is it:
- choosing a more sophisticated algorithm?
- cleaning the data?
- adding better features?
- understanding the business context?
- or some combination of all four?
Instead of building one model and stopping when it produces a respectable score, this exercise runs a series of controlled experiments so you can see the effect of each decision.
The results are surprisingly instructive.
The Starting Point: A Simple ML.NET Regression Model
Taxi fare prediction is a regression problem because we are predicting a continuous numerical value: the fare amount.
The dataset contains more than one million taxi trips:
1,048,575 rows
The initial ML.NET model uses several basic features:
- Passenger Count
- Trip Time
- Trip Distance
- Payment Type
The first model uses ML.NET’s FastTree regression trainer.
The result:
| Metric | Baseline Result |
|---|---|
| R-Squared | 0.8862 |
| MAE | 0.6191 |
| RMSE | 3.2357 |
| MSE | 10.4698 |
An R-Squared of 0.8862 initially looks pretty good.
The model explains approximately 88.6% of the variance in taxi fares.
The Mean Absolute Error is also only about $0.62.
If we stopped there, it would be easy to conclude:
The model works.
But that would miss one of the most important lessons in Predictive AI.
Ah-Hah #1: Model Metrics Do Not Tell the Whole Story
Instead of looking only at aggregate metrics, the application also prints the 20 worst predictions.
That immediately exposes some dramatic failures.
Examples from the baseline model included:
| Actual Fare | Predicted Fare | Error |
| $320.00 | $53.95 | $266.05 |
| $275.00 | $43.98 | $231.02 |
| $297.00 | $74.24 | $222.76 |
| $270.00 | $54.08 | $215.92 |
Suddenly the model does not look quite as impressive.
How can a model with an average absolute error of only $0.62 miss an individual fare by more than $250?
The answer is in the difference between metrics such as MAE and RMSE.
MAE tells us about the typical absolute error.
RMSE penalizes large errors much more heavily.
When MAE is relatively low but RMSE is substantially higher, that can be a clue that the model performs well for most observations but has a smaller population of very large errors.
That leads directly to the next question:
Why is the model getting those trips so wrong?
Ah-Hah #2: Look at the Data Before Blaming the Algorithm
The next step is not to immediately replace FastTree.
It is to examine the data.
The dataset profile reveals:
| Data Quality Check | Count |
| Total rows | 1,048,575 |
| Zero-distance trips | 5,719 |
| Zero-time trips | 2,385 |
| Zero distance AND zero time | 1,669 |
| Fares over $100 | 339 |
| Fares over $100 with zero distance | 128 |
The fare distribution is equally revealing:
| Statistic | Fare |
| Minimum | $2.50 |
| Median | $9.00 |
| 95th Percentile | $30.00 |
| 99th Percentile | $52.00 |
| Maximum | $425.00 |
Most taxi fares are relatively small.
Only 339 out of more than one million records have fares greater than $100.
Some of those extreme fares also have questionable measurements such as zero distance or zero trip time.
For example, one of the worst baseline predictions involved a recorded fare of $320 for a trip with:
- 0 miles
- 62 seconds
- 1 passenger
The problem may not be that the machine-learning algorithm is incapable of predicting the fare.
The problem may be that the inputs do not adequately explain the fare.
That distinction matters.
Ah-Hah #3: The Model Cannot Learn From Information You Do Not Give It
The baseline model intentionally uses only a subset of the available information.
The next experiment adds two additional features:
- Vendor ID
- Rate Code
The model now uses:
- Passenger Count
- Trip Time
- Trip Distance
- Payment Type
- Vendor ID
- Rate Code
Nothing else changes.
The dataset remains unchanged.
The FastTree algorithm remains unchanged.
The results improve dramatically.
| Metric | Basic Features | Full Features |
| R-Squared | 0.8862 | 0.9479 |
| MAE | 0.6191 | 0.4334 |
| RMSE | 3.2357 | 2.1896 |
| MSE | 10.4698 | 4.7943 |
Simply supplying additional business context raises R-Squared from 0.8862 to 0.9479.
That is a major improvement without changing the machine-learning algorithm.
This demonstrates an important Predictive AI principle:
A model cannot discover relationships based on information it never receives.
Feature engineering is not just a mathematical exercise.
It is often where business knowledge enters the model.
Ah-Hah #4: Data Cleaning Matters Too
Next, we return to the original basic feature set but clean the dataset.
The cleaning rule in this exercise is deliberately simple.
Rows are removed when:
- Trip Distance is zero or negative
- Trip Time is zero or negative
- Fare Amount is zero or negative
Out of 1,048,575 original observations, only 6,435 are removed.
That is just:
0.61% of the dataset
The remaining dataset contains:
1,042,140 rows
Now we run FastTree again with the original basic feature set.
The result:
| Metric | Original Data | Clean Data |
| R-Squared | 0.8862 | 0.9207 |
| MAE | 0.6191 | 0.5164 |
| RMSE | 3.2357 | 2.6246 |
| MSE | 10.4698 | 6.8885 |
Removing less than 1% of the data creates a meaningful improvement.
Again, the algorithm did not change.
The feature set did not change.
Only the quality of the input data changed.
Ah-Hah #5: Better Data and Better Features Reinforce Each Other
Now we combine both improvements:
- cleaned data
- full feature set
- same FastTree algorithm
The model improves again.
| Metric | Baseline | Clean + Full Features |
| R-Squared | 0.8862 | 0.9678 |
| MAE | 0.6191 | 0.3863 |
| RMSE | 3.2357 | 1.6717 |
| MSE | 10.4698 | 2.7945 |
This is one of the most important results in the entire exercise.
We went from:
R² = 0.8862
to:
R² = 0.9678
without replacing FastTree.
The biggest improvement did not come from finding a more exotic algorithm.
It came from understanding the data and supplying better information to the model.
Now We Can Fairly Compare Machine-Learning Algorithms
Only after improving the data and features do we start experimenting with different algorithms.
The exercise compares three ML.NET regression trainers:
- FastTree
- LightGBM
- FastForest
All three models receive the same cleaned data and the same full feature set.
This makes the comparison meaningful.
The results:
| Algorithm | R-Squared | MAE | RMSE | MSE |
| FastTree | 0.9678 | 0.3863 | 1.6717 | 2.7945 |
| LightGBM | 0.9684 | 0.3690 | 1.6573 | 2.7466 |
| FastForest | 0.9174 | 1.2113 | 2.6776 | 7.1697 |
LightGBM produces the best overall result.
But notice the size of the improvement.
FastTree:
R² = 0.9678
LightGBM:
R² = 0.9684
That is an improvement, but it is small.
Compare that with the improvement from better features:
0.8862 → 0.9479
Or the combination of better data and features:
0.8862 → 0.9678
This gives us another important lesson:
Model selection matters, but it may matter much less than data quality and feature engineering.
FastForest also provides another useful lesson.
It performs substantially worse than both FastTree and LightGBM.
A different algorithm is not automatically a better algorithm.
The Six Controlled Experiments
The source code runs all six experiments automatically.
| Run | Data | Features | Algorithm | R-Squared | MAE | RMSE |
| A | Original | Basic | FastTree | 0.8862 | 0.6191 | 3.2357 |
| B | Original | Full | FastTree | 0.9479 | 0.4334 | 2.1896 |
| C | Clean | Basic | FastTree | 0.9207 | 0.5164 | 2.6246 |
| D | Clean | Full | FastTree | 0.9678 | 0.3863 | 1.6717 |
| E | Clean | Full | LightGBM | 0.9684 | 0.3690 | 1.6573 |
| F | Clean | Full | FastForest | 0.9174 | 1.2113 | 2.6776 |
The experiment is deliberately structured so that related runs reuse the same training/test split.
That matters.
If we changed the data sample, features, and algorithm simultaneously, we would not know which change produced the improvement.
Controlled experiments let us isolate the effect of each decision.
This Is What Practical Predictive AI Looks Like
Machine learning is sometimes presented as:
- Find a dataset.
- Pick an algorithm.
- Train a model.
- Look at the accuracy.
- Done.
Real Predictive AI is much more iterative.
A better workflow looks like this:
Understand the business problem
↓
Understand the available data
↓
Establish a baseline model
↓
Measure performance
↓
Inspect the failures
↓
Investigate the data
↓
Improve data quality
↓
Improve the features
↓
Compare algorithms
↓
Tune the strongest candidates
↓
Continue monitoring real-world performance
The model is only one part of the system.
Why This Exercise Is Useful for .NET Developers
One reason I like ML.NET is that it gives experienced .NET developers a practical way to start working with machine learning without abandoning the Microsoft development environment they already know.
The project is a standard C# console application.
The core technologies are:
- C#
- .NET 10
- ML.NET 5
- Visual Studio
- FastTree
- LightGBM
- FastForest
There is no separate Python application to deploy.
There is no requirement to move the entire application architecture into a different programming ecosystem.
A .NET developer can:
- load data
- define features
- train models
- evaluate predictions
- save models
- load models
- integrate predictions into existing .NET applications
using familiar C# code.
That makes ML.NET particularly useful for experimenting with Predictive AI inside organizations already standardized on Microsoft technologies.
Try the ML.NET Taxi Fare Prediction Exercise Yourself
I published the complete source code on GitHub:
GitHub Repository:
https://github.com/AI-n-DotNet/AInDotNet.MLNET.TaxiFare
The repository includes:
- complete C# source code
- Visual Studio solution
- dataset setup instructions
- data profiling
- train/test splitting
- six controlled experiments
- FastTree regression
- LightGBM regression
- FastForest regression
- R-Squared evaluation
- MAE, RMSE, and MSE
- worst-prediction analysis
- reproducible random seeds
- experiment questions
- additional exercises to try yourself
Homework: Don’t Just Run the Code
The most valuable way to use this exercise is not to simply clone the repository, press F5, and look at the final numbers.
Change something.
Form a hypothesis first.
Then test it.
For example:
Remove Individual Features
What happens if you remove:
- Rate Code?
- Vendor ID?
- Trip Time?
- Passenger Count?
Which variables actually matter?
Try Different Cleaning Rules
What should you do with records such as:
- $2.50 fare for a 55-mile trip?
- $35 fare for a 76-mile trip?
- very short trips with extremely high fares?
Are they:
- bad data?
- legitimate exceptions?
- special rate structures?
- evidence of missing features?
There is no value in blindly deleting data simply because it looks unusual.
The business context matters.
Try Additional Algorithms
Add another ML.NET regression trainer.
Keep the training and testing data identical.
Then compare:
- R-Squared
- MAE
- RMSE
- worst predictions
- training time
Does the new algorithm actually improve the model?
Tune the Models
The current exercise largely uses default trainer parameters.
Experiment with:
- number of trees
- number of leaves
- learning rate
- minimum samples per leaf
- tree depth
How much additional improvement can you achieve?
And perhaps more importantly:
Is the additional complexity worth it?
The Bigger Lesson: Predictive AI Is About Experimentation
The taxi-fare model itself is not particularly important.
The process is.
The exercise starts with:
R² = 0.8862
Then:
Better features → 0.9479
Then:
Better data + better features → 0.9678
Then:
Changing to LightGBM → 0.9684
That progression tells an important story.
The machine-learning algorithm mattered.
But understanding the data and providing the right business context mattered much more.
That is why successful Predictive AI projects need more than data scientists or machine-learning libraries.
They need people who understand:
- the business problem
- the data
- the process that generated the data
- what the variables actually mean
- which observations are legitimate
- what constitutes an unacceptable prediction
Machine learning can discover patterns.
But humans still have to define the problem worth solving and supply the context that makes those patterns meaningful.
Final Takeaway
If you are a .NET developer interested in Predictive AI, this is exactly the kind of exercise I recommend.
Do not begin by trying to memorize every ML.NET trainer.
Start with a real problem.
Build a baseline.
Measure it.
Look at what it gets wrong.
Ask why.
Improve the data.
Improve the features.
Then compare models.
In this experiment, that simple discipline improved R-Squared from:
0.8862 to 0.9684
The most important lesson was not that LightGBM won.
It was this:
Data first. Features second. Model tuning third.
That is a much better foundation for building real Predictive AI systems.
Download the Source Code
The complete exercise is available on GitHub:
ML.NET Taxi Fare Prediction Exercise
https://github.com/AI-n-DotNet/AInDotNet.MLNET.TaxiFare
Clone it, run the experiments, change the assumptions, and see what happens.
That is where the real learning starts.
Want more on Predictive AI?
Check out our hub webpage on Predictive AI
Frequently Asked Questions
What is ML.NET?
ML.NET is Microsoft’s machine-learning framework for .NET developers. It allows developers to build, train, evaluate, and consume machine-learning models directly in C# and other .NET languages.
For teams already using .NET, ML.NET makes it possible to add Predictive AI capabilities without requiring a separate Python-based application stack.
Is ML.NET still actively supported?
Yes. ML.NET is still actively maintained and continues to receive new releases.
The framework itself is current, even though some Visual Studio tooling such as Model Builder has lagged behind newer Visual Studio versions. Developers can use ML.NET directly through its NuGet packages and APIs without relying on Model Builder.
What type of machine-learning problem is taxi fare prediction?
Taxi fare prediction is a regression problem.
Regression is used when the value being predicted is numerical and continuous. In this exercise, the model predicts a dollar amount for the taxi fare based on characteristics such as trip distance, trip duration, payment type, rate code, vendor, and passenger count.
Other common regression problems include predicting:
- project cost
- sales amount
- delivery time
- energy usage
- insurance cost
- customer lifetime value
What is the difference between R-Squared, MAE, RMSE, and MSE?
These metrics measure different aspects of regression-model performance.
R-Squared measures how much of the variation in the target value is explained by the model. Values closer to 1.0 generally indicate a better fit.
MAE, or Mean Absolute Error, measures the average absolute difference between actual and predicted values. Because the target in this exercise is a fare amount, MAE can be interpreted directly in dollars.
RMSE, or Root Mean Squared Error, penalizes large prediction errors more heavily than MAE. It can reveal models that perform well most of the time but occasionally make very large mistakes.
MSE, or Mean Squared Error, is similar to RMSE but leaves the errors squared. RMSE is usually easier to interpret because it returns the error to the original units of the target variable.
Why did adding more features improve the model so much?
A machine-learning model can only learn relationships from the information it receives.
The baseline model used:
- passenger count
- trip time
- trip distance
- payment type
The expanded model also included:
- rate code
- vendor ID
Adding those features improved the FastTree model’s R-Squared from 0.8862 to 0.9479 without changing the algorithm or cleaning the data.
This demonstrates why feature engineering and business context are so important in Predictive AI. Important business rules may be represented in variables that initially appear secondary.
Why did removing only 0.61% of the data improve the model?
A small number of poor-quality or anomalous records can have a disproportionate effect on a predictive model.
In this exercise, the original dataset contained records with zero trip distance, zero trip time, and other questionable combinations.
The simple cleaning process removed only 6,435 rows out of 1,048,575, or approximately 0.61% of the dataset.
Even that small change improved the basic FastTree model’s R-Squared from 0.8862 to 0.9207.
The lesson is that data quality should be evaluated by its effect on the model, not simply by the percentage of rows affected.
Why did LightGBM only slightly outperform FastTree?
Once the data was cleaned and the full feature set was used, FastTree already performed very well:
FastTree R-Squared: 0.9678
LightGBM improved the result slightly:
LightGBM R-Squared: 0.9684
That small difference is important because it shows that algorithm selection may provide only incremental gains after the major data-quality and feature-engineering problems have already been addressed.
In this experiment, improving the data and features produced much larger gains than switching from FastTree to LightGBM.
Can I use this ML.NET example as a starting point for my own Predictive AI project?
Yes. That is one of the main purposes of the exercise.
The taxi-fare problem can be replaced with another regression problem by changing:
- the input data schema
- the target value
- the available features
- the cleaning rules
- the model trainers being tested
The same experimental pattern can be applied to many business problems:
- Establish a baseline.
- Measure model performance.
- Inspect the worst predictions.
- Investigate data quality.
- Improve the feature set.
- Compare algorithms.
- Tune the strongest model.
The complete source code is available in the AInDotNet.MLNET.TaxiFare GitHub repository.
