Final AI Project

In this capstone you'll build one complete machine learning project end-to-end — loading data, training a model from scratch, evaluating it, and making predictions — so you finish able to ship real AI work.

Learn Final AI Project in our free AI & Machine Learning course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a…

Part of the free AI & Machine Learning course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

You'll build one project the whole way through : a classifier that decides whether a fruit is an apple or an orange from two numbers — its weight and how bumpy its skin is. It's deliberately tiny so the data fits on screen and you can check every number by hand. The workflow , though, is identical to a million-row production system.

The five milestones — the universal ML workflow:

All code below is plain Python — no numpy, no scikit-learn — so nothing is hidden. At the end you'll see the same project in scikit-learn to connect what you built to the tools the industry uses.

Every project starts by getting data into a shape you can work with and looking at it . Here the dataset is a list of dictionaries — one dict per fruit. Before modelling anything, you check how many samples there are and whether the classes are balanced. A lopsided dataset (say 95% apples) changes every decision that follows.

Run it and read the comments — the # Expected output at the bottom tells you exactly what you should see.

Models work on numbers, so first you encode the text labels (apple → 0, orange → 1). Then you scale the features to a 0-1 range — without this, weight (around 200) would completely drown out bumpiness (around 10) and the model would barely notice the bumpiness at all.

Finally you split the data: most rows train the model, a few are held back to test it. The golden rule of ML is that you never test on data the model trained on — that's like giving students the exam answers in advance.

A perceptron is the simplest learning unit there is — the great-grandparent of every neural network. It multiplies each feature by a weight , adds a bias , and fires 1 if the total is positive, else 0 .

"Training" just means: for each example, make a guess, and if it's wrong, nudge the weights a little in the direction that would have been right. Repeat over the whole dataset a few times (each pass is an epoch ) until it stops making mistakes. That single line — weights[i] += learning_rate * error * features[i] — is the entire learning algorithm.

A trained model is worthless until you know how good it is on data it has never seen . You run it on the held-out test set and count four outcomes into a confusion matrix :

From those four numbers you compute accuracy (overall correctness), precision (when it says orange, how often it's right), and recall (of all the real oranges, how many it caught).

This is the payoff: feeding the model fruit it has never seen and getting a label back. The one trick beginners miss is that new data must be scaled with exactly the same min/max you used in training — re-fitting the scaler on new data would shift everything and corrupt the predictions.

Notice the third fruit (160g, bumpiness 6) sits near the boundary — a great reminder that real models output a decision even when the answer is genuinely uncertain.

You just built every piece by hand. In a real job you'd reach for scikit-learn , which collapses all five milestones into a handful of lines. Read this and match each call to the milestone it replaces — MinMaxScaler is Milestone 2, Perceptron().fit() is Milestone 3, the metric functions are Milestone 4, and .predict() is Milestone 5.

Same result, a fraction of the code. The point of building it from scratch first is that none of this is a black box to you anymore — you know precisely what each line is doing.

You've built a perceptron. Now build the other classic classifier — k-Nearest Neighbours — by filling in two blanks. k-NN classifies a point by letting its closest labelled neighbours vote. Fill in the squared difference in the distance function and the majority threshold.

On imbalanced problems (fraud, disease, spam) accuracy is misleading and the F1 score rules. Finish the recall and F1 formulas below, then check your answer against the expected output.

Support has faded — only a comment outline remains. Combine Milestones 2, 3, and 5 into a single reusable FruitClassifier class with fit() and predict() methods. This mirrors exactly how scikit-learn estimators are structured.

These are the mistakes that quietly ruin ML projects. Spotting them is what separates a working model from a misleading one.

Evaluating on rows the model already saw gives a fake high score:

✅ Fix: always hold out a test set the model never trains on.

Re-fitting the scaler on new data shifts the numbers and breaks predictions:

✅ Fix: reuse the training set's min/max for every prediction.

With 98% legitimate transactions, predicting "always legitimate" scores 98% and catches zero fraud.

✅ Fix: report precision, recall, and F1 — not accuracy alone.

❌ Expecting a perceptron to learn non-linear data

A single perceptron can only draw one straight line. If two classes can't be split by a line, it will never converge.

✅ Fix: cap the epochs, or switch to k-NN or a multi-layer network for tangled data.

🪙 Business Opportunities You Can Build

📚 Structure Your ML Project

🧩 Start Small, Iterate

Begin with a baseline model (logistic regression or random forest), evaluate properly, then improve step by step. Track every experiment with MLflow.

🧪 Evaluate Thoroughly

Use appropriate metrics — F1 for imbalanced data, RMSE for regression, NDCG for rankings. Never rely on accuracy alone.

🌐 Deploy & Showcase

Course Complete — you built a full ML system end-to-end!

You loaded data, preprocessed and split it, trained a perceptron from scratch, evaluated it with a confusion matrix, predicted on unseen fruit, and connected all of it to scikit-learn. That five-step loop — load, preprocess, train, evaluate, predict — is the backbone of every machine learning project, from spam filters to self-driving cars.

🏆 Congratulations — you've completed the entire AI & Machine Learning course. From your first linear regression to LLMs, computer vision, reinforcement learning, and production MLOps, you've mastered the full AI engineering stack. Now go build something real.

Practice quiz

What are the five milestones of the ML workflow in this project?

  • Load, preprocess, train, evaluate, predict
  • Import, compile, run, debug, deploy
  • Collect, label, encrypt, store, delete
  • Plan, design, build, test, ship

Answer: Load, preprocess, train, evaluate, predict. The universal ML workflow is: load and inspect, preprocess and split, train, evaluate, then predict.

Why do you split data into train and test sets?

  • To make training faster
  • To evaluate the model on data it has never seen
  • To double the dataset size
  • To balance the classes

Answer: To evaluate the model on data it has never seen. You hold out a test set so you can measure performance on unseen data — never test on rows the model trained on.

Why scale features before training the perceptron?

  • So a large-valued feature doesn't drown out a small-valued one
  • To convert text into numbers
  • To remove the bias term
  • Scaling is never needed

Answer: So a large-valued feature doesn't drown out a small-valued one. Without scaling, weight (~200) would dwarf bumpiness (~10), so min-max normalisation puts them on equal footing.

When fitting a scaler, what is the correct practice?

  • Fit it on the whole dataset including test
  • Fit it on training data only, then reuse those min/max on test and new data
  • Re-fit a new scaler for every prediction
  • Never reuse the scaler

Answer: Fit it on training data only, then reuse those min/max on test and new data. Fit the scaler on training data only and reuse those same min/max values on test and new data to avoid leakage.

How does a perceptron make a prediction?

  • It stores all data and votes among nearest neighbours
  • It multiplies features by weights, adds a bias, and fires 1 if the total is positive
  • It averages all training labels
  • It picks a random class

Answer: It multiplies features by weights, adds a bias, and fires 1 if the total is positive. A perceptron computes a weighted sum plus bias and applies a step activation: 1 if positive, else 0.

What is the perceptron update rule doing when it makes a mistake?

  • Nudging the weights toward the correct answer
  • Resetting all weights to zero
  • Removing the misclassified sample
  • Increasing the learning rate

Answer: Nudging the weights toward the correct answer. On an error it adjusts each weight by learning_rate * error * feature, moving toward the right answer.

In a confusion matrix, what is a false negative (FN)?

  • Predicted positive, actually positive
  • Predicted positive, actually negative
  • Predicted negative, actually positive — a miss
  • Predicted negative, actually negative

Answer: Predicted negative, actually positive — a miss. A false negative is predicting negative when the truth is positive — for example missing an actual orange.

What does recall measure?

  • Of all flagged items, how many were truly positive
  • Of all real positives, how many the model caught
  • Overall correctness across both classes
  • The model's training time

Answer: Of all real positives, how many the model caught. Recall = TP / (TP + FN): of all real positives, the fraction the model correctly identified.

Why isn't accuracy enough on imbalanced data?

  • Accuracy is impossible to compute
  • A model can score high by always predicting the majority class while missing the rare class
  • Accuracy only works for regression
  • Accuracy ignores the training set

Answer: A model can score high by always predicting the majority class while missing the rare class. With 98% legitimate transactions, always predicting 'legitimate' scores 98% but catches zero fraud — F1 exposes this.

How does k-nearest neighbours (k-NN) classify a new point?

  • By learning a single straight decision boundary during training
  • By voting among the closest stored labelled points at prediction time
  • By averaging all feature values
  • By adding Gaussian noise

Answer: By voting among the closest stored labelled points at prediction time. k-NN learns nothing up front; at prediction time it finds the closest stored points and takes a majority vote.