Differentially-private mean via the Gaussian mechanism with bounded inputs
Source:R/dp.R
morie_dp_gaussian_mean.RdReleases an approximately (\(\epsilon\), \(\delta\))-DP mean of a
bounded numeric vector. Sensitivity is derived from the user-asserted
bounds: changing one record can shift the sum by at most
upper - lower, so the mean's sensitivity is
(upper - lower) / length(x).
Details
The noise standard deviation follows the classical analytic-Gaussian calibration: $$\sigma = \frac{\Delta \cdot \sqrt{2 \ln(1.25/\delta)}}{\epsilon}.$$
Examples
set.seed(1)
x <- runif(1000, 0, 1)
# A private mean of bounded data (bounds asserted by the caller).
morie_dp_gaussian_mean(x, lower = 0, upper = 1, epsilon = 1.0)
#> [1] 0.5001013
mean(x) # the true mean, for comparison
#> [1] 0.4996917
# `delta` controls the (epsilon, delta) guarantee; smaller = stronger.
morie_dp_gaussian_mean(x, 0, 1, epsilon = 1.0, delta = 1e-9)
#> [1] 0.4977702
# Wider bounds raise sensitivity, so the same epsilon adds more noise.
morie_dp_gaussian_mean(x, lower = -5, upper = 5, epsilon = 1.0)
#> [1] 0.436994
# Out-of-range values are clipped to [lower, upper] (with a warning).
y <- c(x, 2, -1)
suppressWarnings(morie_dp_gaussian_mean(y, lower = 0, upper = 1, epsilon = 1))
#> [1] 0.499752