What is Unsupervised Learning?
Unsupervised Learning is a type of Machine Learning where the algorithm works with data that does not have a predefined target or label. Instead of learning from known answers, the algorithm searches for useful patterns, groups, relationships, or unusual observations within the data.
No Target Column
The dataset does not contain a predefined answer that the model must learn to predict.
Find Hidden Patterns
Algorithms search for structures, similarities, relationships, or unusual observations.
Clustering
Similar records are grouped together based on selected features.
Dimensionality Reduction
Large numbers of features can be transformed into fewer dimensions while attempting to preserve useful structure.
In supervised learning, the model learns from labeled examples. In unsupervised learning, the algorithm explores the structure of the available data.
Raw Data
↓
Feature Selection
↓
Data Preparation
↓
Unsupervised Algorithm
↓
Patterns / Groups
↓
Business or Scientific Analysis
| Feature | Supervised Learning | Unsupervised Learning |
|---|---|---|
| Target | Known target | No predefined target |
| Learning | From labeled examples | From data structure |
| Common Task | Prediction | Pattern discovery |
| Example | Predict house price | Group customers |
| Common Algorithms | Linear Regression, Random Forest | K-Means, DBSCAN, PCA |
Clustering
Groups similar records together. Example: customer segmentation.
Dimensionality Reduction
Reduces the number of features while retaining useful structure.
Anomaly Detection
Identifies observations that are unusual compared with the rest of the data.
pip install pandas numpy scikit-learn matplotlib seaborn
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
Consider a business with customer information such as annual income and spending score.
data = {
"CustomerID": [
101, 102, 103, 104, 105,
106, 107, 108, 109, 110
],
"AnnualIncome": [
25000, 28000, 30000, 45000, 50000,
55000, 70000, 75000, 90000, 95000
],
"SpendingScore": [
20, 25, 30, 45, 50,
55, 70, 75, 90, 95
]
}
df = pd.DataFrame(data)
print(df)
CustomerID identifies the customer but does not represent a useful behavioral feature for this clustering example.
X = df[
["AnnualIncome", "SpendingScore"]
]
print(X)
Scaling is often useful when features have substantially different numerical ranges.
scaler = StandardScaler()
X_scaled = scaler.fit_transform(
X
)
print(X_scaled)
K-Means is one of the most commonly taught clustering algorithms. It attempts to divide observations into a specified number of clusters.
kmeans = KMeans(
n_clusters=3,
random_state=42,
n_init=10
)
kmeans.fit(X_scaled)
df["Cluster"] = kmeans.labels_
print(df)
After clustering, examine the characteristics of each group instead of assigning meanings automatically.
cluster_summary = df.groupby(
"Cluster"
)[
["AnnualIncome", "SpendingScore"]
].mean()
print(cluster_summary)
K-Means requires a value for the number of clusters. One common exploratory technique is the Elbow Method.
inertia = []
for k in range(1, 8):
model = KMeans(
n_clusters=k,
random_state=42,
n_init=10
)
model.fit(X_scaled)
inertia.append(
model.inertia_
)
print(inertia)
Plotting the inertia values can help identify a point where adding more clusters produces diminishing improvements.
plt.plot(
range(1, 8),
inertia,
marker="o"
)
plt.xlabel("Number of Clusters")
plt.ylabel("Inertia")
plt.title("Elbow Method")
plt.show()
plt.scatter(
df["AnnualIncome"],
df["SpendingScore"],
c=df["Cluster"]
)
plt.xlabel("Annual Income")
plt.ylabel("Spending Score")
plt.title("Customer Segments")
plt.show()
Each K-Means cluster has a centroid representing the center of the cluster in feature space.
print(
kmeans.cluster_centers_
)
When clustering was performed on standardized features, the centroid values are expressed in the standardized feature space.
An e-commerce company wants to understand its customers without having predefined customer categories.
Customer Data
↓
Income + Spending + Visits
↓
Data Scaling
↓
K-Means Clustering
↓
Customer Groups
↓
Analyze Group Behavior
↓
Create Business Strategies
Group A
Customers with relatively lower spending and lower purchasing activity.
Group B
Customers with moderate income and spending.
Group C
Customers with relatively higher spending activity.
A retailer can group products according to price, sales volume, customer rating, and inventory movement.
products = pd.DataFrame({
"Price": [
100, 120, 150, 500,
550, 600, 1000, 1100
],
"Sales": [
500, 450, 420, 250,
230, 210, 80, 70
],
"Rating": [
3.8, 4.0, 4.1, 4.2,
4.4, 4.5, 4.7, 4.8
]
})
features = products[
["Price", "Sales", "Rating"]
]
scaler = StandardScaler()
scaled_products = scaler.fit_transform(
features
)
product_model = KMeans(
n_clusters=3,
random_state=42,
n_init=10
)
products["Cluster"] = product_model.fit_predict(
scaled_products
)
print(products)
A company can use geographic coordinates and store characteristics to identify groups of similar locations.
locations = pd.DataFrame({
"Latitude": [
18.52, 18.53, 18.54,
18.60, 18.61, 18.62,
19.00, 19.01, 19.02
],
"Longitude": [
73.85, 73.86, 73.87,
73.80, 73.81, 73.82,
73.10, 73.11, 73.12
]
})
location_model = KMeans(
n_clusters=3,
random_state=42,
n_init=10
)
locations["Cluster"] = location_model.fit_predict(
locations[
["Latitude", "Longitude"]
]
)
print(locations)
Hierarchical clustering builds a hierarchy of groups and can be visualized as a dendrogram.
from scipy.cluster.hierarchy import (
dendrogram,
linkage
)
Z = linkage(
X_scaled,
method="ward"
)
dendrogram(Z)
plt.title(
"Hierarchical Clustering Dendrogram"
)
plt.xlabel("Samples")
plt.ylabel("Distance")
plt.show()
Agglomerative clustering starts with individual observations and progressively merges similar groups.
from sklearn.cluster import AgglomerativeClustering
model = AgglomerativeClustering(
n_clusters=3
)
labels = model.fit_predict(
X_scaled
)
df["HierarchicalCluster"] = labels
print(df)
DBSCAN groups observations based on density and can identify observations that do not belong to dense groups.
from sklearn.cluster import DBSCAN
dbscan = DBSCAN(
eps=0.5,
min_samples=3
)
labels = dbscan.fit_predict(
X_scaled
)
df["DBSCAN_Cluster"] = labels
print(df)
-1 represents observations identified as noise.
Unsupervised techniques can help identify transactions or observations that look unusual compared with normal patterns.
Transaction Data
↓
Amount + Frequency + Time
↓
Find Normal Patterns
↓
Identify Unusual Records
↓
Investigate Potential Anomalies
Isolation Forest is commonly used for anomaly detection. It attempts to isolate unusual observations more quickly than typical observations.
from sklearn.ensemble import IsolationForest
transactions = pd.DataFrame({
"Amount": [
100, 120, 90, 110,
130, 125, 105, 115,
5000, 95
],
"Frequency": [
2, 3, 2, 4,
3, 2, 3, 4,
1, 2
]
})
model = IsolationForest(
contamination=0.1,
random_state=42
)
transactions["Anomaly"] = model.fit_predict(
transactions[
["Amount", "Frequency"]
]
)
print(transactions)
1 for an
observation considered normal and -1 for
one considered anomalous.
Principal Component Analysis, or PCA, transforms a dataset into a smaller number of components that capture important variation in the data.
from sklearn.decomposition import PCA
pca = PCA(
n_components=2
)
X_pca = pca.fit_transform(
X_scaled
)
print(X_pca)
plt.scatter(
X_pca[:, 0],
X_pca[:, 1]
)
plt.xlabel("Principal Component 1")
plt.ylabel("Principal Component 2")
plt.title("PCA Visualization")
plt.show()
PCA provides explained-variance information that indicates how much variation is captured by each principal component.
print(
pca.explained_variance_ratio_
)
print(
"Total:",
pca.explained_variance_ratio_.sum()
)
Suppose an e-commerce dataset contains many customer behavior features.
customers = pd.DataFrame({
"Visits": [5, 8, 12, 20, 25],
"Orders": [1, 2, 3, 7, 9],
"Returns": [0, 1, 1, 2, 2],
"Reviews": [1, 2, 4, 8, 10],
"SupportTickets": [4, 3, 3, 1, 1]
})
scaler = StandardScaler()
scaled = scaler.fit_transform(
customers
)
pca = PCA(
n_components=2
)
reduced = pca.fit_transform(
scaled
)
pca_df = pd.DataFrame(
reduced,
columns=[
"PC1",
"PC2"
]
)
print(pca_df)
An organization can explore employee data using features such as experience, training hours, project count, and performance-related measurements.
employees = pd.DataFrame({
"Experience": [
1, 2, 3, 5, 7,
8, 10, 12
],
"TrainingHours": [
10, 15, 20, 30,
35, 40, 50, 55
],
"Projects": [
1, 2, 2, 4,
5, 6, 8, 10
]
})
scaler = StandardScaler()
employee_scaled = scaler.fit_transform(
employees
)
model = KMeans(
n_clusters=3,
random_state=42,
n_init=10
)
employees["Group"] = model.fit_predict(
employee_scaled
)
print(employees)
A retailer can group products according to demand, inventory levels, and sales frequency.
inventory = pd.DataFrame({
"MonthlySales": [
100, 120, 150, 300,
350, 400, 50, 60
],
"StockLevel": [
500, 450, 400, 300,
280, 250, 700, 650
],
"Orders": [
20, 25, 30, 60,
70, 80, 10, 12
]
})
features = inventory[
[
"MonthlySales",
"StockLevel",
"Orders"
]
]
scaler = StandardScaler()
scaled = scaler.fit_transform(
features
)
model = KMeans(
n_clusters=3,
random_state=42,
n_init=10
)
inventory["Cluster"] = model.fit_predict(
scaled
)
print(inventory)
The Silhouette Score is one measure that can help evaluate how well observations fit within their assigned clusters.
from sklearn.metrics import silhouette_score
score = silhouette_score(
X_scaled,
kmeans.labels_
)
print(
"Silhouette Score:",
score
)
| Algorithm | Useful When | Important Consideration |
|---|---|---|
| K-Means | Compact groups and known cluster count | Requires choosing k |
| Hierarchical | Exploring nested group structures | Can be computationally expensive |
| DBSCAN | Density-based groups and possible noise | Sensitive to parameter choices |
| Gaussian Mixture | Soft or probabilistic cluster membership | Distribution assumptions matter |
Gaussian Mixture Models represent data as a mixture of probability distributions and can provide soft cluster membership.
from sklearn.mixture import GaussianMixture
gmm = GaussianMixture(
n_components=3,
random_state=42
)
gmm.fit(X_scaled)
labels = gmm.predict(
X_scaled
)
df["GMM_Cluster"] = labels
print(df)
Unsupervised methods can be used to discover customer groups before building more targeted business analyses.
customer_features = df[
["AnnualIncome", "SpendingScore"]
]
scaler = StandardScaler()
scaled_customers = scaler.fit_transform(
customer_features
)
model = KMeans(
n_clusters=4,
random_state=42,
n_init=10
)
df["CustomerGroup"] = model.fit_predict(
scaled_customers
)
summary = df.groupby(
"CustomerGroup"
)[
["AnnualIncome", "SpendingScore"]
].mean()
print(summary)
A website can group visitors based on browsing behavior such as session duration, pages viewed, and visits per month.
visitors = pd.DataFrame({
"SessionMinutes": [
2, 3, 5, 8,
15, 18, 20, 25,
30, 35
],
"PagesViewed": [
2, 3, 4, 6,
10, 12, 15, 18,
22, 25
],
"MonthlyVisits": [
1, 2, 3, 5,
8, 9, 10, 12,
15, 18
]
})
scaler = StandardScaler()
scaled = scaler.fit_transform(
visitors
)
model = KMeans(
n_clusters=3,
random_state=42,
n_init=10
)
visitors["Segment"] = model.fit_predict(
scaled
)
print(visitors)
Articles can be represented using text features and grouped according to similarities in their content.
News Articles
↓
Text Cleaning
↓
TF-IDF Features
↓
Clustering
↓
Similar Article Groups
↓
Topic Exploration
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
documents = [
"Python programming and software development",
"Machine learning and artificial intelligence",
"Football match and sports results",
"Cricket tournament and sports news",
"Python data analysis with pandas",
"Artificial intelligence model training"
]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(
documents
)
model = KMeans(
n_clusters=3,
random_state=42,
n_init=10
)
labels = model.fit_predict(X)
for document, label in zip(
documents,
labels
):
print(label, ":", document)
Market basket analysis looks for relationships between products that customers purchase together. Association-rule mining is commonly used for this type of task.
Customer Transactions
↓
Products Purchased Together
↓
Find Frequent Itemsets
↓
Discover Associations
↓
Business Analysis
Many unsupervised algorithms do not accept missing values directly. Missing data often needs to be handled before clustering or dimensionality reduction.
data = pd.DataFrame({
"Income": [
25000,
30000,
None,
50000,
70000
],
"Spending": [
20,
30,
40,
None,
80
]
})
data["Income"] = data["Income"].fillna(
data["Income"].median()
)
data["Spending"] = data["Spending"].fillna(
data["Spending"].median()
)
print(data)
This example combines data creation, feature selection, scaling, clustering, cluster summaries, and a visualization.
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
# --------------------------------
# 1. Create customer data
# --------------------------------
data = {
"CustomerID": range(101, 113),
"AnnualIncome": [
22000, 25000, 28000, 30000,
45000, 48000, 52000, 56000,
70000, 76000, 85000, 95000
],
"SpendingScore": [
15, 20, 25, 30,
40, 45, 50, 55,
70, 75, 85, 95
],
"MonthlyVisits": [
2, 3, 3, 4,
6, 7, 7, 8,
10, 11, 13, 15
]
}
df = pd.DataFrame(data)
# --------------------------------
# 2. Select features
# --------------------------------
features = df[
[
"AnnualIncome",
"SpendingScore",
"MonthlyVisits"
]
]
# --------------------------------
# 3. Scale features
# --------------------------------
scaler = StandardScaler()
X_scaled = scaler.fit_transform(
features
)
# --------------------------------
# 4. Train K-Means
# --------------------------------
model = KMeans(
n_clusters=3,
random_state=42,
n_init=10
)
df["Cluster"] = model.fit_predict(
X_scaled
)
# --------------------------------
# 5. Analyze clusters
# --------------------------------
summary = df.groupby(
"Cluster"
)[
[
"AnnualIncome",
"SpendingScore",
"MonthlyVisits"
]
].mean()
print("Cluster Summary:")
print(summary)
# --------------------------------
# 6. Display customer groups
# --------------------------------
print("\nCustomers:")
print(df)
# --------------------------------
# 7. Visualize two features
# --------------------------------
plt.scatter(
df["AnnualIncome"],
df["SpendingScore"],
c=df["Cluster"]
)
plt.xlabel("Annual Income")
plt.ylabel("Spending Score")
plt.title("Customer Segmentation")
plt.show()
Dimensionality reduction can make complex datasets easier to visualize and can sometimes reduce computational burden. However, reducing dimensions may also remove information.
- Understand the business or research question.
- Collect relevant unlabeled data.
- Inspect and clean the dataset.
- Select meaningful features.
- Handle missing values appropriately.
- Scale or transform features when appropriate.
- Try suitable clustering algorithms.
- Evaluate cluster structure using appropriate measures.
- Profile and interpret the resulting groups.
- Validate whether the groups are useful for the intended purpose.
Customer Segmentation
Discover groups of customers with similar behavior.
Fraud Analysis
Identify unusual transaction patterns for further investigation.
Product Grouping
Discover similar products using sales or product characteristics.
Document Clustering
Group documents with similar text content.
Image Analysis
Discover visual patterns or reduce image feature dimensions.
Anomaly Detection
Identify observations that differ significantly from common patterns.
- Choosing an unsuitable number of clusters.
- Using irrelevant features.
- Ignoring feature scale.
- Allowing outliers to dominate the analysis.
- Assuming clusters automatically represent meaningful business categories.
- Using a clustering algorithm whose assumptions do not fit the data.
- Ignoring changes in the data over time.
- Interpreting cluster labels as ordered scores.
| Business Question | Approach | Example |
|---|---|---|
| Will this customer purchase? | Supervised Learning | Classification |
| How much will this customer spend? | Supervised Learning | Regression |
| Which customers behave similarly? | Unsupervised Learning | Clustering |
| Which transactions look unusual? | Unsupervised Learning | Anomaly Detection |
| Can we visualize 50 features in fewer dimensions? | Unsupervised Learning | PCA |
- Understand the purpose of discovering groups or patterns.
- Use meaningful features.
- Clean the data before modeling.
- Handle missing values appropriately.
- Consider scaling when required by the algorithm.
- Compare reasonable algorithm and parameter choices.
- Use multiple evaluation approaches when possible.
- Profile each cluster after creating it.
- Do not assume that every cluster is meaningful.
- Validate discovered patterns with domain knowledge.
- Monitor whether discovered structures change over time.
- Document preprocessing and modeling assumptions.
| Step | Question |
|---|---|
| 1 | What pattern or structure are we trying to discover? |
| 2 | Do we have appropriate unlabeled data? |
| 3 | Which features are meaningful? |
| 4 | Does the data require scaling? |
| 5 | Which algorithm fits the data? |
| 6 | How will we evaluate the discovered structure? |
| 7 | Can the groups or patterns be interpreted? |
| 8 | Are the results useful for the intended purpose? |
- Unsupervised learning generally works without predefined target labels.
- Clustering groups observations according to similarities or distances.
- K-Means requires choosing the number of clusters.
- Cluster labels are identifiers, not rankings.
- Feature scaling can strongly affect distance-based algorithms.
- DBSCAN can identify dense groups and noise observations.
- Hierarchical clustering can reveal nested relationships.
- PCA reduces dimensions and creates new transformed components.
- Isolation Forest can be used for anomaly detection.
- Cluster quality should be evaluated using appropriate methods.
- Business meaning should be validated after patterns are discovered.
- Unsupervised results are exploratory and should not automatically be treated as ground truth.
Python Unsupervised Learning • Clustering • PCA • Anomaly Detection • Real-Time Examples