Comprehensive Machine Learning Tutorial: A Beginner’s Guide
Machine Learning Tutorial
Build your first Machine Learning model step by step using Python, pandas, Matplotlib, and scikit-learn.
Introduction
Machine Learning becomes easier to understand when theoretical concepts are connected to a complete practical example. In this tutorial, you will follow a beginner-friendly Machine Learning workflow from problem definition and data exploration to model training, evaluation, and prediction.
We will build a classification model using the Iris flower dataset. The model will learn from flower measurements and predict the species of a flower it has not previously seen.
The Iris dataset is available directly through scikit-learn, so you do not need to download a separate file. It contains numerical measurements describing flowers and a target identifying the corresponding flower species.
Learning Objectives
By the End of This Tutorial
- Understand the stages of a basic Machine Learning project
- Load a built-in dataset using scikit-learn
- Separate input features from the prediction target
- Inspect the structure and quality of a dataset
- Divide data into training and test sets
- Create and train a classification model
- Generate predictions for unseen data
- Evaluate a classifier using suitable metrics
- Use the trained model to classify a new flower
- Recognize common beginner mistakes
Prerequisites
This tutorial is intended for beginners. You do not need previous experience building Machine Learning models, but basic familiarity with Python will make the code easier to understand.
Recommended Knowledge
- Basic Python variables and data types
- Basic Python functions and method calls
- Basic understanding of lists and tabular data
- Awareness of features, targets, training, and prediction
- Basic understanding of classification
Required Environment
- Python 3 installed on your computer or access to Google Colab
- Jupyter Notebook, JupyterLab, Visual Studio Code, or another Python IDE
- pip for installing Python packages
- A virtual environment is recommended for local development
Required Python Libraries
This tutorial uses pandas for tabular data, Matplotlib for visualization, and scikit-learn for loading data, splitting the dataset, training the model, and calculating evaluation metrics.
| Library | Purpose |
|---|---|
| pandas | Stores, explores, and manipulates tabular data |
| Matplotlib | Creates charts and data visualizations |
| scikit-learn | Provides datasets, preprocessing tools, algorithms, and evaluation metrics |
Create a Virtual Environment
python -m venv .venv
Activate the virtual environment using the command appropriate for your operating system.
Windows
.venv\Scripts\activate
Linux or macOS
source .venv/bin/activate
Install the Libraries
pip install pandas matplotlib scikit-learn jupyter
Machine Learning Workflow
A Machine Learning project is not only a call to a training method. It is a sequence of connected activities that begins with a clearly defined problem and continues after the model has been created.
| Stage | Main Question |
|---|---|
| Problem Definition | What result should the model produce? |
| Data Collection | What historical examples are available? |
| Data Exploration | What does the dataset contain? |
| Data Preparation | What corrections or transformations are required? |
| Data Splitting | Which records will be used for training and evaluation? |
| Model Training | What algorithm will learn from the training data? |
| Evaluation | How well does the model perform on unseen data? |
| Prediction | How will the trained model process new observations? |
| Monitoring | Does the model continue to perform as expected? |
Understanding the Tutorial Problem
The objective is to predict the species of an Iris flower from four numerical measurements. Because the output is a category, this is a classification problem.
| Dataset Element | Role |
|---|---|
| Sepal length | Input feature |
| Sepal width | Input feature |
| Petal length | Input feature |
| Petal width | Input feature |
| Flower species | Target class |
Input
- Sepal length
- Sepal width
- Petal length
- Petal width
Output
- Iris setosa
- Iris versicolor
- Iris virginica
Import the Required Libraries
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import (
accuracy_score,
classification_report,
confusion_matrix,
ConfusionMatrixDisplay
)
| Import | Purpose |
|---|---|
pandas |
Creates and explores the tabular dataset |
matplotlib.pyplot |
Displays the confusion matrix visualization |
load_iris |
Loads the built-in Iris dataset |
train_test_split |
Separates data into training and test sets |
DecisionTreeClassifier |
Creates a decision-tree classification model |
accuracy_score |
Calculates the proportion of correct predictions |
classification_report |
Reports precision, recall, and F1 score by class |
confusion_matrix |
Counts actual and predicted class combinations |
Load the Dataset
iris = load_iris()
print(iris.DESCR)
The returned object contains the measurements, target identifiers, feature names, target names, and a description of the dataset.
print("Feature names:")
print(iris.feature_names)
print("\nTarget names:")
print(iris.target_names)
Convert the Data into a DataFrame
A pandas DataFrame provides a readable tabular structure and useful methods for inspecting rows, columns, data types, and missing values.
data = pd.DataFrame(
iris.data,
columns=iris.feature_names
)
data["target"] = iris.target
data["species"] = data["target"].map(
dict(enumerate(iris.target_names))
)
print(data.head())
What the Code Does
| Code | Explanation |
|---|---|
pd.DataFrame() |
Creates a table from the numerical feature data |
columns=iris.feature_names |
Assigns meaningful names to the feature columns |
data["target"] |
Adds the numerical target identifier |
data["species"] |
Adds a readable species name for exploration |
data.head() |
Displays the first few rows |
Explore the Dataset
Data exploration helps identify the number of observations, data types, value ranges, missing values, class distribution, and possible quality problems.
Check the Dataset Dimensions
print("Dataset shape:", data.shape)
The first value represents the number of rows, and the second value represents the number of columns in the DataFrame.
Inspect Column Information
data.info()
Review Descriptive Statistics
print(data.describe())
Descriptive statistics help summarize the count, mean, standard deviation, minimum, maximum, and percentile values of numerical columns.
Check Missing Values
print(data.isnull().sum())
Check Duplicate Rows
print("Duplicate rows:", data.duplicated().sum())
Inspect the Class Distribution
print(data["species"].value_counts())
Data-Quality Questions
- Are the required columns available?
- Do the columns contain the expected data types?
- Are any values missing?
- Are duplicate observations present?
- Are numerical values within reasonable ranges?
- Are all target classes represented?
- Is the class distribution highly imbalanced?
- Could any feature reveal the answer improperly?
Separate Features and Target
The feature matrix is conventionally represented by \(X\), while the target vector is represented by \(y\).
Each \(\mathbf{x}^{(i)}\) represents the features of one flower, while \(y^{(i)}\) represents its known species.
X = data[iris.feature_names]
y = data["target"]
print("Feature matrix shape:", X.shape)
print("Target vector shape:", y.shape)
| Variable | Contains | Role |
|---|---|---|
X |
Sepal and petal measurements | Input features |
y |
Numerical species identifiers | Prediction target |
Split the Dataset
The model needs one portion of the data for learning and another portion for evaluation. Evaluating the model on its training data does not provide a reliable measure of performance on unseen observations.
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.20,
random_state=42,
stratify=y
)
print("Training features:", X_train.shape)
print("Test features:", X_test.shape)
| Parameter | Purpose |
|---|---|
test_size=0.20 |
Allocates 20 percent of the observations to the test set |
random_state=42 |
Makes the random split reproducible |
stratify=y |
Helps preserve the class distribution in both sets |
Create the Model
This tutorial uses a Decision Tree Classifier. A decision tree learns a series of feature-based conditions that divide the data into increasingly specific groups.
model = DecisionTreeClassifier(
max_depth=3,
random_state=42
)
| Parameter | Meaning |
|---|---|
max_depth=3 |
Limits how deeply the tree can divide the data |
random_state=42 |
Makes applicable random behavior reproducible |
Limiting tree depth can make the model easier to inspect and may reduce the risk of learning overly specific patterns from the training data.
Train the Model
model.fit(X_train, y_train)
The fit() method trains the decision tree using the
training features and their known target classes.
DecisionTreeClassifier defines the model and
its settings. Calling fit() allows that model to learn
from the training data.
Generate Predictions
predictions = model.predict(X_test)
comparison = pd.DataFrame({
"actual": y_test.to_numpy(),
"predicted": predictions
})
comparison["actual_species"] = comparison["actual"].map(
dict(enumerate(iris.target_names))
)
comparison["predicted_species"] = comparison["predicted"].map(
dict(enumerate(iris.target_names))
)
print(comparison.head(10))
The predict() method applies the trained decision tree
to the unseen test examples. The comparison table makes it easier
to inspect actual and predicted classes.
In this expression, \(f\) represents the trained model, \(X_{\text{test}}\) represents the unseen test features, and \(\hat{y}\) represents the predicted classes.
Evaluate the Model
Model evaluation checks how well the classifier performs on data that was not used for training.
Accuracy
accuracy = accuracy_score(
y_test,
predictions
)
print(f"Accuracy: {accuracy:.2f}")
Accuracy measures the proportion of test observations that were classified correctly. It is easy to understand, but it should not be used alone when classes are imbalanced or when different kinds of mistakes have different consequences.
Classification Report
report = classification_report(
y_test,
predictions,
target_names=iris.target_names,
zero_division=0
)
print(report)
| Metric | Meaning |
|---|---|
| Precision | Of the observations predicted as a class, how many actually belong to that class |
| Recall | Of the observations that actually belong to a class, how many the model identified |
| F1 Score | A harmonic mean that balances precision and recall |
| Support | The number of actual test observations belonging to each class |
Confusion Matrix
matrix = confusion_matrix(
y_test,
predictions
)
display = ConfusionMatrixDisplay(
confusion_matrix=matrix,
display_labels=iris.target_names
)
display.plot()
plt.title("Iris Classification Confusion Matrix")
plt.show()
A confusion matrix shows how actual classes were distributed across predicted classes. Correct predictions appear on the main diagonal, while off-diagonal values represent classification errors.
Make a Prediction for a New Flower
Once the model has been trained and evaluated, it can classify a new flower from the same four measurements used during training.
new_flower = pd.DataFrame(
[[5.1, 3.5, 1.4, 0.2]],
columns=iris.feature_names
)
predicted_class = model.predict(new_flower)[0]
predicted_species = iris.target_names[predicted_class]
print("Predicted species:", predicted_species)
The new observation must contain the same features used during training, with the same meanings, units, names, and order expected by the model.
Inspect Class Probabilities
probabilities = model.predict_proba(
new_flower
)[0]
probability_table = pd.DataFrame({
"species": iris.target_names,
"probability": probabilities
})
print(probability_table)
Complete Working Code
The following code combines the major tutorial steps into one executable example.
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import (
accuracy_score,
classification_report,
confusion_matrix,
ConfusionMatrixDisplay
)
# Load the dataset
iris = load_iris()
# Create a readable DataFrame
data = pd.DataFrame(
iris.data,
columns=iris.feature_names
)
data["target"] = iris.target
data["species"] = data["target"].map(
dict(enumerate(iris.target_names))
)
# Inspect the data
print(data.head())
print("\nMissing values:")
print(data.isnull().sum())
print("\nClass distribution:")
print(data["species"].value_counts())
# Separate features and target
X = data[iris.feature_names]
y = data["target"]
# Create training and test sets
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.20,
random_state=42,
stratify=y
)
# Create and train the model
model = DecisionTreeClassifier(
max_depth=3,
random_state=42
)
model.fit(X_train, y_train)
# Predict the test classes
predictions = model.predict(X_test)
# Evaluate accuracy
accuracy = accuracy_score(
y_test,
predictions
)
print(f"\nAccuracy: {accuracy:.2f}")
# Display detailed evaluation metrics
print("\nClassification report:")
print(
classification_report(
y_test,
predictions,
target_names=iris.target_names,
zero_division=0
)
)
# Display the confusion matrix
matrix = confusion_matrix(
y_test,
predictions
)
display = ConfusionMatrixDisplay(
confusion_matrix=matrix,
display_labels=iris.target_names
)
display.plot()
plt.title("Iris Classification Confusion Matrix")
plt.show()
# Predict a new flower
new_flower = pd.DataFrame(
[[5.1, 3.5, 1.4, 0.2]],
columns=iris.feature_names
)
predicted_class = model.predict(new_flower)[0]
predicted_species = iris.target_names[predicted_class]
print("\nPredicted species:", predicted_species)
# Display predicted class probabilities
probabilities = model.predict_proba(
new_flower
)[0]
probability_table = pd.DataFrame({
"species": iris.target_names,
"probability": probabilities
})
print("\nPredicted probabilities:")
print(probability_table)
Preventing Data Leakage
Data leakage occurs when information that would not legitimately be available at prediction time influences model training or evaluation. Leakage can create unrealistically high evaluation results.
Leakage Prevention Checklist
- Separate the target from the input features
- Exclude information created after the predicted outcome
- Split the dataset before learning preprocessing parameters
- Fit transformations using training data only
- Keep closely related observations in the same partition
- Use chronological splitting for applicable forecasting problems
- Investigate unexpectedly high evaluation results
Overfitting and Underfitting
Overfitting
- The model follows training details too closely
- Training performance may be very high
- Test performance may be considerably weaker
- Noise may be treated as a meaningful pattern
Underfitting
- The model is unable to learn important patterns
- Training performance remains weak
- Test performance also remains weak
- The features or model may be too limited
Good Generalization
- The model learns useful patterns from training data
- Performance remains reliable on unseen data
- The model is not unnecessarily complex
- The results support the intended practical objective
Common Beginner Mistakes
Best Practices
Recommended Practices
- Begin with a clearly defined prediction problem
- Understand every feature and the target before training
- Inspect missing values, duplicates, ranges, and class distribution
- Keep training and evaluation data logically separate
- Use reproducible random seeds when appropriate
- Compare the model with a meaningful baseline
- Select evaluation metrics based on the practical objective
- Place preprocessing and modeling steps into a consistent pipeline
- Record dataset, feature, model, and evaluation details
- Monitor performance and input data after deployment
Practice Exercise
Complete the following tasks to strengthen your understanding of the tutorial.
Inspect More Rows
Display the first ten and last ten observations. Compare their feature values and species.
Change the Test Size
Change the test proportion and observe whether the evaluation results remain stable.
Change Tree Depth
Train decision trees with different maximum depths. Compare their training and test performance.
Predict Additional Flowers
Create additional observations with valid flower measurements and inspect their predicted species and class probabilities.
Study Classification Errors
Use the confusion matrix and comparison table to identify which species are confused with one another.
Try Another Classifier
Replace the decision tree with a K-Nearest Neighbors or Logistic Regression classifier and compare the evaluation results.
Knowledge Check
Why is this a classification problem?
Consider the form of the output produced by the model.
What is the difference between X and y?
Identify which variable contains features and which contains the target classes.
Why do we split the dataset?
Explain why evaluating the model only on training data can be misleading.
What does the fit method do?
Explain how the model uses training features and known targets.
What does the predict method do?
Explain how a fitted model assigns classes to unseen features.
Why should accuracy not always be used alone?
Consider class imbalance and the different consequences of classification errors.
What is data leakage?
Explain how inappropriate information can create unrealistic evaluation results.
Tutorial Summary
| Step | What You Did |
|---|---|
| Problem Definition | Defined a flower-species classification problem |
| Data Loading | Loaded the Iris dataset from scikit-learn |
| Data Exploration | Inspected rows, columns, statistics, missing values, and classes |
| Feature Selection | Separated flower measurements from the target species |
| Data Splitting | Created separate training and test datasets |
| Model Creation | Created a Decision Tree Classifier |
| Model Training | Fitted the classifier using labeled training examples |
| Prediction | Generated classes for unseen test observations |
| Evaluation | Reviewed accuracy, precision, recall, F1 score, and the confusion matrix |
| New Inference | Predicted the species and probabilities of a new flower |
Key Takeaway
A complete Machine Learning workflow includes problem definition, data understanding, preparation, splitting, training, evaluation, and prediction. Creating a model is only one part of the process. Reliable Machine Learning also requires appropriate data, realistic evaluation, leakage prevention, consistent preprocessing, responsible use, and ongoing monitoring.
Get Machine Learning updates by email
Short, practical lessons and course updates from Rumman Ansari. No spam.