Clip to \([lower, lower + C]\), average, then perturb. Under replace-one adjacency the sensitivity of the mean of \(n\) clipped values is \(\Delta = C/n\); Laplace noise \(Lap(\Delta/\epsilon)\) gives \(\epsilon\)-differential privacy and Gaussian noise with \(\sigma = \Delta\sqrt{2\ln(1.25/\delta)}/\epsilon\) gives \((\epsilon, \delta)\)-differential privacy.
Usage
morie_dp_mean(
y,
C = NULL,
epsilon = 1,
n = NULL,
mechanism = c("laplace", "gaussian"),
delta = 1e-06,
alpha = 0.05,
lower = NULL,
noise = NULL
)Arguments
- y
Numeric sample.
- C
Width of the clipping interval.
- epsilon
Privacy parameter, positive.
- n
Denominator for the sensitivity; defaults to
length(y).- mechanism
"laplace" or "gaussian".
- delta
Used by the Gaussian mechanism only.
- alpha
Two-sided level.
- lower
Lower clipping bound.
- noise
Optional fixed perturbation, bypassing the draw.
Value
A list with estimate, clipped_mean, clipping_bias,
sensitivity, noise_scale, noise_sd, ci_lower, ci_upper,
ci_naive_lower, ci_naive_upper, n_clipped, warnings.
Details
Clipping is the only stage that introduces bias, and nothing
downstream removes it, so the bias is returned rather than folded
into the estimate. Supplying noise directly makes every returned
quantity deterministic, which is what the cross-language parity test
anchors against – R and Python cannot be made to draw the same
Laplace variate, but everything else agrees exactly.
The width C must come from prior knowledge of the domain. Taking it
from the range of y makes it a function of the private data and
voids the guarantee; that case is flagged in warnings.
References
Dwork C, Roth A (2014) Found Trends Theor Comput Sci 9(3-4):211-487, Sec 3.3 and Thm A.1. Karwa V, Vadhan S (2017) arXiv:1711.03908.
Examples
V <- c(1, 2, 3, 4, 5, 6, 7, 8)
morie_dp_mean(V)
#> $estimate
#> [1] 4.649404
#>
#> $non_private_mean
#> [1] 4.5
#>
#> $clipped_mean
#> [1] 4.5
#>
#> $clipping_bias
#> [1] 0
#>
#> $sensitivity
#> [1] 0.875
#>
#> $noise_scale
#> [1] 0.875
#>
#> $noise_sd
#> [1] 1.237437
#>
#> $noise_drawn
#> [1] 0.1494036
#>
#> $mechanism
#> [1] "laplace"
#>
#> $epsilon
#> [1] 1
#>
#> $clip_lower
#> [1] 1
#>
#> $clip_upper
#> [1] 8
#>
#> $clip_width
#> [1] 7
#>
#> $n_clipped
#> [1] 0
#>
#> $sampling_se
#> [1] 0.8660254
#>
#> $total_se
#> [1] 1.510381
#>
#> $ci_lower
#> [1] -0.5194777
#>
#> $ci_upper
#> [1] 9.818285
#>
#> $ci_naive_lower
#> [1] 2.952025
#>
#> $ci_naive_upper
#> [1] 6.346782
#>
#> $n
#> [1] 8
#>
#> $n_denominator
#> [1] 8
#>
#> $warnings
#> [1] "C was taken from the range of y, which is itself a function of the private data. The stated guarantee does not hold for that choice."
#>
#> $method
#> [1] "Differentially private clipped mean (Laplace / Gaussian mechanism)"
#>
