Mastering Local Outlier Factor (LOF): From Global Distance to Local Density
You can follow this Google Colab notebook to better understand the implementation and calculation of the Local Outlier Factor (LOF) algorithm.
Outlier detection is a cornerstone of data analysis, but not all outliers are created equal.
A point that looks perfectly normal from a global perspective can be highly suspicious when we look at its close neighbours.
In this article, we will explore two detection approaches – K‑NN based distance and Local Outlier Factor (LOF) – using a carefully chosen 9‑point dataset. We will go through every step of the calculation, compare the final scores, and understand why LOF is the superior choice for finding local anomalies.
1. Two Basic Types of Outliers
Before we dive into the numbers, let’s clearly define the two main types of outliers.
| Type | Definition |
|---|---|
| Local Outlier | A point that is unusual when compared with its nearby points, even though it may look perfectly normal compared to the entire dataset. |
| Global Outlier | A point that is unusual when compared with the entire dataset as a whole. |
Understanding this distinction is the key to choosing the right detection algorithm.
2. The Dataset
We use the following 9 points. They form two clear groups:
- P1 to P5 – a relatively dense cluster in the lower‑left area.
- P6 to P9 – a sparse, scattered group in the upper‑right area.
| Point | Coordinates |
|---|---|
| P1 | (2, 3) |
| P2 | (8, 7) |
| P3 | (10.8, 7) |
| P4 | (8.3, 4) |
| P5 | (12, 4) |
| P6 | (30, 15) |
| P7 | (35, 10) |
| P8 | (45, 5) |
| P9 | (45, 15) |
When plotted, the two clusters are clearly separated. Points P6, P7, P8, and P9 are far away from the first group, but they also have noticeable gaps among themselves.
3. Step 1 – K‑NN Based Outlier Detection (Global Approach)
The simplest way to find outliers is to measure the average distance to the k‑nearest neighbours.
Here we set k = 3. For each point, we compute the average Euclidean distance to its three closest neighbours – a higher average means the point is more isolated.
Calculated Scores (sorted, highest first)
| Point | Avg. Distance to 3‑NN |
|---|---|
| P6 | 13.3663 |
| P8 | 13.0694 |
| P9 | 12.0601 |
| P7 | 9.8106 |
| P1 | 7.7521 |
| P5 | 3.9770 |
| P2 | 3.6050 |
| P4 | 3.5400 |
| P3 | 3.3121 |
What this tells us
- P6, P8, and P9 are flagged as the strongest outliers.
- P1 also has a relatively high score (7.75) because it lies on the edge of the dense cluster.
The limitation
K‑NN based on global distance cannot distinguish between:
- A point that is truly isolated (e.g., P6).
- A point that is simply on the edge of a sparse region.
If we only relied on these scores, we might incorrectly treat all high‑scoring points the same.
4. Step 2 – Introducing Local Outlier Factor (LOF)
LOF solves this problem by comparing the local density of a point with the local densities of its neighbours. Instead of asking “how far away is this point?”, it asks:
“Is this point’s neighbourhood as dense as the neighbourhoods of its neighbours?”
Core concepts
1. Reachability Distance
For two points p and o, the reachability distance is defined as:
$$
\text{reach-dist}_k(p, o) = \max( \text{actual distance}(p, o),; k\text{-distance}(o) )
$$
-
actual distance(p, o)– the straight‑line Euclidean distance. -
k-distance(o)– the distance fromoto its k‑th nearest neighbour (i.e., the farthest neighbour among itskclosest points).
We always take the maximum of these two values.
2. Local Reachability Density (LRD)
The LRD of a point p is the inverse of the average reachability distance to its k neighbours:
$$
LRD_k(p) = \frac{|N_k(p)|}{\sum_{o \in N_k(p)} \text{reach-dist}_k(p, o)}
$$
A higher LRD means the point is in a dense region (reachability distances are small).
A lower LRD means the point is in a sparse region.
3. LOF Score (finally!)
The LOF score compares the average LRD of p’s neighbours to the LRD of p itself:
$$
LOF_k(p) = \frac{1}{|N_k(p)|} \sum_{o \in N_k(p)} \frac{LRD_k(o)}{LRD_k(p)}
$$
-
LOF ≈ 1 →
phas similar density to its neighbours (normal point). -
LOF > 1 →
pis less dense than its neighbours (potential local outlier). -
LOF < 1 →
pis denser than its neighbours (rare, but possible).
5. Step‑by‑Step Walkthrough: Calculating LOF for P1
Let’s calculate the LOF score for P1 using k = 3 to see exactly how the formula works in practice.
5.1 Find the 3 nearest neighbours of P1
The Euclidean distances from P1 to the other points are:
- P4 = 6.38
- P2 = 7.21
- P3 = 9.67
- P5 = 10.05
- (P6–P9 are much farther)
So the 3 neighbours of P1 are: P2, P4, and P5.
5.2 Compute the reachability distances from P1 to each neighbour
For each neighbour o, we need:
- Actual distance from P1 to
o. -
k-distance(o)– i.e., the distance fromoto its own 3rd nearest neighbour.
| Neighbour | Actual distance to P1 | k‑distance of neighbour | RD = max(actual, k‑dist) |
|---|---|---|---|
| P2 | 7.21 | 5.00 | 7.21 |
| P4 | 6.38 | 3.90 | 6.38 |
| P5 | 10.05 | 3.90 | 10.05 |
5.3 Calculate LRD(P1)
Sum of RD values = 7.21 + 6.38 + 10.05 = 23.64
$$
LRD(P1) = \frac{3}{23.64} = 0.1269
$$
5.4 Calculate LRD for each neighbour (P2, P4, P5)
Following the same procedure (but with their own respective neighbours), we get:
- LRD(P2) = 0.2344
- LRD(P4) = 0.2158
- LRD(P5) = 0.2158
5.5 Apply the LOF formula for P1
$$
LOF(P1) = \frac{1}{3} \times \frac{LRD(P2) + LRD(P4) + LRD(P5)}{LRD(P1)}
$$
$$
= \frac{1}{3} \times \frac{0.2344 + 0.2158 + 0.2158}{0.1269}
= 1.720
$$
Interpretation: P1 has an LOF score of 1.72, meaning its local density is significantly lower than that of its neighbours. P1 is a genuine local outlier.
6. Final Results – LOF Scores for All Points
We repeat this procedure for every point in the dataset.
Here is the sorted list of final LOF scores (from highest to lowest):
| Point | LOF Score | Interpretation |
|---|---|---|
| P1 | 1.720 | Strong local outlier |
| P7 | 1.130 | Mildly suspicious |
| P3 | 1.057 | Slightly above normal |
| P4 | 1.057 | Slightly above normal |
| P9 | 1.021 | Almost normal (≈ 1) |
| P5 | 0.947 | Normal |
| P2 | 0.947 | Normal |
| P6 | 0.934 | Normal (dense in its sparse cluster) |
| P8 | 0.934 | Normal (dense in its sparse cluster) |
7. Analysing the Results
The Local Outlier (P1)
P1 is the only point with an LOF score clearly above 1.5.
Although P1 is not extremely far from P2, P3, and P4, the dense cluster around it is so tight that P1 sits in a relatively empty “gap”. This makes it a perfect example of a local anomaly.
The Global Outliers (P6 and P8)
P6 and P8 were the top scorers in the K‑NN global distance test, yet their LOF scores are below 1 (0.934).
Why? Because they are located in the sparse upper‑right cluster. Their neighbours are similarly far away, so the local density of P6 and P8 matches the local density of their neighbourhood. They are normal within their own group.
The In‑Between Cases
- P7 (1.130) and P9 (1.020) sit on the edges of the sparse cluster and are slightly less dense than their immediate neighbours – but the effect is mild.
- P2, P3, P4, and P5 all have scores very close to 1, confirming they are well‑embedded in their respective local structures.
8. Summary: K‑NN vs LOF
| Aspect | K‑NN (avg. distance) | LOF |
|---|---|---|
| Detects global outliers? | ✅ Yes | ✅ Yes (but indirect) |
| Detects local outliers? | ❌ No | ✅ Yes |
| Handles varying density? | ❌ No – treats all regions equally | ✅ Yes – compares neighbours within each region |
| Interpretation | Distance‑based | Density‑ratio based |
In our dataset:
- K‑NN would wrongly flag P6 and P8 as the most extreme outliers.
- LOF correctly identifies P1 as the most anomalous point relative to its own cluster, while P6 and P8 are considered normal.
9. Final Takeaway
When your dataset contains clusters of different densities, never rely on global distance alone. Local Outlier Factor (LOF) gives you a much more nuanced and truthful picture by answering the right question:
“How does this point compare to its neighbours, and how do those neighbours compare to theirs?”