Always free. For everyone.
Course outline
Module 14 of 20 · Machine learning

Find hidden patterns

Group sensor readings, compress features, and spot unusual activity without labels. This module has 3 lessons and takes about 1h 30m. Each lesson has a practice exercise that runs real Python in your browser and a short quiz.

Start module 14 in the Learning Lab
LESSON 1 OF 3

Group machines with k-means

30 minEngineering
WHAT YOU WILL DO

Implement the two repeating steps of k-means and inspect machine groups.

A workshop records temperature and vibration for six fictional motors. There are no fault labels. Clustering groups readings that look similar, which can help an engineer decide what to inspect next.

K-means alternates between assigning each row to its nearest centre and moving each centre to the average of its assigned rows. Standardise the two columns first so temperature does not dominate just because its numbers are larger.

The group numbers have no built-in meaning. A group is not a diagnosis, and choosing two groups does not prove that two operating states exist. Compare several choices and inspect the original units.

See it in action

example.pyPython 3
import numpy as np

# Synthetic rows: temperature in C, vibration in mm/s.
readings = np.array([[40, 1.0], [42, 1.2], [39, 0.9],
                     [78, 4.8], [80, 5.0], [76, 4.6]])
mean, scale = readings.mean(axis=0), readings.std(axis=0)
X = (readings - mean) / scale
centres = X[[0, 3]].copy()
for step in range(20):
    distances = ((X[:, None, :] - centres[None, :, :]) ** 2).sum(axis=2)
    labels = distances.argmin(axis=1)
    updated = centres.copy()
    for group in range(2):
        members = X[labels == group]
        if len(members):  # Keep the old centre if a group is empty.
            updated[group] = members.mean(axis=0)
    if np.allclose(updated, centres):
        break
    centres = updated
print("Groups:", labels.tolist())
print("Centres in original units:", (centres * scale + mean).round(2))
Keep this in mind

A cluster is a useful pattern to investigate, not a verified label.

LESSON 2 OF 3

Compress correlated sensors with PCA

30 minEnergy
WHAT YOU WILL DO

Project related sensor columns onto a smaller set of directions and measure reconstruction error.

Imagine a solar plant with three sensors that mostly move together as sunlight changes. Principal component analysis, or PCA, finds directions that capture variation across the columns. One new coordinate can summarise much of a strongly shared pattern.

Centre and scale the training data, then use a singular value decomposition to find the directions. Project onto the first direction and reconstruct the original columns to see what information was lost.

A high explained-variance ratio means much of the numeric variation was preserved. It does not mean the retained direction is useful for your prediction target. Fit PCA on training rows only when it is part of a prediction workflow.

See it in action

example.pyPython 3
import numpy as np

rng = np.random.default_rng(14)
sunlight = np.linspace(1, 6, 12)
sensors = np.column_stack([sunlight, 2 * sunlight, 0.5 * sunlight])
sensors += rng.normal(0, 0.08, sensors.shape)
mean, scale = sensors.mean(axis=0), sensors.std(axis=0)
X = (sensors - mean) / scale
_, singular_values, directions = np.linalg.svd(X, full_matrices=False)
component = directions[:1]
compressed = X @ component.T
reconstructed = compressed @ component
ratio = singular_values[0] ** 2 / (singular_values ** 2).sum()
error = np.mean((X - reconstructed) ** 2)
print("Shape:", X.shape, "->", compressed.shape)
print("Variance retained:", round(float(ratio), 4))
print("Reconstruction MSE:", round(float(error), 4))
Keep this in mind

Use reconstruction error and the later task to judge whether compression is useful.

LESSON 3 OF 3

Flag unusual payments with a robust score

30 minFinance
WHAT YOU WILL DO

Build a median-based anomaly score and separate alerts from confirmed events.

A fictional laboratory processes routine supplier payments. A very large payment may be an input mistake, a legitimate equipment purchase, or something that needs review. An anomaly detector can prioritise a queue, but it cannot establish why a payment is unusual.

The median is less affected by a few extreme values than the mean. The median absolute deviation, or MAD, measures typical distance from the median. Dividing a new amount's distance by MAD gives a simple, robust score.

Fit the median and MAD using a reference period. The threshold of 5 below is a teaching choice, not a calibrated fraud rule. When MAD is zero, the example raises an error instead of inventing a reliable score.

See it in action

example.pyPython 3
import numpy as np

reference = np.array([98, 100, 102, 99, 101, 97, 103], dtype=float)
incoming = np.array([101, 99, 280, 104], dtype=float)
centre = np.median(reference)
mad = np.median(np.abs(reference - centre))
if mad == 0:
    raise ValueError("Reference data has no usable MAD scale")
scores = np.abs(incoming - centre) / mad
for amount, score in zip(incoming, scores):
    print(f"Amount {amount:.0f}: score={score:.1f}, review={score > 5}")
Keep this in mind

Keep anomaly scores, review decisions, and confirmed outcomes as separate fields.

ABOUT THE LEARNING LAB

Free, open and run by a nonprofit.

This page is part of Python to AI, a free course of 20 modules and 60 lessons in the engineering.fit( ) Learning Lab. The Learning Lab is built and run by engineering.fit( ), a nonprofit founded by Abdullateef Opeyemi Bakare that helps African engineering students gain research experience. You do not need an account or pay a fee to learn.

Course outline · Project lab · Visit engineering-fit.org