Skip to contents

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)"
#>