Converting Epsilon per Metre to a Privacy Radius
A geo-indistinguishability rate and a privacy radius are the same parameter in different units: , where is the posterior factor you are willing to grant. Set the radius, derive the rate, and never copy a number across from a central-model budget.
Core Calculation permalink
The guarantee bounds the distinguishability of two locations metres apart by . Fixing an acceptable factor and solving for the distance at which it is reached gives
The mean displacement of the planar Laplace mechanism follows directly:
At the conventional , that is exactly . This ratio is the number to carry into a design discussion: a privacy radius of costs a typical error of . Teams routinely ask for a 500 m radius and 50 m of error, and the relationship above is why that request has no solution.
Parameter table permalink
At (posterior ratio 2.72), which is the default this site uses:
| Privacy radius | Rate (m⁻¹) | Mean displacement | 95th-percentile displacement | Typical use |
|---|---|---|---|---|
| 50 m | 0.0200 | 100 m | 240 m | Indoor / campus scale; near GPS error |
| 100 m | 0.0100 | 200 m | 470 m | Street-block confusability |
| 200 m | 0.0050 | 400 m | 950 m | Neighbourhood — a common default |
| 500 m | 0.0020 | 1 000 m | 2 400 m | District-level |
| 1 000 m | 0.0010 | 2 000 m | 4 700 m | Town-level; point utility largely gone |
Raising from to halves the rate for the same radius, and doubles the displacement — it is a weaker guarantee bought with more noise, which is rarely what anyone intends. Leave at unless a reviewer has explicitly agreed otherwise.
Python Implementation permalink
from __future__ import annotations
import math
from dataclasses import dataclass
@dataclass(frozen=True)
class GeoIndParameters:
"""A geo-indistinguishability setting, carrying every reading a reviewer needs.
The class exists so that no caller can pass a bare float named `epsilon`:
the unit ambiguity between a central-model budget and a per-metre rate is the
dominant configuration error in this mechanism.
"""
privacy_radius_m: float
tolerable_factor: float = math.e
def __post_init__(self) -> None:
if self.privacy_radius_m <= 0:
raise ValueError("privacy_radius_m must be positive")
if self.tolerable_factor <= 1.0:
raise ValueError("tolerable_factor must exceed 1 to grant any leeway")
if self.privacy_radius_m < 25.0:
# Below GPS error the guarantee constrains nobody; fail rather than
# ship a release whose documented radius is inside the sensor noise.
raise ValueError("privacy_radius_m below 25 m is not meaningful")
@property
def epsilon_per_m(self) -> float:
return math.log(self.tolerable_factor) / self.privacy_radius_m
@property
def mean_displacement_m(self) -> float:
return 2.0 / self.epsilon_per_m
@property
def p95_displacement_m(self) -> float:
# 95th percentile of Gamma(2, 1/eps): numeric root of F(r) = 0.95
return 4.744 / self.epsilon_per_m
def as_release_record(self) -> dict:
"""Exactly the fields an audit record should carry for this mechanism."""
return {
"mechanism": "planar_laplace",
"epsilon_per_m": round(self.epsilon_per_m, 6),
"privacy_radius_m": self.privacy_radius_m,
"tolerable_factor": round(self.tolerable_factor, 4),
"mean_displacement_m": round(self.mean_displacement_m, 1),
"p95_displacement_m": round(self.p95_displacement_m, 1),
}
params = GeoIndParameters(privacy_radius_m=200.0)
# {'mechanism': 'planar_laplace', 'epsilon_per_m': 0.005, 'privacy_radius_m': 200.0,
# 'tolerable_factor': 2.7183, 'mean_displacement_m': 400.0, 'p95_displacement_m': 948.8}
Verification permalink
def check_parameters(p: GeoIndParameters, max_acceptable_error_m: float) -> dict:
"""Confirm the utility budget and the privacy radius are mutually satisfiable."""
feasible = p.mean_displacement_m <= max_acceptable_error_m
return {
"feasible": feasible,
"mean_displacement_m": p.mean_displacement_m,
"max_acceptable_error_m": max_acceptable_error_m,
"largest_feasible_radius_m": max_acceptable_error_m / 2.0,
"note": ("ok" if feasible else
"the requested radius and error budget cannot both hold; "
"the radius must fall or the error budget must rise"),
}
The largest_feasible_radius_m field is the useful output of a failing check: it converts “this is impossible” into a specific counter-proposal, which is what an engineering discussion needs.
How the Radius Reads to Different Audiences permalink
The reason to lead with the radius rather than the rate is that three different audiences have to sign off on the same number, and only one of them thinks in exponents.
An engineer needs the rate, because it is what the sampler consumes and what appears in the code. A data protection officer needs the radius, because the obligation they are testing is whether the released location is precise enough to identify someone, and “two locations 200 m apart remain confusable” is a direct answer to that question where “ε = 0.005 per metre” is not. An analyst needs the mean displacement, because it tells them whether the released points can still support the query they intend to run.
The three are the same parameter, so a record that carries all three cannot be internally inconsistent — and a review that asks each audience about the figure they understand tends to surface disagreements that a single-number record hides. The commonest such disagreement is between the officer and the analyst: the officer approves a 500 m radius without knowing it implies a kilometre of typical error, and the analyst discovers the implication after the release has been announced.
There is also a presentational trap worth naming. Stating a privacy radius invites readers to imagine a hard boundary — a circle inside which the true location definitely lies, and outside which it definitely does not. The planar Laplace mechanism has no such boundary: its density is positive everywhere, and roughly a quarter of reports land beyond three times the radius. The radius describes where the guarantee is strong, not where the point is. Any summary written for a non-technical reader should say so explicitly, because the alternative reading makes the release sound both more precise and more protective than it is.
Edge Cases & Adjustments permalink
- Radii below GPS error. Under about 25 m the mechanism’s displacement is comparable to the sensor’s own error, so the guarantee constrains an adversary who was already uncertain. The implementation above refuses rather than shipping a radius that reads well and does nothing.
- A different tolerable factor. Raising weakens the guarantee at the stated radius. If a reviewer requests it, record both and : a radius quoted without its factor is not interpretable.
- Comparing against a central-model budget. They are not comparable. If a programme needs one ledger covering both, convert each to a under zero-concentrated accounting and sum those, as described under composing privacy budgets across spatial queries.
- Repeated reports. The radius describes one report. Over independent reports of the same location the effective protection degrades, so the record should state the radius and the reporting policy that keeps it valid.
- Latitude. None of these quantities depend on latitude, because they are defined in a projected CRS. That is a reason to keep the parameter in metres rather than restating it in degrees anywhere.
FAQ permalink
Why is the mean displacement twice the privacy radius?
Because the planar Laplace radius follows Gamma(2, 1/ε), whose mean is , and at the radius is . The factor of two is a property of the mechanism, not a safety margin, and it cannot be tuned away without changing mechanism.
Can I quote a privacy radius for a mechanism that is not planar Laplace?
Only if it satisfies the metric definition. A donut mask or a Gaussian displacement has a characteristic distance but no bound, so calling that distance a privacy radius overstates what it delivers — the distinction drawn in masking vs. differential privacy technique selection.
What should appear in the release record?
Both units, the factor, and both displacement figures. The as_release_record output above is the minimum set; anything less leaves a reviewer unable to reconstruct the mechanism from the record.
Is a 200 m radius a good default?
It is a common one because it corresponds to neighbourhood-scale confusability and a 400 m typical error, which most aggregate analyses tolerate. It is a starting point for a discussion about the specific threat model, not a standard.
Related permalink
- Geo-Indistinguishability & the Planar Laplace Mechanism — the definition these units belong to
- Implementing Planar Laplace Noise in Python — the sampler that consumes this rate
- Composing Privacy Budgets Across Spatial Queries — putting metric and central budgets in one ledger
- Building a Spatial Privacy Audit Report Template — where these fields are recorded
← Back to Geo-Indistinguishability & the Planar Laplace Mechanism