Data Fundamentals for Machine Learning
understanding how data is collected, represented, processed, and prepared for AI models
Core Concepts Covered
- Data types, structured vs unstructured data
- Preprocessing pipelines: cleaning, normalizing, scaling, and feature engineering
- Dataset partitioning: Training, Validation, and Testing sets
Local Setup Recommendation
To execute and experiment with the code cells below on your local machine, ensure you have set up your isolated virtual environments and scientific libraries by following the detailed protocols in Unit 03: Environment Setup or run them in Google Colab.
1. Data Types: Structured vs. Unstructured
Data is the absolute fuel of any machine learning system. Before writing training loops, we must understand how data is formatted and represented. At their core, machine learning models are mathematical systems that can only calculate on numbers, vectors, and matrices. Therefore, all real-world data must be mapped into structured numerical spaces.
• Structured Data: Organized in highly formatted tables, schemas, or relational databases (e.g., CSV files containing age, income, and house price columns). Each sample is a row, and each feature is a column, which can be loaded directly into a standard tabular frame.
• Unstructured Data: Has no pre-defined organizational layout (e.g., raw text articles, JPEG image pixel grids, audio wave recordings, or MP4 video frames). To feed unstructured data into an ML model, we use deep representation layers to automatically extract features. For instance, a Convolutional Neural Network (CNN) transforms a 2D JPEG pixel grid into a flat vector of feature scores, representing the visual contents mathematically in a structured vector space.
import pandas as pd
# Load, structure, and explore tabular datasets
raw_data = {
'Feature_Age': [25, 47, 31, 19, 52],
'Feature_Income': [52000, 115000, 71000, 24000, 142000],
'Target_Purchased': [0, 1, 1, 0, 1]
}
df = pd.DataFrame(raw_data)
print("Dataframe Shape:", df.shape)
print("Summary Statistics:\n", df.describe().round(1))Dataframe Shape: (5, 3)
Summary Statistics:
Feature_Age Feature_Income Target_Purchased
count 5.0 5.0 5.0
mean 34.8 80800.0 0.6
std 13.4 49660.9 0.5
min 19.0 24000.0 0.0
max 52.0 142000.0 1.02. Feature Engineering: Normalization vs. Standardization
In raw tabular datasets, features often span completely different mathematical scales. For instance, in a real estate dataset, the number of bedrooms spans , while annual household income spans 20,000-.
Why Scaling Matters: If we attempt to run Gradient Descent on unscaled features, the loss function's contour landscape becomes extremely skewed and elongated along the larger-scale feature axes. This causes gradient updates to oscillate erratically, slowing down convergence or preventing learning entirely. Scaling the features squashes the contour landscape into a symmetric bowl, enabling smooth, direct steps toward the local minimum.
We solve this using two primary scaling techniques:
• Normalization (Min-Max Scaling): Linearly shifts and scales all values so they lie strictly within a bounded interval, typically . It is ideal when you know your data boundaries have no extreme outliers. The formula is:
• Standardization (Standard Scaling): Centers the feature values to have a mean () of and a standard deviation () of . Unlike normalization, it does not restrict values to a hard range, making it highly robust to extreme outliers. The formula is:
from sklearn.preprocessing import MinMaxScaler, StandardScaler
import numpy as np
# Sample incomes
incomes = np.array([[52000], [115000], [71000], [24000], [142000]])
# Apply Min-Max Normalization [0, 1]
norm_scaler = MinMaxScaler()
normalized = norm_scaler.fit_transform(incomes)
# Apply Standard Scaling (Mean=0, Std=1)
std_scaler = StandardScaler()
standardized = std_scaler.fit_transform(incomes)
print("Original incomes:\n", incomes.flatten())
print("Min-Max Normalized:\n", normalized.flatten().round(2))
print("Standardized (z-score):\n", standardized.flatten().round(2))Original incomes:
[ 52000 115000 71000 24000 142000]
Min-Max Normalized:
[0.24 0.77 0.4 0. 1. ]
Standardized (z-score):
[-0.65 0.77 -0.22 -1.28 1.38]3. Training, Validation, and Testing Split Hygiene
To perform strict scientific evaluation and ensure our models can generalize to new real-world environments, we must split our dataset into three mutually exclusive partitions:
1. Training Set (-): The data passed directly to our optimization algorithms to fit the model parameters (weights and biases).
2. Validation Set (-): Used during development to monitor model generalization, tune hyperparameters (like learning rate or model architecture size), and trigger early stopping if the model begins to overfit.
3. Testing Set (-): Kept completely isolated in a vault until the end of development. It serves as an uncorrupted final benchmark to measure the model's true real-world generalization performance on novel inputs.
• The Threat of Data Leakage: Data leakage occurs when information from the validation or testing set is unintentionally exposed to the model during training. A common source of leakage is scaling: if you compute the global mean () and variance () using the *entire* dataset before splitting, the model 'leaks' properties of the test set into its training phase, yielding artificially optimistic testing scores that collapse when deployed to actual production environments.
from sklearn.model_selection import train_test_split
# Generate a synthetic dataset (100 samples)
X, y = np.arange(200).reshape(100, 2), np.arange(100)
# Correct split workflow: 1st split isolates test partition (20%)
X_train_val, X_test, y_train_val, y_test = train_test_split(X, y, test_size=0.20, random_state=42)
# 2nd split divides train_val partition into train (75%) and val (25% of 80% = 20% overall)
X_train, X_val, y_train, y_val = train_test_split(X_train_val, y_train_val, test_size=0.25, random_state=42)
print(f"Total dataset: 100% (100 samples)")
print(f"Training split: {len(X_train)}% ({len(X_train)} samples)")
print(f"Validation split: {len(X_val)}% ({len(X_val)} samples)")
print(f"Testing split: {len(X_test)}% ({len(X_test)} samples)")Total dataset: 100% (100 samples)
Training split: 60% (60 samples)
Validation split: 20% (20 samples)
Testing split: 20% (20 samples)Interactive Practice Quiz
Test your understanding with instant feedback
Which of the following scenarios represents unstructured data?
Which feature scaling formula converts values into a bounded interval strictly between 0 and 1?
Why is 'Standardization' (Standard Scaling) often preferred over 'Min-Max Normalization' in the presence of extreme outliers?
Which of the following defines 'Data Leakage' in machine learning workflows?
To prevent data leakage, when should feature scalers (like StandardScaler) be 'fit'?
Which of the following describes structured data compared to unstructured data?
What is the mathematical difference between Normalization (Min-Max Scaling) and Standardization (Standard Scaling)?
Why does unscaled feature data distort the 'Loss Contour' landscape during gradient descent?
Which dataset partition is used during development to compare model architectures, tune human-set hyperparameters, and trigger early stopping?
In dataset hygiene, why must the 'Testing Set' be kept completely separated in a 'vault' until final model compilation?
Further Readings
Explore these highly recommended external references to deepen your understanding
