├── .Rbuildignore ├── .codecov.yml ├── .gitignore ├── .travis.yml ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── bernstein_mechanism.R ├── bernstein_polynomials.R ├── diffpriv.R ├── exponential_mechanism.R ├── gaussian_mechanism.R ├── laplace_mechanism.R ├── mechanisms.R ├── numeric_mechanism.R ├── privacy_params.R ├── sensitivity_sampler.R └── utils.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── build_site.R ├── cran-comments.md ├── diffpriv.Rproj ├── docs ├── LICENSE.html ├── articles │ ├── bernstein.pdf │ └── diffpriv.pdf ├── authors.html ├── favicon.ico ├── index.html ├── jquery.sticky-kit.min.js ├── link.svg ├── logo.png ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml └── reference │ ├── DPMech-class.html │ ├── DPMechBernstein-class.html │ ├── DPMechExponential-class.html │ ├── DPMechGaussian-class.html │ ├── DPMechLaplace-class.html │ ├── DPMechNumeric-class.html │ ├── DPParamsDel-class.html │ ├── DPParamsEps-class.html │ ├── DPParamsGam-class.html │ ├── bernstein.html │ ├── diffpriv.html │ ├── figures │ ├── logo.png │ └── logo.svg │ ├── index.html │ ├── predict.bernstein.html │ ├── releaseResponse.html │ ├── sensitivityNorm.html │ ├── sensitivitySampler-DPMech-function-numeric-method.html │ ├── sensitivitySampler.html │ ├── sensitivitySamplerManual-DPMech-function-numeric-numeric-numeric-method.html │ ├── sensitivitySamplerManual-DPMechNumeric-function-numeric-numeric-numeric-method.html │ ├── sensitivitySamplerManual.html │ ├── setDelta-set.html │ ├── setEpsilon-set.html │ └── setGamma-set.html ├── inst ├── CITATION └── doc │ ├── bernstein.R │ ├── bernstein.Rnw │ ├── bernstein.pdf │ ├── diffpriv.R │ ├── diffpriv.Rnw │ └── diffpriv.pdf ├── man ├── DPMech-class.Rd ├── DPMechBernstein-class.Rd ├── DPMechExponential-class.Rd ├── DPMechGaussian-class.Rd ├── DPMechLaplace-class.Rd ├── DPMechNumeric-class.Rd ├── DPParamsDel-class.Rd ├── DPParamsEps-class.Rd ├── DPParamsGam-class.Rd ├── bernstein.Rd ├── diffpriv.Rd ├── figures │ ├── logo.png │ └── logo.svg ├── predict.bernstein.Rd ├── releaseResponse.Rd ├── sensitivityNorm.Rd ├── sensitivitySampler-DPMech-function-numeric-method.Rd ├── sensitivitySampler.Rd ├── sensitivitySamplerManual-DPMech-function-numeric-numeric-numeric-method.Rd ├── sensitivitySamplerManual-DPMechNumeric-function-numeric-numeric-numeric-method.Rd ├── sensitivitySamplerManual.Rd ├── setDelta-set.Rd ├── setEpsilon-set.Rd └── setGamma-set.Rd ├── present ├── 2017-07-25 launchvic │ ├── diffpriv.pptx │ ├── handout.pptx │ ├── logo.png │ ├── pckr.png │ ├── poster.pptx │ └── svm.png ├── 2017-07-25 unimelb │ ├── .gitignore │ ├── Demos │ │ ├── Demos.Rproj │ │ └── sampler.R │ ├── figures │ │ ├── CC-refs.txt │ │ ├── KDE_utility_vs_privacy.pdf │ │ ├── PPTfigs.pptx │ │ ├── Privacy-Preserving Mechanisms for SVM Learning.pdf │ │ ├── brain1.jpg │ │ ├── brain2.jpg │ │ ├── brain3.jpg │ │ ├── brain4.jpg │ │ ├── indistinguishable.png │ │ ├── laplace-proof.PNG │ │ ├── logo-diffpriv-alert.png │ │ ├── logo-diffpriv.png │ │ ├── logo-um.png │ │ ├── logo-uscb.png │ │ ├── m-vs-gamma.pdf │ │ ├── mechanism.PNG │ │ ├── news-godel.PNG │ │ ├── news-medicare.PNG │ │ ├── news-netflix.png │ │ ├── oppts.PNG │ │ ├── paper-svm-1.png │ │ ├── paper-svm-2.png │ │ ├── paper-svm-3.png │ │ ├── results-bernstein-poly.PNG │ │ ├── results-bernstein-svm.PNG │ │ ├── samplerhowto.png │ │ └── screenshot-homepage.PNG │ ├── laplace.mp4 │ ├── sampler.mp4 │ ├── talk-diffpriv.pdf │ └── talk-diffpriv.tex ├── automl2017 │ ├── diffpriv.Rnw │ ├── diffpriv.bib │ └── diffpriv.pdf └── jmlrmloss2017 │ ├── .gitignore │ ├── jmlr2e.sty │ ├── rubinstein17a.Rnw │ ├── rubinstein17a.bib │ └── rubinstein17a.pdf ├── tests ├── testthat.R └── testthat │ ├── test_bernstein.R │ ├── test_mechanisms.R │ ├── test_pparams.R │ ├── test_ssampler.R │ └── test_utils.R └── vignettes ├── bernstein-concordance.tex ├── bernstein.Rnw ├── diffpriv-concordance.tex ├── diffpriv.Rnw ├── diffpriv.bib └── jmlr2e.sty /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^desktop.ini$ 4 | ^README\.Rmd$ 5 | ^README-.*\.png$ 6 | ^\.travis\.yml$ 7 | ^\.codecov\.yml$ 8 | ^_pkgdown\.yml$ 9 | ^docs$ 10 | ^build_site\.R$ 11 | ^present$ 12 | ^cran-comments\.md$ 13 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: r 2 | cache: packages 3 | sudo: true 4 | dist: trusty 5 | 6 | r_packages: 7 | - covr 8 | 9 | before_install: 10 | - sudo apt-get install -qq --yes libgsl-dev 11 | 12 | after_success: 13 | - Rscript -e 'library(covr); codecov()' 14 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: diffpriv 2 | Type: Package 3 | Title: Easy Differential Privacy 4 | Version: 0.4.2.9000 5 | Date: 2017-07-18 6 | Authors@R: c( 7 | person("Benjamin", "Rubinstein", email = "brubinstein@unimelb.edu.au", role = c("aut", "cre")), 8 | person("Francesco", "Aldà", email = "francesco.alda@gmail.com", role = "aut")) 9 | Description: An implementation of major general-purpose mechanisms for privatizing 10 | statistics, models, and machine learners, within the framework of differential 11 | privacy of Dwork et al. (2006) . Example mechanisms 12 | include the Laplace mechanism for releasing numeric aggregates, and the 13 | exponential mechanism for releasing set elements. A sensitivity sampler 14 | (Rubinstein & Alda, 2017) permits sampling target 15 | non-private function sensitivity; combined with the generic mechanisms, it 16 | permits turn-key privatization of arbitrary programs. 17 | License: MIT + file LICENSE 18 | LazyData: TRUE 19 | Depends: R (>= 3.4.0) 20 | Imports: 21 | gsl, 22 | methods, 23 | stats 24 | URL: https://github.com/brubinstein/diffpriv, http://brubinstein.github.io/diffpriv 25 | BugReports: https://github.com/brubinstein/diffpriv/issues 26 | RoxygenNote: 6.0.1 27 | VignetteBuilder: knitr 28 | Encoding: UTF-8 29 | Suggests: 30 | randomNames, 31 | testthat, 32 | knitr, 33 | rmarkdown 34 | Collate: 35 | 'utils.R' 36 | 'bernstein_polynomials.R' 37 | 'privacy_params.R' 38 | 'mechanisms.R' 39 | 'bernstein_mechanism.R' 40 | 'diffpriv.R' 41 | 'exponential_mechanism.R' 42 | 'numeric_mechanism.R' 43 | 'gaussian_mechanism.R' 44 | 'laplace_mechanism.R' 45 | 'sensitivity_sampler.R' 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2017 2 | COPYRIGHT HOLDER: Benjamin I. P. Rubinstein 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(predict,bernstein) 4 | export(DPMechBernstein) 5 | export(DPMechExponential) 6 | export(DPMechGaussian) 7 | export(DPMechLaplace) 8 | export(DPMechNumeric) 9 | export(DPParamsDel) 10 | export(DPParamsEps) 11 | export(DPParamsGam) 12 | export(bernstein) 13 | export(sensitivitySampler) 14 | export(sensitivitySamplerManual) 15 | exportClasses(DPMech) 16 | exportClasses(DPMechBernstein) 17 | exportClasses(DPMechExponential) 18 | exportClasses(DPMechGaussian) 19 | exportClasses(DPMechLaplace) 20 | exportClasses(DPMechNumeric) 21 | exportClasses(DPParamsDel) 22 | exportClasses(DPParamsEps) 23 | exportClasses(DPParamsGam) 24 | exportMethods(releaseResponse) 25 | exportMethods(sensitivityNorm) 26 | exportMethods(sensitivitySampler) 27 | exportMethods(sensitivitySamplerManual) 28 | import(methods) 29 | importFrom(stats,predict) 30 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | ## diffpriv 0.4.2 2 | 3 | * Second vignette `bernstein` on: Bernstein approximations and use of `DPMechBernstein` for private function release. 4 | * Minor edits to docs 5 | 6 | ## diffpriv 0.4.1 7 | 8 | * Expanding test coverage of Bernstein mechanism and function approximation code. 9 | 10 | ## diffpriv 0.4.0 11 | 12 | * Addition of `S3` constructor and `predict()` generic implementation for fitting (non-iterated) Bernstein polynomial function approximations. 13 | * Addition of `DPMechBernstein` class implementing the Bernstein mechanism of Alda and Rubinstein (AAAI'2017), for privately releasing functions. 14 | * Bug fix in the Laplace random sampler affecting `DPMechLaplace` 15 | * Unit test coverage of new functionality; general documentation improvements. 16 | 17 | ## diffpriv 0.3.2 18 | 19 | * Addition of `DPMechGaussian` class for the generic Gaussian mechanism to 20 | README, Vignette. Resolves #2 21 | * Minor test additions. 22 | 23 | ## diffpriv 0.3.1 24 | 25 | * Refactoring around `releaseResponse()` method in `DPMechNumeric`. Resolves #1 26 | * Increased test coverage. 27 | 28 | ## diffpriv 0.3.0 29 | 30 | * New `DPMechGaussian` class implementing the Gaussian mechanism, which 31 | achieves (epsilon,delta)-differential privacy by adding Gaussian noise to 32 | numeric responses calibrated by L2-norm sensitivity. 33 | * Refactoring of `DPMechGaussian` and `DPMechLaplace` underneath a new 34 | `VIRTUAL` class `DPMechNumeric` which contains common methods, `dims` slot 35 | (formerly `dim` changed because `dim` is a special slot for S4). 36 | 37 | ## diffpriv 0.2.0 38 | 39 | * `DPMechLaplace` objects can now be initialized without specifying 40 | non-private `target` response `dim`. In such cases, the sensitivity sampler 41 | will perform an additional `target` probe to determine `dim`. 42 | 43 | ## diffpriv 0.1.0.901 44 | 45 | * Sensitivity sampler methods no longer require oracles that return lists. 46 | Acceptable oracles may now return lists, matrices, data frames, numeric 47 | vectors, or char vectors. As a consequence some example code in docs, README and vignette, is simplified. 48 | 49 | ## diffpriv 0.1.0.900 50 | 51 | * Initial release 52 | -------------------------------------------------------------------------------- /R/bernstein_mechanism.R: -------------------------------------------------------------------------------- 1 | #' @include mechanisms.R privacy_params.R utils.R bernstein_polynomials.R 2 | #' @importFrom stats predict 3 | NULL 4 | 5 | #' An S4 class for the Bernstein mechanism of differential privacy. 6 | #' 7 | #' A class that implements the Bernstein mechanism (not iterated version) of 8 | #' differential privacy, for privatizing release of real-valued functions on 9 | #' \eqn{[0,1]^l} based on arbitrary datasets. Approximates the \code{target} 10 | #' on a lattice. 11 | #' 12 | #' @slot sensitivity non-negative scalar numeric maximum absolute \code{target} 13 | #' sensitivity maximized over the lattice. Defaults to \code{Inf} for use 14 | #' with \code{sensitivitySampler()}. 15 | #' @slot target might be a closure that takes arbitrary dataset and returns a 16 | #' real-valued function on \eqn{[0,1]^l}. 17 | #' @slot gammaSensitivity \code{NA_real_} if inactive, or scalar in [0,1) 18 | #' indicating that responses must be RDP with specific confidence. 19 | #' @slot latticeK positive scalar integer-valued numeric specifying the lattice 20 | #' resolution. Defaults to (invalid) \code{NA_integer_}. 21 | #' @slot dims positive scalar integer-valued numeric specifying the dimension 22 | #' of released function domain. Defaults to (invalid) \code{NA_integer_}. 23 | #' 24 | #' @examples 25 | #' ## See the bernstein vignette 26 | #' 27 | #' @references 28 | #' Francesco Aldà and Benjamin I. P. Rubinstein. "The Bernstein Mechanism: 29 | #' Function Release under Differential Privacy", in Proceedings of the 31st 30 | #' AAAI Conference on Artificial Intelligence (AAAI'2017), pp. 1705-1711, 31 | #' Feb 2017. 32 | #' 33 | #' @export DPMechBernstein 34 | #' @exportClass DPMechBernstein 35 | DPMechBernstein <- setClass("DPMechBernstein", 36 | contains = "DPMech", 37 | slots = list(latticeK="numeric", dims="numeric"), 38 | prototype = prototype(latticeK=NA_integer_, dims=NA_integer_) 39 | ) 40 | 41 | ## A \code{DPMechBernstein} should be constructed with appropriate 42 | ## lattice parameter, function domain dimension. 43 | setValidity("DPMechBernstein", function(object) { 44 | if (!.check_integer(object@latticeK) || object@latticeK < 1) { 45 | return("DPMechBernstein@latticeK should be positive integer-valued.") 46 | } 47 | if (!.check_integer(object@dims) || object@dims < 1) { 48 | return("DPMechBernstein@dims should be positive integer-valued.") 49 | } 50 | return(TRUE) 51 | }) 52 | 53 | #' @describeIn DPMechBernstein automatically prints the object. 54 | #' @param object an instance of class \code{DPMech}. 55 | setMethod("show", "DPMechBernstein", function(object) { 56 | cat("Bernstein mechanism\n") 57 | cat("Sensitivity:", object@sensitivity, "\n") 58 | if (is.na(object@gammaSensitivity)) { 59 | cat("Sampled sensitivity gamma: NA\n") 60 | } else { 61 | cat("Sampled sensitivity gamma:", object@gammaSensitivity, "\n") 62 | } 63 | cat("Lattice resolution:", object@latticeK, "\n") 64 | cat("Function domain dimension:", object@dims, "\n") 65 | cat("Target function: \n") 66 | show(object@target) 67 | }) 68 | 69 | #' @describeIn DPMechBernstein releases Bernstein mechanism responses. 70 | #' @param mechanism an object of class \code{\link{DPMechBernstein}}. 71 | #' @param privacyParams an object of class \code{\link{DPParamsEps}}. 72 | #' @param X a privacy-sensitive dataset, if using sensitivity sampler a: list, 73 | #' matrix, data frame, numeric/character vector. 74 | #' @return list with slots per argument, actual privacy parameter and response: 75 | #' mechanism response with length of target release: 76 | #' \code{privacyParams, sensitivity, latticeK, dims, target, response}. 77 | #' @export 78 | setMethod("releaseResponse", 79 | signature(mechanism = "DPMechBernstein", 80 | privacyParams = "DPParamsEps", 81 | X = "ANY"), 82 | function(mechanism, privacyParams, X) { 83 | ## Retrieve non-private function using data X, Bernstein fit 84 | rawFunc <- mechanism@target(X) 85 | if (!is.function(rawFunc)) { 86 | stop("Non-private target output is not a function.") 87 | } 88 | appFunc <- bernstein(rawFunc, dims=mechanism@dims, k=mechanism@latticeK) 89 | ## Laplace-perturb coefficients 90 | scale <- mechanism@sensitivity * 91 | (mechanism@latticeK + 1)^mechanism@dims / 92 | privacyParams@epsilon 93 | noise <- .rlap((mechanism@latticeK + 1)^(mechanism@dims), 94 | location = 0, 95 | scale = scale) 96 | appFunc$coeffs <- appFunc$coeffs + noise 97 | ## Wrap up results, return 98 | R <- function(y) predict(appFunc, y) 99 | if (is.na(mechanism@gammaSensitivity)) { 100 | p <- privacyParams 101 | } else { 102 | p <- toGamma(privacyParams, mechanism@gammaSensitivity) 103 | } 104 | return(list( 105 | privacyParams = p, 106 | sensitivity = mechanism@sensitivity, 107 | latticeK = mechanism@latticeK, 108 | dims = mechanism@dims, 109 | target = mechanism@target, 110 | response = R 111 | )) 112 | } 113 | ) 114 | 115 | #' @describeIn DPMechBernstein measures \code{target} sensitivity. 116 | #' @param X1 a privacy-sensitive dataset. 117 | #' @param X2 a privacy-sensitive dataset. 118 | #' @return scalar numeric norm of non-private \code{target} on datasets. 119 | #' The \eqn{L_\infty} of the functions on a lattice. 120 | #' @export 121 | setMethod("sensitivityNorm", 122 | signature(mechanism = "DPMechBernstein", 123 | X1 = "ANY", 124 | X2 = "ANY"), 125 | function(mechanism, X1, X2) { 126 | ## The raw functions to start 127 | rawFunc1 <- mechanism@target(X1) 128 | rawFunc2 <- mechanism@target(X2) 129 | if (!is.function(rawFunc1) || !is.function(rawFunc2)) { 130 | stop("Non-private target output is not a function.") 131 | } 132 | ## Lattice on which to compare 133 | latt <- .bernstein_lattice( 134 | d = mechanism@dims, 135 | k = mechanism@latticeK) / mechanism@latticeK 136 | ## Compare functions as their max deviation on the lattice 137 | rs1 <- apply(latt, 1, rawFunc1) 138 | rs2 <- apply(latt, 1, rawFunc2) 139 | return(.linfty_norm(rs1 - rs2)) 140 | } 141 | ) 142 | -------------------------------------------------------------------------------- /R/bernstein_polynomials.R: -------------------------------------------------------------------------------- 1 | #' @include utils.R 2 | NULL 3 | 4 | #' Multidimensional lattice for Bernstein approximation. 5 | #' 6 | #' Generates a lattice in \code{d} dimensions in each ranging from 7 | #' \code{0} through \code{k}, in some fixed order. For internal use only. 8 | #' 9 | #' @param d positive scalar integer dimension. 10 | #' @param k positive scalar integer max lattice point component. 11 | #' @return a matrix with \eqn{(k+1)^d} rows and \eqn{d} columns enumerating 12 | #' the lattice points in rows. 13 | .bernstein_lattice <- function(d, k) { 14 | if (!.check_integer(d) || d < 1) { 15 | stop("Expected positive scalar integer d.") 16 | } 17 | if (!.check_integer(k) || k < 1) { 18 | stop("Expected positive scalar integer k.") 19 | } 20 | return(as.matrix(expand.grid(replicate(d, 0:k, simplify = FALSE)))) 21 | } 22 | 23 | #' Fit a Bernstein polynomial approximation. 24 | #' 25 | #' Fits the basis of Bernstein polynomial functions to given real-valued 26 | #' function \code{f} of \eqn{[0,1]^d} where \eqn{d=}\code{dims}, against 27 | #' a regular lattice of \eqn{k+1} points in each dimension for given 28 | #' \code{k}. Note the approximation is not the iterated variant. 29 | #' 30 | #' @param f a function to be approximated. 31 | #' @param dims the function \code{f}'s domain dimension. 32 | #' @param k the lattice resolution of approximation. 33 | #' @return an S3 object of class \code{bernstein}. 34 | #' 35 | #' @seealso \code{\link{predict.bernstein}} for subsequent evaluation. 36 | #' 37 | #' @examples 38 | #' f <- function(x) x * sin(x*10) 39 | #' b <- bernstein(f, dims = 1) 40 | #' xs <- seq(from=0, to=1, length=50) 41 | #' mean((f(xs) - predict(b,xs))^2) 42 | #' 43 | #' @references 44 | #' Francesco Aldà and Benjamin I. P. Rubinstein. "The Bernstein Mechanism: 45 | #' Function Release under Differential Privacy", in Proceedings of the 31st 46 | #' AAAI Conference on Artificial Intelligence (AAAI'2017), pp. 1705-1711, 47 | #' Feb 2017. 48 | #' 49 | #' @export 50 | bernstein <- function(f, dims, k = 10) { 51 | if (!is.function(f)) { 52 | stop("Expected f a function.") 53 | } 54 | if (!.check_integer(dims) || dims < 1) { 55 | stop("Expected positive scalar integer dims.") 56 | } 57 | if (!.check_integer(k) || k < 1) { 58 | stop("Expected positive scalar integer k.") 59 | } 60 | latt <- .bernstein_lattice(d = dims, k = k) / k 61 | r <- structure(list(dims = dims, k = k, coeffs = apply(latt, 1, f)), 62 | class = "bernstein") 63 | return(r) 64 | } 65 | 66 | #' Evaluate Bernstein approximations on data. 67 | #' 68 | #' Evaluates a given S3 object of type \code{bernstein} on given 69 | #' data \code{D}. 70 | #' 71 | #' @param object an S3 object of type \code{bernstein}. 72 | #' @param D either a numeric vector or matrix, all values in \code{[0,1]}. 73 | #' If numeric then length should be \code{object$dims} unless the latter is 74 | #' 1 in which case the length can be arbitrary. If a matrix then the number 75 | #' of columns should match \code{object$dims}. 76 | #' @param \dots additional arguments. 77 | #' @return a numeric vector of scalar real evaluations. 78 | #' 79 | #' @examples 80 | #' f <- function(x) x * sin(x*10) 81 | #' b <- bernstein(f, dims = 1) 82 | #' xs <- seq(from=0, to=1, length=50) 83 | #' mean((f(xs) - predict(b,xs))^2) 84 | #' 85 | #' @references 86 | #' Francesco Aldà and Benjamin I. P. Rubinstein. "The Bernstein Mechanism: 87 | #' Function Release under Differential Privacy", in Proceedings of the 31st 88 | #' AAAI Conference on Artificial Intelligence (AAAI'2017), pp. 1705-1711, 89 | #' Feb 2017. 90 | #' 91 | #' @export 92 | predict.bernstein <- function(object, D, ...) { 93 | if (class(object) != "bernstein") { 94 | stop("Expected object of type 'bernstein'.") 95 | } 96 | if (!is.numeric(D) || any(D < 0) || any(D > 1)) { 97 | stop("Expected numeric data in unit interval [0,1].") 98 | } 99 | if (is.matrix(D) && ncol(D) != object$dims) { 100 | stop("Expected object$dims columns in matrix D.") 101 | } 102 | if (!is.matrix(D)) { 103 | if (object$dims <= 1) { 104 | D <- as.matrix(D, ncol = 1) 105 | } else { 106 | if (length(D) != object$dims) { 107 | stop("Expected numeric D of length object$dims.") 108 | } 109 | D <- matrix(D, nrow = 1, ncol = object$dims) 110 | } 111 | } 112 | latt <- .bernstein_lattice(d = object$dims, k = object$k) 113 | oneEval <- function(ys) { 114 | pmfs <- apply(latt, 1, 115 | stats::dbinom, 116 | size = rep(object$k, object$dims), 117 | prob = ys) 118 | if (object$dims > 1) { 119 | pmfs <- apply(pmfs, 2, prod) 120 | } 121 | return(sum(pmfs * object$coeffs)) 122 | } 123 | return(apply(D, 1, oneEval)) 124 | } 125 | -------------------------------------------------------------------------------- /R/diffpriv.R: -------------------------------------------------------------------------------- 1 | #' \code{diffpriv}: practical differential privacy in R. 2 | #' 3 | #' The \code{diffpriv} package is a collection of generic tools for privacy-aware 4 | #' data science, under the formal framework of differential privacy. A 5 | #' differentially-private mechanism can release responses to untrusted third 6 | #' parties, models fit on privacy-sensitive data. Due to the formal worst-case 7 | #' nature of the framework, however, mechanism development typically requires 8 | #' theoretical analysis. \code{diffpriv} offers a turn-key approach to 9 | #' differential privacy. 10 | #' 11 | #' @section General-purpose mechanisms: 12 | #' 13 | #' Differential privacy's popularity is owed in part to a number of generic 14 | #' mechanisms for privatizing non-private target functions. Virtual S4 15 | #' class \code{\link{DPMech-class}} captures common features of these mechanisms and 16 | #' is superclass to: 17 | #' 18 | #' \itemize{ 19 | #' \item \code{\link{DPMechLaplace}}: the Laplace mechanism of Dwork et al. 20 | #' (2006) for releasing numeric vectors; 21 | #' \item \code{\link{DPMechExponential}}: the exponential mechanism of McSherry 22 | #' and Talwar (2007) for releasing solutions to optimizations, over numeric or 23 | #' non-numeric sets; and 24 | #' \item More mechanisms coming soon. Users can also develop new mechanisms by 25 | #' subclassing \code{\link{DPMech-class}}. 26 | #' } 27 | #' 28 | #' \code{\link{DPMech-class}}-derived objects are initialized with a problem-specific 29 | #' non-private \code{target} function. Subsequently, the 30 | #' \code{\link{releaseResponse}} method can privatize responses of \code{target} 31 | #' on input datasets. The level of corresponding privatization depends on given 32 | #' privacy parameters \code{\link{DPParamsEps}} or derived parameters object. 33 | #' 34 | #' @section Privatize anything with sensitivity measurement: 35 | #' 36 | #' \code{diffpriv} mechanisms have in common a reliance on the 'sensitivity' of 37 | #' \code{target} function to small changes to input datasets. This sensitivity 38 | #' must be provably bounded for an application's \code{target} in order for 39 | #' differential privacy to be proved, and is used to calibrate privacy-preserving 40 | #' randomization. Unfortunately bounding sensitivity is often prohibitively 41 | #' complex, for example if \code{target} is an arbitrary computer program. All 42 | #' \code{\link{DPMech-class}} mechanisms offer a \code{\link{sensitivitySampler}} 43 | #' method due to Rubinstein and Aldà (2017) that repeatedly probes \code{target} 44 | #' to estimate sensitivity automatically. Mechanisms with estimated sensitivities 45 | #' achieve a slightly weaker form of random differential privacy due to 46 | #' Hall et al. (2013), but without any theoretical analysis necessary. 47 | #' 48 | #' @examples 49 | #' \dontrun{ 50 | #' ## for full examples see the diffpriv vignette 51 | #' vignette("diffpriv") 52 | #' } 53 | #' 54 | #' @references 55 | #' Benjamin I. P. Rubinstein and Francesco Aldà. "Pain-Free Random Differential 56 | #' Privacy with Sensitivity Sampling", accepted into the 34th International 57 | #' Conference on Machine Learning (ICML'2017), May 2017. 58 | #' 59 | #' Cynthia Dwork, Frank McSherry, Kobbi Nissim, and Adam Smith. 60 | #' "Calibrating noise to sensitivity in private data analysis." In Theory of 61 | #' Cryptography Conference, pp. 265-284. Springer Berlin Heidelberg, 2006. 62 | #' 63 | #' Frank McSherry and Kunal Talwar. "Mechanism design via differential privacy." 64 | #' In the 48th Annual IEEE Symposium on Foundations of Computer Science 65 | #' (FOCS'07), pp. 94-103. IEEE, 2007. 66 | #' 67 | #' Rob Hall, Alessandro Rinaldo, and Larry Wasserman. "Random Differential 68 | #' Privacy." Journal of Privacy and Confidentiality, 4(2), pp. 43-59, 2012. 69 | #' 70 | #' @docType package 71 | #' @name diffpriv 72 | #' @import methods 73 | NULL 74 | -------------------------------------------------------------------------------- /R/exponential_mechanism.R: -------------------------------------------------------------------------------- 1 | #' @include mechanisms.R privacy_params.R utils.R 2 | NULL 3 | 4 | #' An S4 class for the exponential mechanism of differential privacy. 5 | #' 6 | #' A class that implements the exponential mechanism of differential privacy, 7 | #' for privatizing releases from sets (not necessarily numeric as 8 | #' required by \code{\link{DPMechLaplace}}). Currently limited to responses 9 | #' from a finite sets - the most widely used case - as these induce easily 10 | #' computed sampling distributions from a uniform base measure. 11 | #' 12 | #' @slot sensitivity non-negative scalar numeric quality function sensitivity. 13 | #' Defaults to \code{Inf} for use with \code{sensitivitySampler()}. 14 | #' @slot target the quality score function mapping dataset to a function on 15 | #' responses (elements of \code{responseSet}). 16 | #' @slot gammaSensitivity \code{NA_real_} if inactive, or scalar in [0,1) 17 | #' indicating that responses must be RDP with specific confidence. 18 | #' @slot responseSet a list of possible responses of the mechanism. 19 | #' 20 | #' @references 21 | #' Frank McSherry and Kunal Talwar. "Mechanism design via differential privacy." 22 | #' In the 48th Annual IEEE Symposium on Foundations of Computer Science 23 | #' (FOCS'07), pp. 94-103. IEEE, 2007. 24 | #' 25 | #' @export DPMechExponential 26 | #' @exportClass DPMechExponential 27 | DPMechExponential <- setClass("DPMechExponential", 28 | contains = "DPMech", 29 | slots = list(responseSet = "list") 30 | ) 31 | 32 | ## A \code{DPMechExponential} should be constructed with an appropriate 33 | ## response set. 34 | setValidity("DPMechExponential", function(object) { 35 | if (!is.list(object@responseSet) || length(object@responseSet) <= 0) { 36 | return("DPMechExponential@responseSet should be non-empty list.") 37 | } 38 | return(TRUE) 39 | }) 40 | 41 | #' @describeIn DPMechExponential automatically prints the object. 42 | #' @param object an instance of class \code{DPMech}. 43 | setMethod("show", "DPMechExponential", function(object) { 44 | cat("Exponential mechanism\n") 45 | cat("Sensitivity:", object@sensitivity, "\n") 46 | if (is.na(object@gammaSensitivity)) { 47 | cat("Sampled sensitivity gamma: NA\n") 48 | } else { 49 | cat("Sampled sensitivity gamma:", object@gammaSensitivity, "\n") 50 | } 51 | cat("Response set:", paste(object@responseSet)) 52 | cat("Quality score function: \n") 53 | show(object@target) 54 | }) 55 | 56 | #' @describeIn DPMechExponential releases exponential mechanism responses. 57 | #' @param mechanism an object of class \code{\link{DPMechExponential}}. 58 | #' @param privacyParams an object of class \code{\link{DPParamsEps}}. 59 | #' @param X a privacy-sensitive dataset, if using sensitivity sampler a: list, 60 | #' matrix, data frame, numeric/character vector. 61 | #' @return list with slots per argument, actual privacy parameter and response: 62 | #' mechanism response with length of target release: 63 | #' \code{privacyParams, sensitivity, responseSet, target, response}. 64 | #' @examples 65 | #' ## Sensitive data are strings of length at most 5. 66 | #' ## Task is to release most frequent character present, hence quality function 67 | #' ## is a closure that counts character frequencies for given candidate char. 68 | #' ## Global sensitivity is max string length. 69 | #' qualF <- function(X) { function(r) sum(r == unlist(strsplit(X, ""))) } 70 | #' rs <- as.list(letters) 71 | #' m <- DPMechExponential(sensitivity = 5, target = qualF, responseSet = rs) 72 | #' X <- strsplit("the quick brown fox jumps over the lazy dog"," ")[[1]] 73 | #' p <- DPParamsEps(epsilon = 1) 74 | #' releaseResponse(m, p, X) 75 | #' @export 76 | setMethod("releaseResponse", 77 | signature(mechanism = "DPMechExponential", 78 | privacyParams = "DPParamsEps", 79 | X = "ANY"), 80 | function(mechanism, privacyParams, X) { 81 | scoreFunc <- mechanism@target(X) ## target returns a function 82 | if (!is.function(scoreFunc)) { 83 | stop("Non-private target output is not a function.") 84 | } 85 | qualities <- sapply(mechanism@responseSet, scoreFunc) 86 | pmf <- qualities * (getEpsilon(privacyParams) / (2*mechanism@sensitivity)) 87 | pmf <- pmf / sum(pmf) 88 | R <- sample(mechanism@responseSet, size=1, prob=pmf)[[1]] 89 | if (is.na(mechanism@gammaSensitivity)) { 90 | p <- privacyParams 91 | } else { 92 | p <- toGamma(privacyParams, mechanism@gammaSensitivity) 93 | } 94 | return(list( 95 | privacyParams = p, 96 | sensitivity = mechanism@sensitivity, 97 | responseSet = mechanism@responseSet, 98 | target = mechanism@target, 99 | response = R 100 | )) 101 | } 102 | ) 103 | 104 | #' @describeIn DPMechExponential measures \code{target} quality score sensitivity. 105 | #' @param X1 a privacy-sensitive dataset. 106 | #' @param X2 a privacy-sensitive dataset. 107 | #' @return scalar numeric norm of non-private \code{target} on datasets. 108 | #' @export 109 | setMethod("sensitivityNorm", 110 | signature(mechanism = "DPMechExponential", 111 | X1 = "ANY", 112 | X2 = "ANY"), 113 | function(mechanism, X1, X2) { 114 | scoreFunc1 <- mechanism@target(X1) 115 | scoreFunc2 <- mechanism@target(X2) 116 | if (!is.function(scoreFunc1) || !is.function(scoreFunc2)) { 117 | stop("Non-private target output is not a function.") 118 | } 119 | scores1 <- sapply(mechanism@responseSet, scoreFunc1) 120 | scores2 <- sapply(mechanism@responseSet, scoreFunc2) 121 | return(.linfty_norm(scores1 - scores2)) 122 | } 123 | ) 124 | -------------------------------------------------------------------------------- /R/gaussian_mechanism.R: -------------------------------------------------------------------------------- 1 | #' @include mechanisms.R numeric_mechanism.R privacy_params.R utils.R 2 | NULL 3 | 4 | #' An S4 class for the Gaussian mechanism of differential privacy. 5 | #' 6 | #' A class that implements the Gaussian mechanism of differential privacy, 7 | #' for privatizing numeric vector releases. 8 | #' 9 | #' @slot sensitivity non-negative scalar numeric L2 target sensitivity. 10 | #' Defaults to \code{Inf} for use with \code{sensitivitySampler()}. 11 | #' @slot target the target non-private function to be privatized, takes lists. 12 | #' Defaults to a constant function. Gaussian mechanism assumes functions that 13 | #' release numeric vectors of fixed dimension \code{dims}. 14 | #' @slot gammaSensitivity \code{NA_real_} if inactive, or scalar in [0,1) 15 | #' indicating that responses must be RDP with specific confidence. 16 | #' @slot dims positive scalar numeric dimension of responses. Defaults to 17 | #' \code{NA_integer_} for use with \code{sensitivitySampler()} which can 18 | #' probe \code{target} to determine dimension. 19 | #' 20 | #' @references Cynthia Dwork and Aaron Roth. "Algorithmic Foundations of 21 | #' Differential Privacy" Foundations and Trends in Theoretical Computer 22 | #' Science. Now Publishers, 2014. 23 | #' 24 | #' @export DPMechGaussian 25 | #' @exportClass DPMechGaussian 26 | DPMechGaussian <- setClass("DPMechGaussian", 27 | contains = "DPMechNumeric" 28 | ) 29 | 30 | #' @describeIn DPMechGaussian automatically prints the object. 31 | #' @param object an instance of class \code{DPMech}. 32 | setMethod("show", "DPMechGaussian", function(object) { 33 | cat("Gaussian mechanism\n") 34 | callNextMethod() 35 | }) 36 | 37 | #' \code{DPMechGaussian} response space L2 norm. 38 | #' 39 | #' Represents the L2 norm on \code{target} responses. For internal use. 40 | #' 41 | #' @param object an instance of class \code{\link{DPMechGaussian-class}}. 42 | #' @param rawR1 a non-private response from \code{target}. 43 | #' @param rawR2 a non-private response from \code{target}. 44 | #' @return a non-negative scalar L2 norm between \code{rawR1}, \code{rawR2}. 45 | setMethod(".numericNorm", 46 | signature(object = "DPMechGaussian", 47 | rawR1 = "numeric", 48 | rawR2 = "numeric"), 49 | function(object, rawR1, rawR2) { 50 | return(.l2norm(rawR1 - rawR2)) 51 | } 52 | ) 53 | 54 | #' \code{DPMechGaussian} release response core. 55 | #' 56 | #' Implements the core calculation specific to the \code{DPMechGaussian} 57 | #' subclass \code{releaseResponse()}. Internal function, not to be called. 58 | #' 59 | #' @param object an instance of class \code{\link{DPMechGaussian-class}}. 60 | #' @param rawR a non-private response from \code{target}. 61 | #' @param privacyParams object of type \code{DPParamsDel}. 62 | #' @return a numeric private response. 63 | setMethod(".responseCore", 64 | signature(object = "DPMechGaussian", 65 | rawR = "numeric", 66 | privacyParams = "DPParamsDel"), 67 | function(object, rawR, privacyParams) { 68 | C <- sqrt(2 * log(1.25 / privacyParams@delta)) 69 | noise <- stats::rnorm(length(rawR), mean = 0, 70 | sd = object@sensitivity * C / privacyParams@epsilon) 71 | R <- rawR + noise 72 | return(R) 73 | } 74 | ) 75 | -------------------------------------------------------------------------------- /R/laplace_mechanism.R: -------------------------------------------------------------------------------- 1 | #' @include mechanisms.R numeric_mechanism.R privacy_params.R utils.R 2 | NULL 3 | 4 | #' An S4 class for the Laplace mechanism of differential privacy. 5 | #' 6 | #' A class that implements the basic Laplace mechanism of differential privacy, 7 | #' for privatizing numeric vector releases. 8 | #' 9 | #' @slot sensitivity non-negative scalar numeric L1 target sensitivity. 10 | #' Defaults to \code{Inf} for use with \code{sensitivitySampler()}. 11 | #' @slot target the target non-private function to be privatized, takes lists. 12 | #' Defaults to a constant function. Laplace mechanism assumes functions that 13 | #' release numeric vectors of fixed dimension \code{dims}. 14 | #' @slot gammaSensitivity \code{NA_real_} if inactive, or scalar in [0,1) 15 | #' indicating that responses must be RDP with specific confidence. 16 | #' @slot dims positive scalar numeric dimension of responses. Defaults to 17 | #' \code{NA_integer_} for use with \code{sensitivitySampler()} which can 18 | #' probe \code{target} to determine dimension. 19 | #' 20 | #' @references Cynthia Dwork, Frank McSherry, Kobbi Nissim, and Adam Smith. 21 | #' "Calibrating noise to sensitivity in private data analysis." In Theory of 22 | #' Cryptography Conference, pp. 265-284. Springer Berlin Heidelberg, 2006. 23 | #' 24 | #' @export DPMechLaplace 25 | #' @exportClass DPMechLaplace 26 | DPMechLaplace <- setClass("DPMechLaplace", 27 | contains = "DPMechNumeric" 28 | ) 29 | 30 | #' @describeIn DPMechLaplace automatically prints the object. 31 | #' @param object an instance of class \code{DPMech}. 32 | setMethod("show", "DPMechLaplace", function(object) { 33 | cat("Laplace mechanism\n") 34 | callNextMethod() 35 | }) 36 | 37 | #' \code{DPMechLaplace} response space L1 norm. 38 | #' 39 | #' Represents the L1 norm on \code{target} responses. For internal use. 40 | #' 41 | #' @param object an instance of class \code{\link{DPMechLaplace-class}}. 42 | #' @param rawR1 a non-private response from \code{target}. 43 | #' @param rawR2 a non-private response from \code{target}. 44 | #' @return a non-negative scalar L1 norm between \code{rawR1}, \code{rawR2}. 45 | setMethod(".numericNorm", 46 | signature(object = "DPMechLaplace", 47 | rawR1 = "numeric", 48 | rawR2 = "numeric"), 49 | function(object, rawR1, rawR2) { 50 | return(.l1norm(rawR1 - rawR2)) 51 | } 52 | ) 53 | 54 | #' \code{DPMechLaplace} release response core. 55 | #' 56 | #' Implements the core calculation specific to the \code{DPMechLaplace} 57 | #' subclass \code{releaseResponse()}. Internal function, not to be called. 58 | #' 59 | #' @param object an instance of class \code{\link{DPMechLaplace-class}}. 60 | #' @param rawR a non-private response from \code{target}. 61 | #' @param privacyParams object of type \code{DPParamsEps}. 62 | #' @return a numeric private response. 63 | setMethod(".responseCore", 64 | signature(object = "DPMechLaplace", 65 | rawR = "numeric", 66 | privacyParams = "DPParamsEps"), 67 | function(object, rawR, privacyParams) { 68 | noise <- .rlap(length(rawR), 69 | location = 0, 70 | scale = object@sensitivity / privacyParams@epsilon) 71 | R <- rawR + noise 72 | return(R) 73 | } 74 | ) 75 | -------------------------------------------------------------------------------- /R/mechanisms.R: -------------------------------------------------------------------------------- 1 | #' @include privacy_params.R utils.R 2 | NULL 3 | 4 | #' An S4 class for differentially-private mechanisms. 5 | #' 6 | #' A base class for representing output-perturbing mechanisms in differential 7 | #' privacy. As this class is \code{VIRTUAL} it cannot be instantiated, but it can 8 | #' be subclassed. 9 | #' 10 | #' @slot sensitivity non-negative scalar numeric target sensitivity. Defaults 11 | #' to \code{Inf} for use with \code{sensitivitySampler()}. 12 | #' @slot target the target non-private function to be privatized, takes lists. 13 | #' Defaults to a constant function. 14 | #' @slot gammaSensitivity \code{NA_real_} if inactive, or scalar in [0,1) 15 | #' indicating that responses must be RDP with specific confidence. 16 | #' 17 | #' @references Cynthia Dwork, Frank McSherry, Kobbi Nissim, and Adam Smith. 18 | #' "Calibrating noise to sensitivity in private data analysis." In Theory of 19 | #' Cryptography Conference, pp. 265-284. Springer Berlin Heidelberg, 2006. 20 | #' 21 | #' @seealso \code{\link{DPMechLaplace}} subclass for the Laplace mechanism. 22 | #' 23 | #' @export 24 | setClass("DPMech", 25 | slots = list( 26 | sensitivity = "numeric", 27 | target = "function", 28 | gammaSensitivity = "numeric"), 29 | prototype = prototype( 30 | sensitivity = Inf, 31 | target = .constant_target, 32 | gammaSensitivity = NA_real_), 33 | contains = "VIRTUAL" 34 | ) 35 | 36 | ## A \code{DPMech} should be constructed with an appropriate sensitivity. 37 | setValidity("DPMech", function(object) { 38 | if (length(object@sensitivity) != 1) { 39 | return("DPMech@sensitivity should be a scalar.") 40 | } 41 | if (object@sensitivity < 0) { 42 | return("DPMech@sensitivity should be non-negative.") 43 | } 44 | if (!is.numeric(object@gammaSensitivity) || 45 | length(object@gammaSensitivity) != 1) { 46 | return("DPMech@gammaSensitivity should be scalar numeric.") 47 | } 48 | if (!is.na(object@gammaSensitivity) && 49 | (object@gammaSensitivity < 0 || object@gammaSensitivity >= 1)) { 50 | return("DPMech@gammaSensitivity should be NA_real_ or in [0,1).") 51 | } 52 | return(TRUE) 53 | }) 54 | 55 | #' \code{DPMech} private release method. 56 | #' 57 | #' Runs the differentially-private mechanism on given data. 58 | #' 59 | #' @param mechanism an object of class \code{\link{DPMech-class}}. 60 | #' @param privacyParams an object of class \code{\link{DPParamsEps}} or subclass. 61 | #' @param X a privacy-sensitive dataset, if using sensitivity sampler a: list, 62 | #' matrix, data frame, numeric/character vector. 63 | #' @return list with slots per argument, including at least: actual privacy 64 | #' parameters \code{privacyParams}, and response \code{response}. 65 | setGeneric("releaseResponse", function(mechanism, privacyParams, X) { 66 | standardGeneric("releaseResponse") 67 | }) 68 | 69 | #' \code{DPMech} sensitivity-inducing norm. 70 | #' 71 | #' Norm of a \code{\link{DPMech-class}}'s non-private \code{target} function 72 | #' evaluated on two given databases \code{X1}, \code{X2}. 73 | #' 74 | #' @param mechanism an object of class \code{\link{DPMech-class}}. 75 | #' @param X1 a privacy-sensitive dataset. 76 | #' @param X2 a privacy-sensitive dataset. 77 | setGeneric("sensitivityNorm", function(mechanism, X1, X2) { 78 | standardGeneric("sensitivityNorm") 79 | }) 80 | -------------------------------------------------------------------------------- /R/numeric_mechanism.R: -------------------------------------------------------------------------------- 1 | #' @include mechanisms.R privacy_params.R utils.R 2 | NULL 3 | 4 | #' A virtual S4 class for differentially-private numeric mechanisms. 5 | #' 6 | #' A virtual class that implements common features of Laplace, Gaussian 7 | #' mechanisms from differential privacy, for privatizing numeric vector 8 | #' releases. 9 | #' 10 | #' @slot sensitivity non-negative scalar numeric target sensitivity. 11 | #' Defaults to \code{Inf} for use with \code{sensitivitySampler()}. 12 | #' @slot target the target non-private function to be privatized, takes lists. 13 | #' Defaults to a constant function. Laplace mechanism assumes functions that 14 | #' release numeric vectors of fixed dimension \code{dims}. 15 | #' @slot gammaSensitivity \code{NA_real_} if deactive, or scalar in [0,1) 16 | #' indicating that responses must be RDP with specific confidence. 17 | #' @slot dims positive scalar numeric dimension of responses. Defaults to 18 | #' \code{NA_integer_} for use with \code{sensitivitySampler()} which can 19 | #' probe \code{target} to determine dimension. 20 | #' 21 | #' @export DPMechNumeric 22 | #' @exportClass DPMechNumeric 23 | DPMechNumeric <- setClass("DPMechNumeric", 24 | contains = c("DPMech", "VIRTUAL"), 25 | slots = list(dims = "numeric"), 26 | prototype = prototype(dims = NA_integer_) 27 | ) 28 | 29 | ## A \code{DPMechNumeric} should be constructed with an appropriate dimension. 30 | setValidity("DPMechNumeric", function(object) { 31 | if (!is.na(object@dims) && !.check_integer(object@dims)) { 32 | return("DPMechNumeric@dims should be a scalar natural number.") 33 | } 34 | return(TRUE) 35 | }) 36 | 37 | #' @describeIn DPMechNumeric automatically prints the object. 38 | #' @param object an instance of class \code{DPMech}. 39 | setMethod("show", "DPMechNumeric", function(object) { 40 | cat("Sensitivity:", object@sensitivity, "\n") 41 | if (is.na(object@gammaSensitivity)) { 42 | cat("Sampled sensitivity gamma: NA\n") 43 | } else { 44 | cat("Sampled sensitivity gamma:", object@gammaSensitivity, "\n") 45 | } 46 | cat("Response dimension:", object@dims, "\n") 47 | cat("Target function: \n") 48 | show(object@target) 49 | }) 50 | 51 | #' @describeIn DPMechNumeric measures sensitivity of non-private \code{target}. 52 | #' @param mechanism an object of class \code{DPMechNumeric-class}. 53 | #' @param X1 a privacy-sensitive dataset. 54 | #' @param X2 a privacy-sensitive dataset. 55 | #' @return scalar numeric norm of non-private \code{target} on datasets. 56 | #' @examples 57 | #' f <- function(xs) mean(xs) 58 | #' n <- 100 59 | #' m <- DPMechLaplace(sensitivity = 1/n, target = f, dims = 1) 60 | #' X1 <- runif(n) 61 | #' X2 <- runif(n) 62 | #' sensitivityNorm(m, X1, X2) 63 | #' @export 64 | setMethod("sensitivityNorm", 65 | signature(mechanism = "DPMechNumeric", 66 | X1 = "ANY", 67 | X2 = "ANY"), 68 | function(mechanism, X1, X2) { 69 | rawR1 <- mechanism@target(X1) 70 | rawR2 <- mechanism@target(X2) 71 | if (!is.numeric(rawR1) || !is.numeric(rawR2)) { 72 | stop("Non-private target output non-numeric.") 73 | } 74 | if (is.na(mechanism@dims)) { 75 | warning("No expected dimension set.") 76 | } else { 77 | if (length(rawR1) != mechanism@dims || length(rawR2) != mechanism@dims) { 78 | warning("Non-private target output has unexpected dimension.") 79 | } 80 | } 81 | if (length(rawR1) != length(rawR2)) { 82 | stop("Non-private target output dimensions inconsistent.") 83 | } 84 | if (length(rawR1) == 0) { 85 | return(0) 86 | } 87 | return(.numericNorm(mechanism, rawR1, rawR2)) 88 | } 89 | ) 90 | 91 | #' \code{DPMechNumeric} response space norm. 92 | #' 93 | #' Represents the norm of \code{target} responses. For internal use. 94 | #' 95 | #' @param object an instance of class \code{\link{DPMechNumeric-class}}. 96 | #' @param rawR1 a non-private response from \code{target}. 97 | #' @param rawR2 a non-private response from \code{target}. 98 | #' @return a non-negative scalar norm between \code{rawR1}, \code{rawR2}. 99 | setGeneric(".numericNorm", function(object, rawR1, rawR2) { 100 | standardGeneric(".numericNorm") 101 | }) 102 | 103 | #' \code{DPMechNumeric} release response core. 104 | #' 105 | #' Implements the core calculation specific to the \code{DPMechNUmeric} 106 | #' subclass \code{releaseResponse()}. Internal function, not to be called. 107 | #' 108 | #' @param object an instance of class \code{\link{DPMechNumeric-class}}. 109 | #' @param rawR a non-private response from \code{target}. 110 | #' @param privacyParams object of class (or subclass of) \code{DPParamsEps}. 111 | #' @return a numeric private response. 112 | setGeneric(".responseCore", function(object, rawR, privacyParams) { 113 | standardGeneric(".responseCore") 114 | }) 115 | 116 | #' @describeIn DPMechNumeric releases mechanism responses. 117 | #' @param privacyParams an object of class \code{\link{DPParamsEps}}. 118 | #' @param X a privacy-sensitive dataset, if using sensitivity sampler a: list, 119 | #' matrix, data frame, numeric/character vector. 120 | #' @return list with slots per argument, actual privacy parameter; 121 | #' mechanism response with length of target release: 122 | #' \code{privacyParams, sensitivity, dims, target, response}. 123 | #' @examples 124 | #' f <- function(xs) mean(xs) 125 | #' n <- 100 126 | #' m <- DPMechLaplace(sensitivity = 1/n, target = f, dims = 1) 127 | #' X <- runif(n) 128 | #' p <- DPParamsEps(epsilon = 1) 129 | #' releaseResponse(m, p, X) 130 | #' @export 131 | setMethod("releaseResponse", 132 | signature(mechanism = "DPMechNumeric", 133 | privacyParams = "DPParamsEps", 134 | X = "ANY"), 135 | function(mechanism, privacyParams, X) { 136 | rawR <- mechanism@target(X) 137 | if (!is.numeric(rawR)) { 138 | stop("Non-private target output non-numeric.") 139 | } 140 | if (is.na(mechanism@dims)) { 141 | warning("No expected non-private dims slot set.") 142 | } 143 | if (length(rawR) != mechanism@dims) { 144 | warning("Non-private target output has unexpected dimension.") 145 | } 146 | R <- .responseCore(mechanism, rawR = rawR, privacyParams = privacyParams) 147 | if (is.na(mechanism@gammaSensitivity)) { 148 | p <- privacyParams 149 | } else { 150 | p <- toGamma(privacyParams, mechanism@gammaSensitivity) 151 | } 152 | return(list( 153 | privacyParams = p, 154 | sensitivity = mechanism@sensitivity, 155 | dims = mechanism@dims, 156 | target = mechanism@target, 157 | response = R 158 | )) 159 | } 160 | ) 161 | -------------------------------------------------------------------------------- /R/privacy_params.R: -------------------------------------------------------------------------------- 1 | #' An S4 class for basic differential privacy parameters. 2 | #' 3 | #' An S4 base class representing the basic privacy parameter \eqn{\epsilon} in 4 | #' differential privacy. 5 | #' 6 | #' @slot epsilon positive scalar numeric privacy level. 7 | #' 8 | #' @seealso \code{\link{DPParamsDel}} subclass for \eqn{(\epsilon,\delta)} 9 | #' relaxation, \code{\link{DPParamsGam}} subclass for random relaxation. 10 | #' 11 | #' @export DPParamsEps 12 | #' @exportClass DPParamsEps 13 | DPParamsEps <- setClass("DPParamsEps", 14 | slots = list(epsilon = "numeric"), 15 | prototype = prototype(epsilon = 1.0) 16 | ) 17 | 18 | ## Enforce allowable parameter range for \code{DPParamsEps}. 19 | setValidity("DPParamsEps", function(object) { 20 | if (length(object@epsilon) != 1) { 21 | return("DPParamsEps@epsilon should be a scalar.") 22 | } 23 | if (object@epsilon <= 0) { 24 | return("DPParamsEps@epsilon should be positive.") 25 | } 26 | return(TRUE) 27 | }) 28 | 29 | #' @describeIn DPParamsEps automatically prints the object. 30 | setMethod("show", "DPParamsEps", function(object) { 31 | cat("Differential privacy level \u03B5", object@epsilon, sep = "=") 32 | }) 33 | 34 | setGeneric("getEpsilon", function(object) { 35 | standardGeneric("getEpsilon") 36 | }) 37 | 38 | #' @describeIn DPParamsEps getter for slot \code{epsilon}. 39 | setMethod("getEpsilon", "DPParamsEps", function(object) return(object@epsilon)) 40 | 41 | #' Setter for slot \code{epsilon}. 42 | #' 43 | #' Use this method instead of slot \code{epsilon}. 44 | #' 45 | #' @param object the instance of \code{DPParamsEps}. 46 | #' @param value positive numeric \eqn{\epsilon} value. 47 | #' 48 | #' @seealso \code{\link{DPParamsEps}}. 49 | setGeneric("setEpsilon<-", function(object, value) 50 | standardGeneric("setEpsilon<-")) 51 | 52 | #' @describeIn DPParamsEps setter for slot \code{epsilon}. 53 | #' @param object an object of class \code{\link{DPParamsEps}}. 54 | #' @param value a scalar numeric \eqn{\epsilon}. 55 | setReplaceMethod("setEpsilon", "DPParamsEps", function(object, value) { 56 | object@epsilon <- value 57 | validObject(object) 58 | return(object) 59 | }) 60 | 61 | setGeneric("toGamma", function(object, gamma) { 62 | standardGeneric("toGamma") 63 | }) 64 | 65 | #' @describeIn DPParamsEps returns object to corresponding instance of subclass 66 | #' \code{\link{DPParamsGam}}. 67 | #' @param gamma a scalar numeric \eqn{\gamma}. 68 | setMethod("toGamma", signature(object = "DPParamsEps", gamma = "numeric"), 69 | function(object, gamma) { 70 | p <- as(object, "DPParamsGam", strict = TRUE) 71 | setDelta(p) <- 0 72 | setGamma(p) <- gamma 73 | return(p) 74 | } 75 | ) 76 | 77 | #' An S4 class for relaxed differential privacy parameters. 78 | #' 79 | #' An S4 base class representing the privacy parameters in 80 | #' \eqn{(\epsilon,\delta)}-differential privacy. 81 | #' 82 | #' @slot epsilon positive scalar numeric privacy level. 83 | #' @slot delta a scalar numeric privacy level in interval [0,1). 84 | #' 85 | #' @seealso \code{\link{DPParamsEps}} superclass, 86 | #' \code{\link{DPParamsGam}} subclass for random relaxation. 87 | #' 88 | #' @export DPParamsDel 89 | #' @exportClass DPParamsDel 90 | DPParamsDel <- setClass("DPParamsDel", 91 | slots = list(delta = "numeric"), 92 | contains = "DPParamsEps", 93 | prototype = prototype(epsilon = 1.0, delta=0.0) 94 | ) 95 | 96 | ## Enforce allowable parameter range for \code{DPParamsDel}. 97 | setValidity("DPParamsDel", function(object) { 98 | if (length(object@delta) != 1) { 99 | return("DPParamsDel@delta should be a scalar.") 100 | } 101 | if (object@delta < 0 || object@delta >= 1) { 102 | return("DPParamsDel@delta should be in [0,1).") 103 | } 104 | return(TRUE) 105 | }) 106 | 107 | #' @describeIn DPParamsDel automatically prints the object. 108 | setMethod("show", "DPParamsDel", function(object) { 109 | cat("Differential privacy level ", 110 | "\u03B5=", object@epsilon, 111 | ", \u03B4=", object@delta, sep="") 112 | }) 113 | 114 | setGeneric("getDelta", function(object) { 115 | standardGeneric("getDelta") 116 | }) 117 | 118 | #' @describeIn DPParamsDel getter for slot \code{delta}. 119 | setMethod("getDelta", "DPParamsDel", function(object) return(object@delta)) 120 | 121 | #' Setter for slot \code{delta}. 122 | #' 123 | #' Use this method instead of slot \code{delta}. 124 | #' 125 | #' @param object the instance of \code{DPParamsDel}. 126 | #' @param value positive numeric \eqn{\delta} value. 127 | #' 128 | #' @seealso \code{\link{DPParamsDel}}. 129 | setGeneric("setDelta<-", function(object, value) 130 | standardGeneric("setDelta<-")) 131 | 132 | #' @describeIn DPParamsDel setter for slot \code{delta}. 133 | #' @param object an object of class \code{\link{DPParamsDel}}. 134 | #' @param value a scalar numeric \eqn{\delta}. 135 | setReplaceMethod("setDelta", "DPParamsDel", function(object, value) { 136 | object@delta <- value 137 | validObject(object) 138 | return(object) 139 | }) 140 | 141 | #' @describeIn DPParamsDel returns object to corresponding instance of subclass 142 | #' \code{\link{DPParamsGam}}. 143 | #' @param gamma a scalar numeric \eqn{\gamma}. 144 | setMethod("toGamma", signature(object = "DPParamsDel", gamma = "numeric"), 145 | function(object, gamma) { 146 | p <- as(object, "DPParamsGam", strict = TRUE) 147 | setGamma(p) <- gamma 148 | return(p) 149 | } 150 | ) 151 | 152 | #' An S4 class for random differential privacy parameters. 153 | #' 154 | #' An S4 base class representing the privacy parameters in 155 | #' \eqn{(\epsilon,\delta,\gamma)}-random differential privacy. 156 | #' 157 | #' @slot epsilon positive scalar numeric privacy level. 158 | #' @slot delta a scalar numeric privacy level in interval [0,1). 159 | #' @slot gamma a scalar numeric privacy level in [0, 1). 160 | #' 161 | #' @seealso \code{\link{DPParamsEps}}, \code{\link{DPParamsDel}} superclasses. 162 | #' 163 | #' @export DPParamsGam 164 | #' @exportClass DPParamsGam 165 | DPParamsGam <- setClass("DPParamsGam", 166 | slots = list(gamma = "numeric"), 167 | contains = "DPParamsDel", 168 | prototype = prototype(epsilon = 1.0, delta = 0.0, gamma = 0.05) 169 | ) 170 | 171 | ## Enforce allowable parameter range for \code{DPParamsGam}. 172 | setValidity("DPParamsGam", function(object) { 173 | if (length(object@gamma) != 1) { 174 | return("DPParamsGam@gamma should be a scalar.") 175 | } 176 | if (object@gamma < 0 || object@gamma >= 1) { 177 | return("DPParamsGam@gamma should be in [0,1).") 178 | } 179 | return(TRUE) 180 | }) 181 | 182 | #' @describeIn DPParamsGam automatically prints the object. 183 | setMethod("show", "DPParamsGam", function(object) { 184 | cat("Random differential privacy level ", 185 | "\u03B5=", object@epsilon, 186 | ", \u03B4=", object@delta, 187 | ", \u03B3=", object@gamma, sep="") 188 | }) 189 | 190 | setGeneric("getGamma", function(object) { 191 | standardGeneric("getGamma") 192 | }) 193 | 194 | #' @describeIn DPParamsGam getter for slot \code{gamma}. 195 | setMethod("getGamma", "DPParamsGam", function(object) return(object@gamma)) 196 | 197 | #' Setter for slot \code{gamma}. 198 | #' 199 | #' Use this method instead of slot \code{gamma}. 200 | #' 201 | #' @param object the instance of \code{DPParamsGam}. 202 | #' @param value positive numeric \eqn{\gamma} value. 203 | #' 204 | #' @seealso \code{\link{DPParamsGam}}. 205 | setGeneric("setGamma<-", function(object, value) 206 | standardGeneric("setGamma<-")) 207 | 208 | #' @describeIn DPParamsGam setter for slot \code{gamma}. 209 | #' @param object an object of class \code{\link{DPParamsGam}}. 210 | #' @param value a scalar numeric \eqn{\gamma}. 211 | setReplaceMethod("setGamma", "DPParamsGam", function(object, value) { 212 | object@gamma <- value 213 | validObject(object) 214 | return(object) 215 | }) 216 | 217 | #' @describeIn DPParamsGam returns object with set gamma; generic for use with 218 | #' superclasses \code{\link{DPParamsEps}} and \code{\link{DPParamsDel}}. 219 | #' @param gamma scalar numeric \eqn{\gamma}. 220 | setMethod("toGamma", signature(object = "DPParamsGam", gamma = "numeric"), 221 | function(object, gamma) { 222 | warning("Calling toGamma() on DPParamsGam same as setGamma().") 223 | setGamma(object) <- gamma 224 | return(object) 225 | } 226 | ) 227 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | #' Check is Integral. 2 | #' 3 | #' Checks that a numeric has no fractional part. 4 | #' 5 | #' While \link[base]{is.integer} returns \code{TRUE} when given an object of type 6 | #' \code{integer}, it always returns \code{FALSE} on non-floating $\code{numeric}s. 7 | #' This function ignores class, and indicates absence of fractional part. 8 | #' 9 | #' @param n a singleton numeric. 10 | #' @return Boolean that \code{n} is singleton numeric with no fractional part. 11 | #' 12 | #' @seealso \link[base]{is.integer} for checking for objects of type \code{integer}. 13 | #' 14 | #' @examples 15 | #' .check_integer(5) # TRUE 16 | #' .check_integer(5.0) # FALSE 17 | #' .check_integer(as.integer(5)) # TRUE 18 | .check_integer <- function(n) { 19 | is.numeric(n) && length(n) == 1 && n %% 1 == 0 20 | } 21 | 22 | #' The Laplace Distribution 23 | #' 24 | #' Random generation for the Laplace distribution with location \code{location} 25 | #' and scale \code{scale}. 26 | #' 27 | #' If \code{location} is not specified, it assumes the default value of \code{0}. 28 | #' If \code{scale} is not specified, it assumes the default value of \code{1}. 29 | #' 30 | #' The Laplace distribution with real location \eqn{\mu} and scale \eqn{b>0} has 31 | #' density 32 | #' \deqn{f(x)=\frac{1}{2b}\exp\left(-\frac{|x-\mu|}{b}\right)}{% 33 | #' f(x)=exp(-|x-\mu|/b)/(2b)} 34 | #' for real \eqn{x}. 35 | #' 36 | #' @param n of observations (singleton numeric). 37 | #' @param location the location (singleton numeric). 38 | #' @param scale the scale (singelton numeric). 39 | #' @return The length of the numeric result is determined by \code{n}. 40 | #' 41 | #' @source Uses \link[stats]{rexp}. 42 | #' 43 | #' @seealso \link[stats]{rexp} for random generation from the exponential distribution. 44 | #' 45 | #' @examples 46 | #' rlap(5) 47 | #' rlap(5, location=5) 48 | #' rlap(5, location=5, scale=0.5) 49 | .rlap <- function(n, location = 0, scale = 1) { 50 | if (!.check_integer(n) || n < 0) 51 | stop("Given sample size is not scalar non-negative integer.") 52 | if (!is.numeric(location) | length(location) != 1) 53 | stop("Given location is a not a scalar numeric.") 54 | if (!is.numeric(scale) || length(scale) != 1 || scale < 0) 55 | stop("Given scale is not scalar non-negative.") 56 | if (scale <= 0) 57 | rep(location, n) 58 | rep(location, n) + 59 | stats::rexp(n = n, rate = 1/scale) - 60 | stats::rexp(n = n, rate = 1/scale) 61 | } 62 | 63 | #' The L1 norm. 64 | #' 65 | #' L1 norm of a numeric vector. 66 | #' 67 | #' Returns \code{0} for \code{xs} of length zero; otherwise the sum of absolutes. 68 | #' 69 | #' @param xs a numeric vector. 70 | #' @return The sum of absolutes of \code{xs}. 71 | #' 72 | #' @examples 73 | #' xs <- c(-2.5, 1, 2) 74 | #' .l1norm(xs) # 5.5 75 | .l1norm <- function(xs) { 76 | if (!is.numeric(xs)) 77 | stop("Given object is not numeric.") 78 | if (length(xs) == 0) 79 | return(0) 80 | return(sum(abs(xs))) 81 | } 82 | 83 | #' The L2 norm. 84 | #' 85 | #' L2 norm of a numeric vector. 86 | #' 87 | #' Returns \code{0} for \code{xs} of length zero; otherwise the square root of 88 | #' sum of squares. 89 | #' 90 | #' @param xs a numeric vector. 91 | #' @return The L2 norm of \code{xs}. 92 | #' 93 | #' @examples 94 | #' xs <- c(-2.5, 1, 2) 95 | #' .l2norm(xs) # 3.35 96 | .l2norm <- function(xs) { 97 | if (!is.numeric(xs)) 98 | stop("Given object is not numeric.") 99 | if (length(xs) == 0) 100 | return(0) 101 | return(sqrt(sum(xs^2))) 102 | } 103 | 104 | #' The L_Infty norm. 105 | #' 106 | #' L_Infty norm of a numeric vector. 107 | #' 108 | #' Returns \code{0} for \code{xs} of length zero; otherwise the max of absolutes. 109 | #' 110 | #' @param xs a numeric vector. 111 | #' @return The max of absolutes of \code{xs}. 112 | #' 113 | #' @examples 114 | #' xs <- c(-2.5, 1, 2) 115 | #' .linfty_norm(xs) # 2.5 116 | .linfty_norm <- function(xs) { 117 | if (!is.numeric(xs)) 118 | stop("Given object is not numeric.") 119 | if (length(xs) == 0) 120 | return(0) 121 | return(max(abs(xs))) 122 | } 123 | 124 | #' Constant-valued function. 125 | #' 126 | #' A default target function that outputs response zero. 127 | #' 128 | #' @param X arbitrary dataset object. 129 | #' @return A response that does not depend on \code{X}. 130 | .constant_target <- function(X) { 131 | return(0) 132 | } 133 | 134 | #' Flexible concatenation. 135 | #' 136 | #' A helper function for concatenation. 137 | #' 138 | #' @param xs object of type matrix, data.frame, list, numeric, char. 139 | #' @param x object of type corresponding to a singleton element of \code{xs}: 140 | #' such that for matrices/data frames \code{rbind()} runs without warning, or 141 | #' for lists or vectors \code{[[]]} or \code{[]} subsetting can be used to 142 | #' concatenate. 143 | #' @return The result of concatenating \code{xs} followed by \code{x}. 144 | .generic_append <- function(xs, x) { 145 | if (is.matrix(xs) || is.data.frame(xs)) { 146 | return(rbind(xs, x)) 147 | } else if (is.list(xs)) { 148 | xs[[length(xs) + 1]] <- x 149 | return(xs) 150 | } else if (is.numeric(xs) || is.character(xs)) { 151 | xs[length(xs) + 1] <- x 152 | return(xs) 153 | } 154 | stop("Unrecognized xs type.") 155 | } 156 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | github_document: 4 | html_preview: false 5 | --- 6 | 7 | 8 | 9 | ```{r, echo = FALSE} 10 | knitr::opts_chunk$set( 11 | collapse = TRUE, 12 | comment = "#>", 13 | fig.path = "README-" 14 | ) 15 | set.seed(3033362) # for reproducibility 16 | ``` 17 | 18 | # diffpriv 19 | 20 | ```{r, echo = FALSE} 21 | #version <- as.vector(read.dcf('DESCRIPTION')[, 'Version']) 22 | #version <- gsub('-', '.', version) 23 | version <- "0.4.2.9000" 24 | ``` 25 | 26 | ```{r, echo = FALSE} 27 | #dep <- as.vector(read.dcf('DESCRIPTION')[, 'Depends']) 28 | #m <- regexpr('R *\\(>= \\d+.\\d+.\\d+\\)', dep) 29 | #rm <- regmatches(dep, m) 30 | #rvers <- gsub('.*(\\d+.\\d+.\\d+).*', '\\1', rm) 31 | rvers <- "3.4.0" 32 | ``` 33 | 34 | [![packageversion](https://img.shields.io/badge/Package%20version-`r version`-orange.svg?style=flat-square)](commits/master) 35 | [![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/diffpriv)](https://cran.r-project.org/package=diffpriv) 36 | [![Travis Build Status](https://travis-ci.org/brubinstein/diffpriv.svg?branch=master)](https://travis-ci.org/brubinstein/diffpriv) 37 | [![Coverage Status](https://img.shields.io/codecov/c/github/brubinstein/diffpriv/master.svg)](https://codecov.io/github/brubinstein/diffpriv?branch=master) 38 | [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](http://choosealicense.com/licenses/mit/) 39 | [![minimal R version](https://img.shields.io/badge/R%3E%3D-`r rvers`-6666ff.svg)](https://cran.r-project.org/) 40 | 41 | ## Overview 42 | 43 | The `diffpriv` package makes privacy-aware data science in R easy. 44 | `diffpriv` implements the formal framework of differential privacy: 45 | differentially-private mechanisms can safely release to untrusted third parties: 46 | statistics computed, models fit, or arbitrary structures derived on 47 | privacy-sensitive data. Due to the worst-case nature of the framework, mechanism 48 | development typically requires involved theoretical analysis. `diffpriv` offers 49 | a turn-key approach to differential privacy by automating this process with 50 | sensitivity sampling in place of theoretical sensitivity analysis. 51 | 52 | ## Installation 53 | 54 | Obtaining `diffpriv` is easy. From within R: 55 | 56 | ```{r eval=FALSE} 57 | ## Install the release version of diffpriv from CRAN: 58 | install.packages("diffpriv") 59 | 60 | ## Install the latest development version of diffpriv from GitHub: 61 | install.packages("devtools") 62 | devtools::install_github("brubinstein/diffpriv") 63 | ``` 64 | 65 | ## Example 66 | 67 | A typical example in differential privacy is privately releasing a simple 68 | `target` function of privacy-sensitive input data `X`. Say the mean of 69 | `numeric` data: 70 | 71 | ```{r example-1} 72 | ## a target function we'd like to run on private data X, releasing the result 73 | target <- function(X) mean(X) 74 | ``` 75 | 76 | First load the `diffpriv` package (installed as above) and construct a 77 | chosen differentially-private mechanism for privatizing `target`. 78 | 79 | ```{r example-2} 80 | ## target seeks to release a numeric, so we'll use the Laplace mechanism---a 81 | ## standard generic mechanism for privatizing numeric responses 82 | library(diffpriv) 83 | mech <- DPMechLaplace(target = target) 84 | ``` 85 | 86 | To run `mech` on a dataset `X` we must first determine the sensitivity of 87 | `target` to small changes to input dataset. One avenue is to analytically bound 88 | sensitivity (on paper; see the [vignette](http://brubinstein.github.io/diffpriv/articles/diffpriv.pdf)) and supply it 89 | via the `sensitivity` argument of mechanism construction: in this case not hard 90 | if we assume bounded data, but in general sensitivity can be very non-trivial 91 | to calculate manually. The other approach, which we follow in this example, is 92 | sensitivity sampling: repeated probing of `target` to estimate sensitivity 93 | automatically. We need only specify a distribution for generating random probe 94 | datasets; `sensitivitySampler()` takes care of the rest. The price we pay for 95 | this convenience is the weaker form of random differential privacy. 96 | 97 | ```{r example-3} 98 | ## set a dataset sampling distribution, then estimate target sensitivity with 99 | ## sufficient samples for subsequent mechanism responses to achieve random 100 | ## differential privacy with confidence 1-gamma 101 | distr <- function(n) rnorm(n) 102 | mech <- sensitivitySampler(mech, oracle = distr, n = 5, gamma = 0.1) 103 | mech@sensitivity ## DPMech and subclasses are S4: slots accessed via @ 104 | ``` 105 | 106 | With a sensitivity-calibrated mechanism in hand, we can release private 107 | responses on a dataset `X`, displayed alongside the non-private response 108 | for comparison: 109 | 110 | ```{r example-4} 111 | X <- c(0.328,-1.444,-0.511,0.154,-2.062) # length is sensitivitySampler() n 112 | r <- releaseResponse(mech, privacyParams = DPParamsEps(epsilon = 1), X = X) 113 | cat("Private response r$response: ", r$response, 114 | "\nNon-private response target(X):", target(X)) 115 | ``` 116 | 117 | ## Getting Started 118 | 119 | The above example demonstrates the main components of `diffpriv`: 120 | 121 | * Virtual class `DPMech` for generic mechanisms that captures the non-private 122 | `target` and releases privatized responses from it. Current subclasses 123 | + `DPMechLaplace`, `DPMechGaussian`: the Laplace and Gaussian mechanisms 124 | for releasing numeric responses with additive noise; 125 | + `DPMechExponential`: the exponential mechanism for privately 126 | optimizing over finite sets (which need not be numeric); and 127 | + `DPMechBernstein`: the Bernstein mechanism for privately releasing 128 | multivariate real-valued functions. See the 129 | [bernstein vignette](http://brubinstein.github.io/diffpriv/articles/bernstein.pdf) for more. 130 | * Class `DPParamsEps` and subclasses for encapsulating privacy parameters. 131 | * `sensitivitySampler()` method of `DPMech` subclasses estimates target 132 | sensitivity necessary to run `releaseResponse()` of `DPMech` generic 133 | mechanisms. This provides an easy alternative to exact sensitivity bounds 134 | requiring mathematical analysis. The sampler repeatedly probes 135 | `DPMech@target` to estimate sensitivity to data perturbation. Running 136 | mechanisms with obtained sensitivities yield random differential privacy. 137 | 138 | Read the [package vignette](http://brubinstein.github.io/diffpriv/articles/diffpriv.pdf) for more, or [news](http://brubinstein.github.io/diffpriv/news/index.html) 139 | for the latest release notes. 140 | 141 | ## Citing the Package 142 | 143 | `diffpriv` is an open-source package offered with a permissive MIT License. 144 | Please acknowledge use of `diffpriv` by citing the paper on the sensitivity 145 | sampler: 146 | 147 | > Benjamin I. P. Rubinstein and Francesco Aldà. "Pain-Free Random Differential 148 | > Privacy with Sensitivity Sampling", to appear in the 34th International 149 | > Conference on Machine Learning (ICML'2017), 2017. 150 | 151 | Other relevant references to cite depending on usage: 152 | 153 | * **Differential privacy and the Laplace mechanism:** 154 | Cynthia Dwork, Frank McSherry, Kobbi Nissim, and Adam Smith. "Calibrating 155 | noise to sensitivity in private data analysis." In Theory of Cryptography 156 | Conference, pp. 265-284. Springer Berlin Heidelberg, 2006. 157 | * **The Gaussian mechanism:** Cynthia Dwork and Aaron Roth. "The algorithmic 158 | foundations of differential privacy." Foundations and Trends in Theoretical 159 | Computer Science 9(3–4), pp. 211-407, 2014. 160 | * **The exponential mechanism:** Frank McSherry and Kunal Talwar. "Mechanism 161 | design via differential privacy." In the 48th Annual IEEE Symposium on 162 | Foundations of Computer Science (FOCS'07), pp. 94-103. IEEE, 2007. 163 | * **The Bernstein mechanism:** Francesco Aldà and Benjamin I. P. Rubinstein. 164 | "The Bernstein Mechanism: Function Release under Differential Privacy." In 165 | Proceedings of the 31st AAAI Conference on Artificial Intelligence 166 | (AAAI'2017), pp. 1705-1711, 2017. 167 | * **Random differential privacy:** Rob Hall, Alessandro Rinaldo, and Larry 168 | Wasserman. "Random Differential Privacy." Journal of Privacy and 169 | Confidentiality, 4(2), pp. 43-59, 2012. 170 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | diffpriv 4 | ========================================================= 5 | 6 | [![packageversion](https://img.shields.io/badge/Package%20version-0.4.2.9000-orange.svg?style=flat-square)](commits/master) [![CRAN\_Status\_Badge](http://www.r-pkg.org/badges/version/diffpriv)](https://cran.r-project.org/package=diffpriv) [![Travis Build Status](https://travis-ci.org/brubinstein/diffpriv.svg?branch=master)](https://travis-ci.org/brubinstein/diffpriv) [![Coverage Status](https://img.shields.io/codecov/c/github/brubinstein/diffpriv/master.svg)](https://codecov.io/github/brubinstein/diffpriv?branch=master) [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](http://choosealicense.com/licenses/mit/) [![minimal R version](https://img.shields.io/badge/R%3E%3D-3.4.0-6666ff.svg)](https://cran.r-project.org/) 7 | 8 | Overview 9 | -------- 10 | 11 | The `diffpriv` package makes privacy-aware data science in R easy. `diffpriv` implements the formal framework of differential privacy: differentially-private mechanisms can safely release to untrusted third parties: statistics computed, models fit, or arbitrary structures derived on privacy-sensitive data. Due to the worst-case nature of the framework, mechanism development typically requires involved theoretical analysis. `diffpriv` offers a turn-key approach to differential privacy by automating this process with sensitivity sampling in place of theoretical sensitivity analysis. 12 | 13 | Installation 14 | ------------ 15 | 16 | Obtaining `diffpriv` is easy. From within R: 17 | 18 | ``` r 19 | ## Install the release version of diffpriv from CRAN: 20 | install.packages("diffpriv") 21 | 22 | ## Install the latest development version of diffpriv from GitHub: 23 | install.packages("devtools") 24 | devtools::install_github("brubinstein/diffpriv") 25 | ``` 26 | 27 | Example 28 | ------- 29 | 30 | A typical example in differential privacy is privately releasing a simple `target` function of privacy-sensitive input data `X`. Say the mean of `numeric` data: 31 | 32 | ``` r 33 | ## a target function we'd like to run on private data X, releasing the result 34 | target <- function(X) mean(X) 35 | ``` 36 | 37 | First load the `diffpriv` package (installed as above) and construct a chosen differentially-private mechanism for privatizing `target`. 38 | 39 | ``` r 40 | ## target seeks to release a numeric, so we'll use the Laplace mechanism---a 41 | ## standard generic mechanism for privatizing numeric responses 42 | library(diffpriv) 43 | mech <- DPMechLaplace(target = target) 44 | ``` 45 | 46 | To run `mech` on a dataset `X` we must first determine the sensitivity of `target` to small changes to input dataset. One avenue is to analytically bound sensitivity (on paper; see the [vignette](http://brubinstein.github.io/diffpriv/articles/diffpriv.pdf)) and supply it via the `sensitivity` argument of mechanism construction: in this case, it is not hard if we assume bounded data, but in general sensitivity can be very non-trivial to calculate manually. The other approach, which we follow in this example, is sensitivity sampling: repeated probing of `target` to estimate sensitivity automatically. We need only specify a distribution for generating random probe datasets; `sensitivitySampler()` takes care of the rest. The price we pay for this convenience is the weaker form of random differential privacy. 47 | 48 | ``` r 49 | ## set a dataset sampling distribution, then estimate target sensitivity with 50 | ## sufficient samples for subsequent mechanism responses to achieve random 51 | ## differential privacy with confidence 1-gamma 52 | distr <- function(n) rnorm(n) 53 | mech <- sensitivitySampler(mech, oracle = distr, n = 5, gamma = 0.1) 54 | #> Sampling sensitivity with m=285 gamma=0.1 k=285 55 | mech@sensitivity ## DPMech and subclasses are S4: slots accessed via @ 56 | #> [1] 0.8089517 57 | ``` 58 | 59 | With a sensitivity-calibrated mechanism in hand, we can release private responses on a dataset `X`, displayed alongside the non-private response for comparison: 60 | 61 | ``` r 62 | X <- c(0.328,-1.444,-0.511,0.154,-2.062) # length is sensitivitySampler() n 63 | r <- releaseResponse(mech, privacyParams = DPParamsEps(epsilon = 1), X = X) 64 | cat("Private response r$response: ", r$response, 65 | "\nNon-private response target(X):", target(X)) 66 | #> Private response r$response: -1.119506 67 | #> Non-private response target(X): -0.707 68 | ``` 69 | 70 | Getting Started 71 | --------------- 72 | 73 | The above example demonstrates the main components of `diffpriv`: 74 | 75 | - Virtual class `DPMech` for generic mechanisms that captures the non-private `target` and releases privatized responses from it. Current subclasses 76 | - `DPMechLaplace`, `DPMechGaussian`: the Laplace and Gaussian mechanisms for releasing numeric responses with additive noise; 77 | - `DPMechExponential`: the exponential mechanism for privately optimizing over finite sets (which need not be numeric); and 78 | - `DPMechBernstein`: the Bernstein mechanism for privately releasing multivariate real-valued functions. See the [bernstein vignette](http://brubinstein.github.io/diffpriv/articles/bernstein.pdf) for more. 79 | - Class `DPParamsEps` and subclasses for encapsulating privacy parameters. 80 | - `sensitivitySampler()` method of `DPMech` subclasses estimates target sensitivity necessary to run `releaseResponse()` of `DPMech` generic mechanisms. This provides an easy alternative to exact sensitivity bounds requiring mathematical analysis. The sampler repeatedly probes `DPMech@target` to estimate sensitivity to data perturbation. Running mechanisms with obtained sensitivities yield random differential privacy. 81 | 82 | Read the [package vignette](http://brubinstein.github.io/diffpriv/articles/diffpriv.pdf) for more, or [news](http://brubinstein.github.io/diffpriv/news/index.html) for the latest release notes. 83 | 84 | Citing the Package 85 | ------------------ 86 | 87 | `diffpriv` is an open-source package offered with a permissive MIT License. Please acknowledge use of `diffpriv` by citing the paper on the sensitivity sampler: 88 | 89 | > Benjamin I. P. Rubinstein and Francesco Aldà. "Pain-Free Random Differential Privacy with Sensitivity Sampling", to appear in the 34th International Conference on Machine Learning (ICML'2017), 2017. 90 | 91 | Other relevant references to cite depending on usage: 92 | 93 | - **Differential privacy and the Laplace mechanism:** Cynthia Dwork, Frank McSherry, Kobbi Nissim, and Adam Smith. "Calibrating noise to sensitivity in private data analysis." In Theory of Cryptography Conference, pp. 265-284. Springer Berlin Heidelberg, 2006. 94 | - **The Gaussian mechanism:** Cynthia Dwork and Aaron Roth. "The algorithmic foundations of differential privacy." Foundations and Trends in Theoretical Computer Science 9(3–4), pp. 211-407, 2014. 95 | - **The exponential mechanism:** Frank McSherry and Kunal Talwar. "Mechanism design via differential privacy." In the 48th Annual IEEE Symposium on Foundations of Computer Science (FOCS'07), pp. 94-103. IEEE, 2007. 96 | - **The Bernstein mechanism:** Francesco Aldà and Benjamin I. P. Rubinstein. "The Bernstein Mechanism: Function Release under Differential Privacy." In Proceedings of the 31st AAAI Conference on Artificial Intelligence (AAAI'2017), pp. 1705-1711, 2017. 97 | - **Random differential privacy:** Rob Hall, Alessandro Rinaldo, and Larry Wasserman. "Random Differential Privacy." Journal of Privacy and Confidentiality, 4(2), pp. 43-59, 2012. 98 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: http://brubinstein.github.io/diffpriv 2 | 3 | template: 4 | params: 5 | bootswatch: flatly 6 | 7 | reference: 8 | - title: Mechanisms 9 | desc: Generic mechanisms for differential privacy. 10 | contents: 11 | - starts_with("DPMech") 12 | - title: Sensitivity Sampling 13 | desc: Automatically estimating non-private target function sensitivity. 14 | contents: 15 | - sensitivitySampler 16 | - title: Privacy Parameters 17 | desc: Encapsulating privacy budget. 18 | contents: 19 | - starts_with("DPParams") 20 | 21 | navbar: 22 | left: 23 | - icon: fa-home fa-lg 24 | href: index.html 25 | - text: "Tutorials (pdf)" 26 | menu: 27 | - text: "diffpriv package" 28 | href: articles/diffpriv.pdf 29 | - text: "Bernstein mechanism" 30 | href: articles/bernstein.pdf 31 | - text: "Docs" 32 | href: reference/index.html 33 | - text: "News" 34 | href: news/index.html 35 | 36 | authors: 37 | Benjamin Rubinstein: 38 | href: http://bipr.net 39 | Francesco Aldà: 40 | href: http://www.ruhr-uni-bochum.de/lmi/alda/ 41 | -------------------------------------------------------------------------------- /build_site.R: -------------------------------------------------------------------------------- 1 | ## Replaces function pkgdown::build_site with one that copies vignette PDFs 2 | ## from inst/doc/ (produced after devtools::build_vignettes() is called), to a 3 | ## new subdirectory docs/articles. Only those vignette PDFs listed in the articles 4 | ## argument are copied over. E.g. might pass "diffpriv.pdf" as an argument. 5 | ## Useful in concert with manual navbar items linking to these newly-copied PDFs, 6 | ## as specified in the _pkgdown.yml config file. 7 | ## 8 | ## Typical workflow: 9 | ## Clean and Rebuild 10 | ## devtools::document() 11 | ## devtools::build_vignettes() 12 | ## [manually update pkg version (and if necessary min R version) in README.rmd] 13 | ## knit README.rmd 14 | ## source this file; build_site(articles = c("diffpriv.pdf", "bernstein.pdf")) 15 | ## CHECK 16 | 17 | library(pkgdown) 18 | 19 | build_site <- function (pkg = ".", path = "docs", examples = TRUE, run_dont_run = FALSE, 20 | mathjax = TRUE, preview = interactive(), seed = 1014, encoding = "UTF-8", 21 | articles = c()) 22 | { 23 | #old <- set_pkgdown_env("true") 24 | #on.exit(set_pkgdown_env(old)) 25 | pkg <- as_pkgdown(pkg) 26 | path <- rel_path(path, pkg$path) 27 | init_site(pkg, path) 28 | build_home(pkg, path = path, encoding = encoding) 29 | build_reference(pkg, lazy = FALSE, examples = examples, run_dont_run = run_dont_run, 30 | mathjax = mathjax, seed = seed, path = file.path(path, 31 | "reference"), depth = 1L) 32 | #build_articles(pkg, path = file.path(path, "articles"), depth = 1L, 33 | # encoding = encoding) 34 | build_news(pkg, path = file.path(path, "news"), depth = 1L) 35 | #if (preview) { 36 | # preview_site(path) 37 | #} 38 | ### New bits for copying articles 39 | if (length(articles) > 0) { 40 | message("Copying articles") 41 | vpath <- file.path(rel_path("inst", pkg$path), "doc") 42 | vpathNew <- file.path(path, "articles") 43 | dir.create(vpathNew, showWarnings = FALSE) 44 | for (article in articles) { 45 | message(" Article: ", article) 46 | oldPath <- file.path(vpath, article) 47 | if (file.exists(oldPath)) { 48 | file.copy(oldPath, file.path(vpathNew, article)) 49 | } else { 50 | warning("File ", article, " not found.") 51 | } 52 | } 53 | } 54 | ## End articles 55 | invisible(TRUE) 56 | } 57 | 58 | build_site(articles = c("diffpriv.pdf", "bernstein.pdf")) 59 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Resubmission 2 | This is a resubmission. In this version I have: 3 | * Added identifers to the two DESCRIPTION-Description references in the proper 4 | format as directed. One as a doi, the other as a standard arxiv identifier as 5 | it is in press but on the arXiv - published but not with a doi. 6 | 7 | ## Test environments 8 | * local win7 install, R 3.4.1 9 | * win-builder (devel and release) 10 | * ubuntu 14.04.5 LTS (on travis-ci), R 3.4.0 11 | 12 | ## R CMD check results 13 | There were no ERRORs, WARNINGs or NOTEs. 14 | 15 | ## Downstream dependencies 16 | There are currently no downstream dependencies for this package. 17 | -------------------------------------------------------------------------------- /diffpriv.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | -------------------------------------------------------------------------------- /docs/LICENSE.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | License • diffpriv 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 |
41 |
42 | 94 | 95 | 96 |
97 | 98 |
99 |
100 | 103 | 104 |
YEAR: 2017
105 | COPYRIGHT HOLDER: Benjamin I. P. Rubinstein
106 | 
107 | 108 |
109 | 110 |
111 | 112 | 113 |
114 | 117 | 118 |
119 |

Site built with pkgdown.

120 |
121 | 122 |
123 |
124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /docs/articles/bernstein.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/articles/bernstein.pdf -------------------------------------------------------------------------------- /docs/articles/diffpriv.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/articles/diffpriv.pdf -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Citation and Authors • diffpriv 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 |
41 |
42 | 94 | 95 | 96 |
97 | 98 |
99 |
100 | 101 | 104 | 105 |

Rubinstein BIP and Alda F (2017). 106 | “Pain-Free Random Differential Privacy with Sensitivity Sampling.” 107 | In 34th International Conference on Machine Learning (ICML'2017). 108 |

109 |
@InProceedings{,
110 |   title = {Pain-Free Random Differential Privacy with Sensitivity Sampling},
111 |   author = {Benjamin I. P. Rubinstein and Francesco Alda},
112 |   year = {2017},
113 |   booktitle = {34th International Conference on Machine Learning (ICML'2017)},
114 | }
115 | 118 | 119 |
    120 |
  • 121 |

    Benjamin Rubinstein. Author, maintainer. 122 |

    123 |
  • 124 |
  • 125 |

    Francesco Aldà. Author. 126 |

    127 |
  • 128 |
129 | 130 |
131 | 132 |
133 | 134 | 135 |
136 | 139 | 140 |
141 |

Site built with pkgdown.

142 |
143 | 144 |
145 |
146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/favicon.ico -------------------------------------------------------------------------------- /docs/jquery.sticky-kit.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 3 | */ 4 | (function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k)); 5 | if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("
"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q, 6 | u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),eb&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}), 8 | a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize", 9 | y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/logo.png -------------------------------------------------------------------------------- /docs/news/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | All news • diffpriv 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 |
41 |
42 | 94 | 95 | 96 |
97 | 98 |
99 | 100 |
101 | 104 | 105 |
106 |
107 |

108 | diffpriv 0.4.2

109 |
    110 |
  • Second vignette bernstein on: Bernstein approximations and use of DPMechBernstein for private function release.
  • 111 |
  • Minor edits to docs
  • 112 |
113 |
114 |
115 |

116 | diffpriv 0.4.1

117 |
    118 |
  • Expanding test coverage of Bernstein mechanism and function approximation code.
  • 119 |
120 |
121 |
122 |

123 | diffpriv 0.4.0

124 |
    125 |
  • Addition of S3 constructor and predict() generic implementation for fitting (non-iterated) Bernstein polynomial function approximations.
  • 126 |
  • Addition of DPMechBernstein class implementing the Bernstein mechanism of Alda and Rubinstein (AAAI’2017), for privately releasing functions.
  • 127 |
  • Bug fix in the Laplace random sampler affecting DPMechLaplace 128 |
  • 129 |
  • Unit test coverage of new functionality; general documentation improvements.
  • 130 |
131 |
132 |
133 |

134 | diffpriv 0.3.2

135 |
    136 |
  • Addition of DPMechGaussian class for the generic Gaussian mechanism to README, Vignette. Resolves #2
  • 137 |
  • Minor test additions.
  • 138 |
139 |
140 |
141 |

142 | diffpriv 0.3.1

143 |
    144 |
  • Refactoring around releaseResponse() method in DPMechNumeric. Resolves #1
  • 145 |
  • Increased test coverage.
  • 146 |
147 |
148 |
149 |

150 | diffpriv 0.3.0

151 |
    152 |
  • New DPMechGaussian class implementing the Gaussian mechanism, which achieves (epsilon,delta)-differential privacy by adding Gaussian noise to numeric responses calibrated by L2-norm sensitivity.
  • 153 |
  • Refactoring of DPMechGaussian and DPMechLaplace underneath a new VIRTUAL class DPMechNumeric which contains common methods, dims slot (formerly dim changed because dim is a special slot for S4).
  • 154 |
155 |
156 |
157 |

158 | diffpriv 0.2.0

159 |
    160 |
  • 161 | DPMechLaplace objects can now be initialized without specifying non-private target response dim. In such cases, the sensitivity sampler will perform an additional target probe to determine dim.
  • 162 |
163 |
164 |
165 |

166 | diffpriv 0.1.0.901

167 |
    168 |
  • Sensitivity sampler methods no longer require oracles that return lists. Acceptable oracles may now return lists, matrices, data frames, numeric vectors, or char vectors. As a consequence some example code in docs, README and vignette, is simplified.
  • 169 |
170 |
171 |
172 |

173 | diffpriv 0.1.0.900

174 |
    175 |
  • Initial release
  • 176 |
177 |
178 |
179 |
180 | 181 | 197 | 198 |
199 | 200 |
201 | 204 | 205 |
206 |

Site built with pkgdown.

207 |
208 | 209 |
210 |
211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticker footer */ 2 | body > .container { 3 | display: flex; 4 | padding-top: 60px; 5 | min-height: calc(100vh); 6 | flex-direction: column; 7 | } 8 | 9 | body > .container .row { 10 | flex: 1; 11 | } 12 | 13 | footer { 14 | margin-top: 45px; 15 | padding: 35px 0 36px; 16 | border-top: 1px solid #e5e5e5; 17 | color: #666; 18 | display: flex; 19 | } 20 | footer p { 21 | margin-bottom: 0; 22 | } 23 | footer div { 24 | flex: 1; 25 | } 26 | footer .pkgdown { 27 | text-align: right; 28 | } 29 | footer p { 30 | margin-bottom: 0; 31 | } 32 | 33 | img.icon { 34 | float: right; 35 | } 36 | 37 | img { 38 | max-width: 100%; 39 | } 40 | 41 | /* Section anchors ---------------------------------*/ 42 | 43 | a.anchor { 44 | margin-left: -30px; 45 | display:inline-block; 46 | width: 30px; 47 | height: 30px; 48 | visibility: hidden; 49 | 50 | background-image: url(./link.svg); 51 | background-repeat: no-repeat; 52 | background-size: 20px 20px; 53 | background-position: center center; 54 | } 55 | 56 | .hasAnchor:hover a.anchor { 57 | visibility: visible; 58 | } 59 | 60 | @media (max-width: 767px) { 61 | .hasAnchor:hover a.anchor { 62 | visibility: hidden; 63 | } 64 | } 65 | 66 | 67 | /* Fixes for fixed navbar --------------------------*/ 68 | 69 | .contents h1, .contents h2, .contents h3, .contents h4 { 70 | padding-top: 60px; 71 | margin-top: -60px; 72 | } 73 | 74 | /* Static header placement on mobile devices */ 75 | @media (max-width: 767px) { 76 | .navbar-fixed-top { 77 | position: absolute; 78 | } 79 | .navbar { 80 | padding: 0; 81 | } 82 | } 83 | 84 | 85 | /* Sidebar --------------------------*/ 86 | 87 | #sidebar { 88 | margin-top: 30px; 89 | } 90 | #sidebar h2 { 91 | font-size: 1.5em; 92 | margin-top: 1em; 93 | } 94 | 95 | #sidebar h2:first-child { 96 | margin-top: 0; 97 | } 98 | 99 | #sidebar .list-unstyled li { 100 | margin-bottom: 0.5em; 101 | } 102 | 103 | /* Reference index & topics ----------------------------------------------- */ 104 | 105 | .ref-index th {font-weight: normal;} 106 | .ref-index h2 {font-size: 20px;} 107 | 108 | .ref-index td {vertical-align: top;} 109 | .ref-index .alias {width: 40%;} 110 | .ref-index .title {width: 60%;} 111 | 112 | .ref-index .alias {width: 40%;} 113 | .ref-index .title {width: 60%;} 114 | 115 | .ref-arguments th {text-align: right; padding-right: 10px;} 116 | .ref-arguments th, .ref-arguments td {vertical-align: top;} 117 | .ref-arguments .name {width: 20%;} 118 | .ref-arguments .desc {width: 80%;} 119 | 120 | /* Nice scrolling for wide elements --------------------------------------- */ 121 | 122 | table { 123 | display: block; 124 | overflow: auto; 125 | } 126 | 127 | /* Syntax highlighting ---------------------------------------------------- */ 128 | 129 | pre { 130 | word-wrap: normal; 131 | word-break: normal; 132 | border: 1px solid #eee; 133 | } 134 | 135 | pre, code { 136 | background-color: #f8f8f8; 137 | color: #333; 138 | } 139 | 140 | pre .img { 141 | margin: 5px 0; 142 | } 143 | 144 | pre .img img { 145 | background-color: #fff; 146 | display: block; 147 | height: auto; 148 | } 149 | 150 | code a, pre a { 151 | color: #375f84; 152 | } 153 | 154 | .fl {color: #1514b5;} 155 | .fu {color: #000000;} /* function */ 156 | .ch,.st {color: #036a07;} /* string */ 157 | .kw {color: #264D66;} /* keyword */ 158 | .co {color: #888888;} /* comment */ 159 | 160 | .message { color: black; font-weight: bolder;} 161 | .error { color: orange; font-weight: bolder;} 162 | .warning { color: #6A0366; font-weight: bolder;} 163 | 164 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | $("#sidebar").stick_in_parent({offset_top: 40}); 3 | $('body').scrollspy({ 4 | target: '#sidebar', 5 | offset: 60 6 | }); 7 | 8 | var cur_path = paths(location.pathname); 9 | $("#navbar ul li a").each(function(index, value) { 10 | if (value.text == "Home") 11 | return; 12 | if (value.getAttribute("href") === "#") 13 | return; 14 | 15 | var path = paths(value.pathname); 16 | if (is_prefix(cur_path, path)) { 17 | // Add class to parent
  • , and enclosing
  • if in dropdown 18 | var menu_anchor = $(value); 19 | menu_anchor.parent().addClass("active"); 20 | menu_anchor.closest("li.dropdown").addClass("active"); 21 | } 22 | }); 23 | }); 24 | 25 | function paths(pathname) { 26 | var pieces = pathname.split("/"); 27 | pieces.shift(); // always starts with / 28 | 29 | var end = pieces[pieces.length - 1]; 30 | if (end === "index.html" || end === "") 31 | pieces.pop(); 32 | return(pieces); 33 | } 34 | 35 | function is_prefix(needle, haystack) { 36 | if (needle.length > haystack.lengh) 37 | return(false); 38 | 39 | for (var i = 0; i < haystack.length; i++) { 40 | if (needle[i] != haystack[i]) 41 | return(false); 42 | } 43 | 44 | return(true); 45 | } 46 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | urls: 2 | reference: http://brubinstein.github.io/diffpriv/reference 3 | article: http://brubinstein.github.io/diffpriv/articles 4 | articles: {} 5 | 6 | -------------------------------------------------------------------------------- /docs/reference/DPMech-class.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/DPMech-class.html -------------------------------------------------------------------------------- /docs/reference/DPMechBernstein-class.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/DPMechBernstein-class.html -------------------------------------------------------------------------------- /docs/reference/DPMechExponential-class.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/DPMechExponential-class.html -------------------------------------------------------------------------------- /docs/reference/DPMechGaussian-class.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/DPMechGaussian-class.html -------------------------------------------------------------------------------- /docs/reference/DPMechLaplace-class.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/DPMechLaplace-class.html -------------------------------------------------------------------------------- /docs/reference/DPMechNumeric-class.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/DPMechNumeric-class.html -------------------------------------------------------------------------------- /docs/reference/DPParamsDel-class.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/DPParamsDel-class.html -------------------------------------------------------------------------------- /docs/reference/DPParamsEps-class.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/DPParamsEps-class.html -------------------------------------------------------------------------------- /docs/reference/DPParamsGam-class.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/DPParamsGam-class.html -------------------------------------------------------------------------------- /docs/reference/bernstein.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/bernstein.html -------------------------------------------------------------------------------- /docs/reference/diffpriv.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/diffpriv.html -------------------------------------------------------------------------------- /docs/reference/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/figures/logo.png -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Function reference • diffpriv 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 |
    41 |
    42 | 94 | 95 | 96 |
    97 | 98 |
    99 |
    100 | 106 | 107 |
    108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 121 | 122 | 123 | 124 | 127 | 128 | 129 | 130 | 133 | 134 | 135 | 136 | 139 | 140 | 141 | 142 | 145 | 146 | 147 | 148 | 151 | 152 | 153 | 154 | 157 | 158 | 159 | 160 | 161 | 165 | 166 | 167 | 168 | 171 | 172 | 173 | 174 | 175 | 179 | 180 | 181 | 182 | 185 | 186 | 187 | 188 | 191 | 192 | 193 | 194 | 197 | 198 | 199 | 200 |
    118 |

    Mechanisms

    119 |

    Generic mechanisms for differential privacy.

    120 |
    125 |

    126 |

    An S4 class for differentially-private mechanisms.

    131 |

    show releaseResponse sensitivityNorm

    132 |

    An S4 class for the Bernstein mechanism of differential privacy.

    137 |

    show releaseResponse sensitivityNorm

    138 |

    An S4 class for the exponential mechanism of differential privacy.

    143 |

    show

    144 |

    An S4 class for the Gaussian mechanism of differential privacy.

    149 |

    show

    150 |

    An S4 class for the Laplace mechanism of differential privacy.

    155 |

    show sensitivityNorm releaseResponse

    156 |

    A virtual S4 class for differentially-private numeric mechanisms.

    162 |

    Sensitivity Sampling

    163 |

    Automatically estimating non-private target function sensitivity.

    164 |
    169 |

    sensitivitySampler

    170 |

    Sensitivity sampler for DPMech-class's.

    176 |

    Privacy Parameters

    177 |

    Encapsulating privacy budget.

    178 |
    183 |

    show getDelta setDelta<- toGamma

    184 |

    An S4 class for relaxed differential privacy parameters.

    189 |

    show getEpsilon setEpsilon<- toGamma

    190 |

    An S4 class for basic differential privacy parameters.

    195 |

    show getGamma setGamma<- toGamma

    196 |

    An S4 class for random differential privacy parameters.

    201 |
    202 |
    203 | 204 | 212 |
    213 | 214 | 224 |
    225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /docs/reference/predict.bernstein.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/predict.bernstein.html -------------------------------------------------------------------------------- /docs/reference/releaseResponse.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/releaseResponse.html -------------------------------------------------------------------------------- /docs/reference/sensitivityNorm.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/sensitivityNorm.html -------------------------------------------------------------------------------- /docs/reference/sensitivitySampler-DPMech-function-numeric-method.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/sensitivitySampler-DPMech-function-numeric-method.html -------------------------------------------------------------------------------- /docs/reference/sensitivitySampler.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/sensitivitySampler.html -------------------------------------------------------------------------------- /docs/reference/sensitivitySamplerManual-DPMech-function-numeric-numeric-numeric-method.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/sensitivitySamplerManual-DPMech-function-numeric-numeric-numeric-method.html -------------------------------------------------------------------------------- /docs/reference/sensitivitySamplerManual-DPMechNumeric-function-numeric-numeric-numeric-method.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/sensitivitySamplerManual-DPMechNumeric-function-numeric-numeric-numeric-method.html -------------------------------------------------------------------------------- /docs/reference/sensitivitySamplerManual.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/sensitivitySamplerManual.html -------------------------------------------------------------------------------- /docs/reference/setDelta-set.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/setDelta-set.html -------------------------------------------------------------------------------- /docs/reference/setEpsilon-set.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/setEpsilon-set.html -------------------------------------------------------------------------------- /docs/reference/setGamma-set.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/docs/reference/setGamma-set.html -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite diffpriv in publications use:") 2 | 3 | citEntry(entry = "inproceedings", 4 | title = "Pain-Free Random Differential Privacy with Sensitivity Sampling", 5 | author = personList(person(c("Benjamin", "I.", "P."), "Rubinstein"), 6 | person("Francesco", "Alda")), 7 | year = "2017", 8 | booktitle = "34th International Conference on Machine Learning (ICML'2017)", 9 | 10 | textVersion = 11 | paste("Benjamin I. P. Rubinstein and Francesco Alda (2017).", 12 | "'Pain-Free Random Differential Privacy with Sensitivity Sampling'", 13 | "in the 34th International Conference on Machine Learning (ICML'2017).") 14 | ) 15 | 16 | -------------------------------------------------------------------------------- /inst/doc/bernstein.R: -------------------------------------------------------------------------------- 1 | ## ----knitr_options, include=FALSE------------------------- 2 | library(knitr) 3 | opts_chunk$set(fig.width=12, fig.height=4, fig.path='', comment="#>", 4 | warning=FALSE, message=FALSE, tidy=FALSE, size="small") 5 | options(width=60) 6 | set.seed(3033362) # for reproducibility 7 | # install package if necessary: 8 | #if(!require("qtl")) install.packages("qtl", repos="http://cran.us.r-project.org") 9 | 10 | ## ----example1-1, include=TRUE, echo=TRUE, results='markup'---- 11 | library(diffpriv) 12 | targetF <- function(x) x * sin(10 * x) 13 | bernsteinF <- bernstein(targetF, dims = 1, k = 25) 14 | 15 | ## ----example1-2, include=TRUE, echo=TRUE, results='markup'---- 16 | bernsteinF$coeffs 17 | 18 | ## ----example1-3, include=TRUE, echo=TRUE, results='markup'---- 19 | predict(bernsteinF, D = 0.2) # approximate f(0.5) 20 | targetF(0.2) # actual f(0.5) 21 | 22 | ## ----example1-4, include=TRUE, echo=TRUE, results='markup', fig.show='hold', fig.width=7, fig.height=3.5, fig.cap = "Bernstein polynomial approximation (blue) vs target (red)."---- 23 | xs <- seq(from = 0, to = 1, length = 50) 24 | plot(xs, targetF(xs), xlim = c(0,1), ylim = c(-1,1), lty = "dashed", lwd = 2, 25 | col = "red", type="l", xlab="x", ylab="y", 26 | main="Bernstein polynomial approximation") 27 | lines(xs, predict(bernsteinF, xs), col = "blue", lwd = 2) 28 | 29 | ## ----example2-1, include=TRUE, echo=TRUE, results='markup'---- 30 | pck_regression <- function(D, bandwidth = 0.1) { 31 | K <- function(x) exp(-x^2/2) 32 | ids <- sort(D[,1], decreasing = FALSE, index.return = TRUE)$ix 33 | D <- D[ids, ] 34 | n <- nrow(D) 35 | ws <- (D[2:n,1] - D[1:(n-1),1]) * D[2:n,2] 36 | predictor <- function(x) { 37 | sum(ws * sapply((x - D[2:n,1]) / bandwidth, K)) / bandwidth 38 | } 39 | return(predictor) 40 | } 41 | 42 | ## ----example2-2, include=TRUE, echo=TRUE, results='markup'---- 43 | N <- 250 44 | D <- runif(N) 45 | D <- cbind(D, sin(D*10)*D + rnorm(N, mean=0, sd=0.2)) 46 | 47 | ## ----example2-3, include=TRUE, echo=TRUE, results='markup'---- 48 | ## Non private fitting 49 | model <- pck_regression(D) 50 | 51 | ## Bernstein non private fitting 52 | K <- 25 53 | bmodel <- bernstein(model, dims=1, k=K) 54 | 55 | ## Private Bernstein fitting 56 | m <- DPMechBernstein(target=pck_regression, latticeK=K, dims=1) 57 | P <- function(n) { # a sampler of random, "plausible", datasets 58 | Dx <- runif(n) 59 | Dy <- rep(0, n) 60 | if (runif(1) < 0.95) Dy <- Dy + Dx 61 | if (runif(1) < 0.5) Dy <- Dy * sin(Dx) 62 | if (runif(1) < 0.5) Dy <- Dy * cos(Dx) 63 | cbind(Dx, Dy + rnorm(n, mean=0, sd=0.2)) 64 | } 65 | m <- sensitivitySampler(m, oracle=P, n=N, gamma=0.20, m=500) 66 | R <- releaseResponse(m, privacyParams=DPParamsEps(epsilon=5), X=D) 67 | pmodel <- R$response 68 | 69 | ## ----example2-4, include=TRUE, echo=TRUE, results='markup'---- 70 | xs <- seq(from=0, to=1, length=50) 71 | yhats <- sapply(xs, model) 72 | yhats.b <- predict(bmodel, xs) 73 | yhats.p <- R$response(xs) 74 | 75 | ## ----example2-5, include=TRUE, echo=TRUE, results='markup', fig.show='hold', fig.width=7, fig.height=3.5, fig.cap = "Kernel regression on 1D training data (gray points): non-private model (red dashed); non-private Bernstein polynomial approximation (black dotted); private Bernstein mechanism (blue solid)."---- 76 | xlim <- c(0, 1) 77 | ylim <- range(c(yhats.b, yhats.p, yhats, D[,2])) 78 | plot(D, pch=20, cex=0.6, xlim=c(0,1), ylim=ylim, xlab="X", ylab="Y", 79 | main="Priestly-Chao Kernel Regression", col="lightgrey") 80 | lines(xs, yhats.p, col="blue", type="l", lty="solid", lwd = 2) 81 | lines(xs, yhats.b, col="black", type="l", lty="dotted", lwd = 3) 82 | lines(xs, yhats, col="red", type="l", lty="dashed", lwd =2) 83 | 84 | -------------------------------------------------------------------------------- /inst/doc/bernstein.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/inst/doc/bernstein.pdf -------------------------------------------------------------------------------- /inst/doc/diffpriv.R: -------------------------------------------------------------------------------- 1 | ## ----knitr_options, include=FALSE------------------------- 2 | library(knitr) 3 | opts_chunk$set(fig.width=12, fig.height=4, fig.path='', comment="#>", 4 | warning=FALSE, message=FALSE, tidy=FALSE, size="small") 5 | options(width=60) 6 | set.seed(53079239) 7 | # install package if necessary: 8 | #if(!require("qtl")) install.packages("qtl", repos="http://cran.us.r-project.org") 9 | 10 | ## ----genericLaplace, include=TRUE, echo=TRUE, results='markup'---- 11 | library(diffpriv) 12 | f <- function(X) mean(X) ## target function 13 | n <- 100 ## dataset size 14 | mechanism <- DPMechLaplace(target = f, sensitivity = 1/n, dims = 1) 15 | D <- runif(n, min = 0, max = 1) ## the sensitive database in [0,1]^n 16 | pparams <- DPParamsEps(epsilon = 1) ## desired privacy budget 17 | r <- releaseResponse(mechanism, privacyParams = pparams, X = D) 18 | cat("Private response r$response:", r$response, 19 | "\nNon-private response f(D): ", f(D)) 20 | 21 | ## ----samplerExponential, include=TRUE, echo=TRUE, results='markup'---- 22 | library(randomNames) ## a package that generates representative random names 23 | oracle <- function(n) randomNames(n) 24 | D <- c("Michael Jordan", "Andrew Ng", "Andrew Zisserman","Christopher Manning", 25 | "Jitendra Malik", "Geoffrey Hinton", "Scott Shenker", 26 | "Bernhard Scholkopf", "Jon Kleinberg", "Judea Pearl") 27 | n <- length(D) 28 | f <- function(X) { function(r) sum(r == unlist(base::strsplit(X, ""))) } 29 | rSet <- as.list(letters) ## the response set, letters a--z, must be a list 30 | mechanism <- DPMechExponential(target = f, responseSet = rSet) 31 | mechanism <- sensitivitySampler(mechanism, oracle = oracle, n = n, gamma = 0.1) 32 | pparams <- DPParamsEps(epsilon = 1) 33 | r <- releaseResponse(mechanism, privacyParams = pparams, X = D) 34 | cat("Private response r$response: ", r$response, 35 | "\nNon-private f(D) maximizer: ", letters[which.max(sapply(rSet, f(D)))]) 36 | 37 | -------------------------------------------------------------------------------- /inst/doc/diffpriv.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/inst/doc/diffpriv.pdf -------------------------------------------------------------------------------- /man/DPMech-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mechanisms.R 3 | \docType{class} 4 | \name{DPMech-class} 5 | \alias{DPMech-class} 6 | \title{An S4 class for differentially-private mechanisms.} 7 | \description{ 8 | A base class for representing output-perturbing mechanisms in differential 9 | privacy. As this class is \code{VIRTUAL} it cannot be instantiated, but it can 10 | be subclassed. 11 | } 12 | \section{Slots}{ 13 | 14 | \describe{ 15 | \item{\code{sensitivity}}{non-negative scalar numeric target sensitivity. Defaults 16 | to \code{Inf} for use with \code{sensitivitySampler()}.} 17 | 18 | \item{\code{target}}{the target non-private function to be privatized, takes lists. 19 | Defaults to a constant function.} 20 | 21 | \item{\code{gammaSensitivity}}{\code{NA_real_} if inactive, or scalar in [0,1) 22 | indicating that responses must be RDP with specific confidence.} 23 | }} 24 | 25 | \references{ 26 | Cynthia Dwork, Frank McSherry, Kobbi Nissim, and Adam Smith. 27 | "Calibrating noise to sensitivity in private data analysis." In Theory of 28 | Cryptography Conference, pp. 265-284. Springer Berlin Heidelberg, 2006. 29 | } 30 | \seealso{ 31 | \code{\link{DPMechLaplace}} subclass for the Laplace mechanism. 32 | } 33 | -------------------------------------------------------------------------------- /man/DPMechBernstein-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bernstein_mechanism.R 3 | \docType{class} 4 | \name{DPMechBernstein-class} 5 | \alias{DPMechBernstein-class} 6 | \alias{DPMechBernstein} 7 | \alias{show,DPMechBernstein-method} 8 | \alias{releaseResponse,DPMechBernstein,DPParamsEps-method} 9 | \alias{sensitivityNorm,DPMechBernstein-method} 10 | \title{An S4 class for the Bernstein mechanism of differential privacy.} 11 | \usage{ 12 | \S4method{show}{DPMechBernstein}(object) 13 | 14 | \S4method{releaseResponse}{DPMechBernstein,DPParamsEps}(mechanism, 15 | privacyParams, X) 16 | 17 | \S4method{sensitivityNorm}{DPMechBernstein}(mechanism, X1, X2) 18 | } 19 | \arguments{ 20 | \item{object}{an instance of class \code{DPMech}.} 21 | 22 | \item{mechanism}{an object of class \code{\link{DPMechBernstein}}.} 23 | 24 | \item{privacyParams}{an object of class \code{\link{DPParamsEps}}.} 25 | 26 | \item{X}{a privacy-sensitive dataset, if using sensitivity sampler a: list, 27 | matrix, data frame, numeric/character vector.} 28 | 29 | \item{X1}{a privacy-sensitive dataset.} 30 | 31 | \item{X2}{a privacy-sensitive dataset.} 32 | } 33 | \value{ 34 | list with slots per argument, actual privacy parameter and response: 35 | mechanism response with length of target release: 36 | \code{privacyParams, sensitivity, latticeK, dims, target, response}. 37 | 38 | scalar numeric norm of non-private \code{target} on datasets. 39 | The \eqn{L_\infty} of the functions on a lattice. 40 | } 41 | \description{ 42 | A class that implements the Bernstein mechanism (not iterated version) of 43 | differential privacy, for privatizing release of real-valued functions on 44 | \eqn{[0,1]^l} based on arbitrary datasets. Approximates the \code{target} 45 | on a lattice. 46 | } 47 | \section{Methods (by generic)}{ 48 | \itemize{ 49 | \item \code{show}: automatically prints the object. 50 | 51 | \item \code{releaseResponse}: releases Bernstein mechanism responses. 52 | 53 | \item \code{sensitivityNorm}: measures \code{target} sensitivity. 54 | }} 55 | 56 | \section{Slots}{ 57 | 58 | \describe{ 59 | \item{\code{sensitivity}}{non-negative scalar numeric maximum absolute \code{target} 60 | sensitivity maximized over the lattice. Defaults to \code{Inf} for use 61 | with \code{sensitivitySampler()}.} 62 | 63 | \item{\code{target}}{might be a closure that takes arbitrary dataset and returns a 64 | real-valued function on \eqn{[0,1]^l}.} 65 | 66 | \item{\code{gammaSensitivity}}{\code{NA_real_} if inactive, or scalar in [0,1) 67 | indicating that responses must be RDP with specific confidence.} 68 | 69 | \item{\code{latticeK}}{positive scalar integer-valued numeric specifying the lattice 70 | resolution. Defaults to (invalid) \code{NA_integer_}.} 71 | 72 | \item{\code{dims}}{positive scalar integer-valued numeric specifying the dimension 73 | of released function domain. Defaults to (invalid) \code{NA_integer_}.} 74 | }} 75 | 76 | \examples{ 77 | ## See the bernstein vignette 78 | 79 | } 80 | \references{ 81 | Francesco Aldà and Benjamin I. P. Rubinstein. "The Bernstein Mechanism: 82 | Function Release under Differential Privacy", in Proceedings of the 31st 83 | AAAI Conference on Artificial Intelligence (AAAI'2017), pp. 1705-1711, 84 | Feb 2017. 85 | } 86 | -------------------------------------------------------------------------------- /man/DPMechExponential-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/exponential_mechanism.R 3 | \docType{class} 4 | \name{DPMechExponential-class} 5 | \alias{DPMechExponential-class} 6 | \alias{DPMechExponential} 7 | \alias{show,DPMechExponential-method} 8 | \alias{releaseResponse,DPMechExponential,DPParamsEps-method} 9 | \alias{sensitivityNorm,DPMechExponential-method} 10 | \title{An S4 class for the exponential mechanism of differential privacy.} 11 | \usage{ 12 | \S4method{show}{DPMechExponential}(object) 13 | 14 | \S4method{releaseResponse}{DPMechExponential,DPParamsEps}(mechanism, 15 | privacyParams, X) 16 | 17 | \S4method{sensitivityNorm}{DPMechExponential}(mechanism, X1, X2) 18 | } 19 | \arguments{ 20 | \item{object}{an instance of class \code{DPMech}.} 21 | 22 | \item{mechanism}{an object of class \code{\link{DPMechExponential}}.} 23 | 24 | \item{privacyParams}{an object of class \code{\link{DPParamsEps}}.} 25 | 26 | \item{X}{a privacy-sensitive dataset, if using sensitivity sampler a: list, 27 | matrix, data frame, numeric/character vector.} 28 | 29 | \item{X1}{a privacy-sensitive dataset.} 30 | 31 | \item{X2}{a privacy-sensitive dataset.} 32 | } 33 | \value{ 34 | list with slots per argument, actual privacy parameter and response: 35 | mechanism response with length of target release: 36 | \code{privacyParams, sensitivity, responseSet, target, response}. 37 | 38 | scalar numeric norm of non-private \code{target} on datasets. 39 | } 40 | \description{ 41 | A class that implements the exponential mechanism of differential privacy, 42 | for privatizing releases from sets (not necessarily numeric as 43 | required by \code{\link{DPMechLaplace}}). Currently limited to responses 44 | from a finite sets - the most widely used case - as these induce easily 45 | computed sampling distributions from a uniform base measure. 46 | } 47 | \section{Methods (by generic)}{ 48 | \itemize{ 49 | \item \code{show}: automatically prints the object. 50 | 51 | \item \code{releaseResponse}: releases exponential mechanism responses. 52 | 53 | \item \code{sensitivityNorm}: measures \code{target} quality score sensitivity. 54 | }} 55 | 56 | \section{Slots}{ 57 | 58 | \describe{ 59 | \item{\code{sensitivity}}{non-negative scalar numeric quality function sensitivity. 60 | Defaults to \code{Inf} for use with \code{sensitivitySampler()}.} 61 | 62 | \item{\code{target}}{the quality score function mapping dataset to a function on 63 | responses (elements of \code{responseSet}).} 64 | 65 | \item{\code{gammaSensitivity}}{\code{NA_real_} if inactive, or scalar in [0,1) 66 | indicating that responses must be RDP with specific confidence.} 67 | 68 | \item{\code{responseSet}}{a list of possible responses of the mechanism.} 69 | }} 70 | 71 | \examples{ 72 | ## Sensitive data are strings of length at most 5. 73 | ## Task is to release most frequent character present, hence quality function 74 | ## is a closure that counts character frequencies for given candidate char. 75 | ## Global sensitivity is max string length. 76 | qualF <- function(X) { function(r) sum(r == unlist(strsplit(X, ""))) } 77 | rs <- as.list(letters) 78 | m <- DPMechExponential(sensitivity = 5, target = qualF, responseSet = rs) 79 | X <- strsplit("the quick brown fox jumps over the lazy dog"," ")[[1]] 80 | p <- DPParamsEps(epsilon = 1) 81 | releaseResponse(m, p, X) 82 | } 83 | \references{ 84 | Frank McSherry and Kunal Talwar. "Mechanism design via differential privacy." 85 | In the 48th Annual IEEE Symposium on Foundations of Computer Science 86 | (FOCS'07), pp. 94-103. IEEE, 2007. 87 | } 88 | -------------------------------------------------------------------------------- /man/DPMechGaussian-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/gaussian_mechanism.R 3 | \docType{class} 4 | \name{DPMechGaussian-class} 5 | \alias{DPMechGaussian-class} 6 | \alias{DPMechGaussian} 7 | \alias{show,DPMechGaussian-method} 8 | \title{An S4 class for the Gaussian mechanism of differential privacy.} 9 | \usage{ 10 | \S4method{show}{DPMechGaussian}(object) 11 | } 12 | \arguments{ 13 | \item{object}{an instance of class \code{DPMech}.} 14 | } 15 | \description{ 16 | A class that implements the Gaussian mechanism of differential privacy, 17 | for privatizing numeric vector releases. 18 | } 19 | \section{Methods (by generic)}{ 20 | \itemize{ 21 | \item \code{show}: automatically prints the object. 22 | }} 23 | 24 | \section{Slots}{ 25 | 26 | \describe{ 27 | \item{\code{sensitivity}}{non-negative scalar numeric L2 target sensitivity. 28 | Defaults to \code{Inf} for use with \code{sensitivitySampler()}.} 29 | 30 | \item{\code{target}}{the target non-private function to be privatized, takes lists. 31 | Defaults to a constant function. Gaussian mechanism assumes functions that 32 | release numeric vectors of fixed dimension \code{dims}.} 33 | 34 | \item{\code{gammaSensitivity}}{\code{NA_real_} if inactive, or scalar in [0,1) 35 | indicating that responses must be RDP with specific confidence.} 36 | 37 | \item{\code{dims}}{positive scalar numeric dimension of responses. Defaults to 38 | \code{NA_integer_} for use with \code{sensitivitySampler()} which can 39 | probe \code{target} to determine dimension.} 40 | }} 41 | 42 | \references{ 43 | Cynthia Dwork and Aaron Roth. "Algorithmic Foundations of 44 | Differential Privacy" Foundations and Trends in Theoretical Computer 45 | Science. Now Publishers, 2014. 46 | } 47 | -------------------------------------------------------------------------------- /man/DPMechLaplace-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/laplace_mechanism.R 3 | \docType{class} 4 | \name{DPMechLaplace-class} 5 | \alias{DPMechLaplace-class} 6 | \alias{DPMechLaplace} 7 | \alias{show,DPMechLaplace-method} 8 | \title{An S4 class for the Laplace mechanism of differential privacy.} 9 | \usage{ 10 | \S4method{show}{DPMechLaplace}(object) 11 | } 12 | \arguments{ 13 | \item{object}{an instance of class \code{DPMech}.} 14 | } 15 | \description{ 16 | A class that implements the basic Laplace mechanism of differential privacy, 17 | for privatizing numeric vector releases. 18 | } 19 | \section{Methods (by generic)}{ 20 | \itemize{ 21 | \item \code{show}: automatically prints the object. 22 | }} 23 | 24 | \section{Slots}{ 25 | 26 | \describe{ 27 | \item{\code{sensitivity}}{non-negative scalar numeric L1 target sensitivity. 28 | Defaults to \code{Inf} for use with \code{sensitivitySampler()}.} 29 | 30 | \item{\code{target}}{the target non-private function to be privatized, takes lists. 31 | Defaults to a constant function. Laplace mechanism assumes functions that 32 | release numeric vectors of fixed dimension \code{dims}.} 33 | 34 | \item{\code{gammaSensitivity}}{\code{NA_real_} if inactive, or scalar in [0,1) 35 | indicating that responses must be RDP with specific confidence.} 36 | 37 | \item{\code{dims}}{positive scalar numeric dimension of responses. Defaults to 38 | \code{NA_integer_} for use with \code{sensitivitySampler()} which can 39 | probe \code{target} to determine dimension.} 40 | }} 41 | 42 | \references{ 43 | Cynthia Dwork, Frank McSherry, Kobbi Nissim, and Adam Smith. 44 | "Calibrating noise to sensitivity in private data analysis." In Theory of 45 | Cryptography Conference, pp. 265-284. Springer Berlin Heidelberg, 2006. 46 | } 47 | -------------------------------------------------------------------------------- /man/DPMechNumeric-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/numeric_mechanism.R 3 | \docType{class} 4 | \name{DPMechNumeric-class} 5 | \alias{DPMechNumeric-class} 6 | \alias{DPMechNumeric} 7 | \alias{show,DPMechNumeric-method} 8 | \alias{sensitivityNorm,DPMechNumeric-method} 9 | \alias{releaseResponse,DPMechNumeric,DPParamsEps-method} 10 | \title{A virtual S4 class for differentially-private numeric mechanisms.} 11 | \usage{ 12 | \S4method{show}{DPMechNumeric}(object) 13 | 14 | \S4method{sensitivityNorm}{DPMechNumeric}(mechanism, X1, X2) 15 | 16 | \S4method{releaseResponse}{DPMechNumeric,DPParamsEps}(mechanism, privacyParams, 17 | X) 18 | } 19 | \arguments{ 20 | \item{object}{an instance of class \code{DPMech}.} 21 | 22 | \item{mechanism}{an object of class \code{DPMechNumeric-class}.} 23 | 24 | \item{X1}{a privacy-sensitive dataset.} 25 | 26 | \item{X2}{a privacy-sensitive dataset.} 27 | 28 | \item{privacyParams}{an object of class \code{\link{DPParamsEps}}.} 29 | 30 | \item{X}{a privacy-sensitive dataset, if using sensitivity sampler a: list, 31 | matrix, data frame, numeric/character vector.} 32 | } 33 | \value{ 34 | scalar numeric norm of non-private \code{target} on datasets. 35 | 36 | list with slots per argument, actual privacy parameter; 37 | mechanism response with length of target release: 38 | \code{privacyParams, sensitivity, dims, target, response}. 39 | } 40 | \description{ 41 | A virtual class that implements common features of Laplace, Gaussian 42 | mechanisms from differential privacy, for privatizing numeric vector 43 | releases. 44 | } 45 | \section{Methods (by generic)}{ 46 | \itemize{ 47 | \item \code{show}: automatically prints the object. 48 | 49 | \item \code{sensitivityNorm}: measures sensitivity of non-private \code{target}. 50 | 51 | \item \code{releaseResponse}: releases mechanism responses. 52 | }} 53 | 54 | \section{Slots}{ 55 | 56 | \describe{ 57 | \item{\code{sensitivity}}{non-negative scalar numeric target sensitivity. 58 | Defaults to \code{Inf} for use with \code{sensitivitySampler()}.} 59 | 60 | \item{\code{target}}{the target non-private function to be privatized, takes lists. 61 | Defaults to a constant function. Laplace mechanism assumes functions that 62 | release numeric vectors of fixed dimension \code{dims}.} 63 | 64 | \item{\code{gammaSensitivity}}{\code{NA_real_} if deactive, or scalar in [0,1) 65 | indicating that responses must be RDP with specific confidence.} 66 | 67 | \item{\code{dims}}{positive scalar numeric dimension of responses. Defaults to 68 | \code{NA_integer_} for use with \code{sensitivitySampler()} which can 69 | probe \code{target} to determine dimension.} 70 | }} 71 | 72 | \examples{ 73 | f <- function(xs) mean(xs) 74 | n <- 100 75 | m <- DPMechLaplace(sensitivity = 1/n, target = f, dims = 1) 76 | X1 <- runif(n) 77 | X2 <- runif(n) 78 | sensitivityNorm(m, X1, X2) 79 | f <- function(xs) mean(xs) 80 | n <- 100 81 | m <- DPMechLaplace(sensitivity = 1/n, target = f, dims = 1) 82 | X <- runif(n) 83 | p <- DPParamsEps(epsilon = 1) 84 | releaseResponse(m, p, X) 85 | } 86 | -------------------------------------------------------------------------------- /man/DPParamsDel-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/privacy_params.R 3 | \docType{class} 4 | \name{DPParamsDel-class} 5 | \alias{DPParamsDel-class} 6 | \alias{DPParamsDel} 7 | \alias{show,DPParamsDel-method} 8 | \alias{getDelta,DPParamsDel-method} 9 | \alias{setDelta<-,DPParamsDel-method} 10 | \alias{toGamma,DPParamsDel,numeric-method} 11 | \title{An S4 class for relaxed differential privacy parameters.} 12 | \usage{ 13 | \S4method{show}{DPParamsDel}(object) 14 | 15 | \S4method{getDelta}{DPParamsDel}(object) 16 | 17 | \S4method{setDelta}{DPParamsDel}(object) <- value 18 | 19 | \S4method{toGamma}{DPParamsDel,numeric}(object, gamma) 20 | } 21 | \arguments{ 22 | \item{object}{an object of class \code{\link{DPParamsDel}}.} 23 | 24 | \item{value}{a scalar numeric \eqn{\delta}.} 25 | 26 | \item{gamma}{a scalar numeric \eqn{\gamma}.} 27 | } 28 | \description{ 29 | An S4 base class representing the privacy parameters in 30 | \eqn{(\epsilon,\delta)}-differential privacy. 31 | } 32 | \section{Methods (by generic)}{ 33 | \itemize{ 34 | \item \code{show}: automatically prints the object. 35 | 36 | \item \code{getDelta}: getter for slot \code{delta}. 37 | 38 | \item \code{setDelta<-}: setter for slot \code{delta}. 39 | 40 | \item \code{toGamma}: returns object to corresponding instance of subclass 41 | \code{\link{DPParamsGam}}. 42 | }} 43 | 44 | \section{Slots}{ 45 | 46 | \describe{ 47 | \item{\code{epsilon}}{positive scalar numeric privacy level.} 48 | 49 | \item{\code{delta}}{a scalar numeric privacy level in interval [0,1).} 50 | }} 51 | 52 | \seealso{ 53 | \code{\link{DPParamsEps}} superclass, 54 | \code{\link{DPParamsGam}} subclass for random relaxation. 55 | } 56 | -------------------------------------------------------------------------------- /man/DPParamsEps-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/privacy_params.R 3 | \docType{class} 4 | \name{DPParamsEps-class} 5 | \alias{DPParamsEps-class} 6 | \alias{DPParamsEps} 7 | \alias{show,DPParamsEps-method} 8 | \alias{getEpsilon,DPParamsEps-method} 9 | \alias{setEpsilon<-,DPParamsEps-method} 10 | \alias{toGamma,DPParamsEps,numeric-method} 11 | \title{An S4 class for basic differential privacy parameters.} 12 | \usage{ 13 | \S4method{show}{DPParamsEps}(object) 14 | 15 | \S4method{getEpsilon}{DPParamsEps}(object) 16 | 17 | \S4method{setEpsilon}{DPParamsEps}(object) <- value 18 | 19 | \S4method{toGamma}{DPParamsEps,numeric}(object, gamma) 20 | } 21 | \arguments{ 22 | \item{object}{an object of class \code{\link{DPParamsEps}}.} 23 | 24 | \item{value}{a scalar numeric \eqn{\epsilon}.} 25 | 26 | \item{gamma}{a scalar numeric \eqn{\gamma}.} 27 | } 28 | \description{ 29 | An S4 base class representing the basic privacy parameter \eqn{\epsilon} in 30 | differential privacy. 31 | } 32 | \section{Methods (by generic)}{ 33 | \itemize{ 34 | \item \code{show}: automatically prints the object. 35 | 36 | \item \code{getEpsilon}: getter for slot \code{epsilon}. 37 | 38 | \item \code{setEpsilon<-}: setter for slot \code{epsilon}. 39 | 40 | \item \code{toGamma}: returns object to corresponding instance of subclass 41 | \code{\link{DPParamsGam}}. 42 | }} 43 | 44 | \section{Slots}{ 45 | 46 | \describe{ 47 | \item{\code{epsilon}}{positive scalar numeric privacy level.} 48 | }} 49 | 50 | \seealso{ 51 | \code{\link{DPParamsDel}} subclass for \eqn{(\epsilon,\delta)} 52 | relaxation, \code{\link{DPParamsGam}} subclass for random relaxation. 53 | } 54 | -------------------------------------------------------------------------------- /man/DPParamsGam-class.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/privacy_params.R 3 | \docType{class} 4 | \name{DPParamsGam-class} 5 | \alias{DPParamsGam-class} 6 | \alias{DPParamsGam} 7 | \alias{show,DPParamsGam-method} 8 | \alias{getGamma,DPParamsGam-method} 9 | \alias{setGamma<-,DPParamsGam-method} 10 | \alias{toGamma,DPParamsGam,numeric-method} 11 | \title{An S4 class for random differential privacy parameters.} 12 | \usage{ 13 | \S4method{show}{DPParamsGam}(object) 14 | 15 | \S4method{getGamma}{DPParamsGam}(object) 16 | 17 | \S4method{setGamma}{DPParamsGam}(object) <- value 18 | 19 | \S4method{toGamma}{DPParamsGam,numeric}(object, gamma) 20 | } 21 | \arguments{ 22 | \item{object}{an object of class \code{\link{DPParamsGam}}.} 23 | 24 | \item{value}{a scalar numeric \eqn{\gamma}.} 25 | 26 | \item{gamma}{scalar numeric \eqn{\gamma}.} 27 | } 28 | \description{ 29 | An S4 base class representing the privacy parameters in 30 | \eqn{(\epsilon,\delta,\gamma)}-random differential privacy. 31 | } 32 | \section{Methods (by generic)}{ 33 | \itemize{ 34 | \item \code{show}: automatically prints the object. 35 | 36 | \item \code{getGamma}: getter for slot \code{gamma}. 37 | 38 | \item \code{setGamma<-}: setter for slot \code{gamma}. 39 | 40 | \item \code{toGamma}: returns object with set gamma; generic for use with 41 | superclasses \code{\link{DPParamsEps}} and \code{\link{DPParamsDel}}. 42 | }} 43 | 44 | \section{Slots}{ 45 | 46 | \describe{ 47 | \item{\code{epsilon}}{positive scalar numeric privacy level.} 48 | 49 | \item{\code{delta}}{a scalar numeric privacy level in interval [0,1).} 50 | 51 | \item{\code{gamma}}{a scalar numeric privacy level in [0, 1).} 52 | }} 53 | 54 | \seealso{ 55 | \code{\link{DPParamsEps}}, \code{\link{DPParamsDel}} superclasses. 56 | } 57 | -------------------------------------------------------------------------------- /man/bernstein.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bernstein_polynomials.R 3 | \name{bernstein} 4 | \alias{bernstein} 5 | \title{Fit a Bernstein polynomial approximation.} 6 | \usage{ 7 | bernstein(f, dims, k = 10) 8 | } 9 | \arguments{ 10 | \item{f}{a function to be approximated.} 11 | 12 | \item{dims}{the function \code{f}'s domain dimension.} 13 | 14 | \item{k}{the lattice resolution of approximation.} 15 | } 16 | \value{ 17 | an S3 object of class \code{bernstein}. 18 | } 19 | \description{ 20 | Fits the basis of Bernstein polynomial functions to given real-valued 21 | function \code{f} of \eqn{[0,1]^d} where \eqn{d=}\code{dims}, against 22 | a regular lattice of \eqn{k+1} points in each dimension for given 23 | \code{k}. Note the approximation is not the iterated variant. 24 | } 25 | \examples{ 26 | f <- function(x) x * sin(x*10) 27 | b <- bernstein(f, dims = 1) 28 | xs <- seq(from=0, to=1, length=50) 29 | mean((f(xs) - predict(b,xs))^2) 30 | 31 | } 32 | \references{ 33 | Francesco Aldà and Benjamin I. P. Rubinstein. "The Bernstein Mechanism: 34 | Function Release under Differential Privacy", in Proceedings of the 31st 35 | AAAI Conference on Artificial Intelligence (AAAI'2017), pp. 1705-1711, 36 | Feb 2017. 37 | } 38 | \seealso{ 39 | \code{\link{predict.bernstein}} for subsequent evaluation. 40 | } 41 | -------------------------------------------------------------------------------- /man/diffpriv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diffpriv.R 3 | \docType{package} 4 | \name{diffpriv} 5 | \alias{diffpriv} 6 | \alias{diffpriv-package} 7 | \title{\code{diffpriv}: practical differential privacy in R.} 8 | \description{ 9 | The \code{diffpriv} package is a collection of generic tools for privacy-aware 10 | data science, under the formal framework of differential privacy. A 11 | differentially-private mechanism can release responses to untrusted third 12 | parties, models fit on privacy-sensitive data. Due to the formal worst-case 13 | nature of the framework, however, mechanism development typically requires 14 | theoretical analysis. \code{diffpriv} offers a turn-key approach to 15 | differential privacy. 16 | } 17 | \section{General-purpose mechanisms}{ 18 | 19 | 20 | Differential privacy's popularity is owed in part to a number of generic 21 | mechanisms for privatizing non-private target functions. Virtual S4 22 | class \code{\link{DPMech-class}} captures common features of these mechanisms and 23 | is superclass to: 24 | 25 | \itemize{ 26 | \item \code{\link{DPMechLaplace}}: the Laplace mechanism of Dwork et al. 27 | (2006) for releasing numeric vectors; 28 | \item \code{\link{DPMechExponential}}: the exponential mechanism of McSherry 29 | and Talwar (2007) for releasing solutions to optimizations, over numeric or 30 | non-numeric sets; and 31 | \item More mechanisms coming soon. Users can also develop new mechanisms by 32 | subclassing \code{\link{DPMech-class}}. 33 | } 34 | 35 | \code{\link{DPMech-class}}-derived objects are initialized with a problem-specific 36 | non-private \code{target} function. Subsequently, the 37 | \code{\link{releaseResponse}} method can privatize responses of \code{target} 38 | on input datasets. The level of corresponding privatization depends on given 39 | privacy parameters \code{\link{DPParamsEps}} or derived parameters object. 40 | } 41 | 42 | \section{Privatize anything with sensitivity measurement}{ 43 | 44 | 45 | \code{diffpriv} mechanisms have in common a reliance on the 'sensitivity' of 46 | \code{target} function to small changes to input datasets. This sensitivity 47 | must be provably bounded for an application's \code{target} in order for 48 | differential privacy to be proved, and is used to calibrate privacy-preserving 49 | randomization. Unfortunately bounding sensitivity is often prohibitively 50 | complex, for example if \code{target} is an arbitrary computer program. All 51 | \code{\link{DPMech-class}} mechanisms offer a \code{\link{sensitivitySampler}} 52 | method due to Rubinstein and Aldà (2017) that repeatedly probes \code{target} 53 | to estimate sensitivity automatically. Mechanisms with estimated sensitivities 54 | achieve a slightly weaker form of random differential privacy due to 55 | Hall et al. (2013), but without any theoretical analysis necessary. 56 | } 57 | 58 | \examples{ 59 | \dontrun{ 60 | ## for full examples see the diffpriv vignette 61 | vignette("diffpriv") 62 | } 63 | 64 | } 65 | \references{ 66 | Benjamin I. P. Rubinstein and Francesco Aldà. "Pain-Free Random Differential 67 | Privacy with Sensitivity Sampling", accepted into the 34th International 68 | Conference on Machine Learning (ICML'2017), May 2017. 69 | 70 | Cynthia Dwork, Frank McSherry, Kobbi Nissim, and Adam Smith. 71 | "Calibrating noise to sensitivity in private data analysis." In Theory of 72 | Cryptography Conference, pp. 265-284. Springer Berlin Heidelberg, 2006. 73 | 74 | Frank McSherry and Kunal Talwar. "Mechanism design via differential privacy." 75 | In the 48th Annual IEEE Symposium on Foundations of Computer Science 76 | (FOCS'07), pp. 94-103. IEEE, 2007. 77 | 78 | Rob Hall, Alessandro Rinaldo, and Larry Wasserman. "Random Differential 79 | Privacy." Journal of Privacy and Confidentiality, 4(2), pp. 43-59, 2012. 80 | } 81 | -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/man/figures/logo.png -------------------------------------------------------------------------------- /man/predict.bernstein.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bernstein_polynomials.R 3 | \name{predict.bernstein} 4 | \alias{predict.bernstein} 5 | \title{Evaluate Bernstein approximations on data.} 6 | \usage{ 7 | \method{predict}{bernstein}(object, D, ...) 8 | } 9 | \arguments{ 10 | \item{object}{an S3 object of type \code{bernstein}.} 11 | 12 | \item{D}{either a numeric vector or matrix, all values in \code{[0,1]}. 13 | If numeric then length should be \code{object$dims} unless the latter is 14 | 1 in which case the length can be arbitrary. If a matrix then the number 15 | of columns should match \code{object$dims}.} 16 | 17 | \item{\dots}{additional arguments.} 18 | } 19 | \value{ 20 | a numeric vector of scalar real evaluations. 21 | } 22 | \description{ 23 | Evaluates a given S3 object of type \code{bernstein} on given 24 | data \code{D}. 25 | } 26 | \examples{ 27 | f <- function(x) x * sin(x*10) 28 | b <- bernstein(f, dims = 1) 29 | xs <- seq(from=0, to=1, length=50) 30 | mean((f(xs) - predict(b,xs))^2) 31 | 32 | } 33 | \references{ 34 | Francesco Aldà and Benjamin I. P. Rubinstein. "The Bernstein Mechanism: 35 | Function Release under Differential Privacy", in Proceedings of the 31st 36 | AAAI Conference on Artificial Intelligence (AAAI'2017), pp. 1705-1711, 37 | Feb 2017. 38 | } 39 | -------------------------------------------------------------------------------- /man/releaseResponse.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mechanisms.R 3 | \name{releaseResponse} 4 | \alias{releaseResponse} 5 | \title{\code{DPMech} private release method.} 6 | \usage{ 7 | releaseResponse(mechanism, privacyParams, X) 8 | } 9 | \arguments{ 10 | \item{mechanism}{an object of class \code{\link{DPMech-class}}.} 11 | 12 | \item{privacyParams}{an object of class \code{\link{DPParamsEps}} or subclass.} 13 | 14 | \item{X}{a privacy-sensitive dataset, if using sensitivity sampler a: list, 15 | matrix, data frame, numeric/character vector.} 16 | } 17 | \value{ 18 | list with slots per argument, including at least: actual privacy 19 | parameters \code{privacyParams}, and response \code{response}. 20 | } 21 | \description{ 22 | Runs the differentially-private mechanism on given data. 23 | } 24 | -------------------------------------------------------------------------------- /man/sensitivityNorm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mechanisms.R 3 | \name{sensitivityNorm} 4 | \alias{sensitivityNorm} 5 | \title{\code{DPMech} sensitivity-inducing norm.} 6 | \usage{ 7 | sensitivityNorm(mechanism, X1, X2) 8 | } 9 | \arguments{ 10 | \item{mechanism}{an object of class \code{\link{DPMech-class}}.} 11 | 12 | \item{X1}{a privacy-sensitive dataset.} 13 | 14 | \item{X2}{a privacy-sensitive dataset.} 15 | } 16 | \description{ 17 | Norm of a \code{\link{DPMech-class}}'s non-private \code{target} function 18 | evaluated on two given databases \code{X1}, \code{X2}. 19 | } 20 | -------------------------------------------------------------------------------- /man/sensitivitySampler-DPMech-function-numeric-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sensitivity_sampler.R 3 | \docType{methods} 4 | \name{sensitivitySampler,DPMech,function,numeric-method} 5 | \alias{sensitivitySampler,DPMech,function,numeric-method} 6 | \title{Sensitivity sampler for \code{\link{DPMech-class}}'s.} 7 | \usage{ 8 | \S4method{sensitivitySampler}{DPMech,`function`,numeric}(object, oracle, n, 9 | m = NA_integer_, gamma = NA_real_) 10 | } 11 | \arguments{ 12 | \item{object}{an object of class \code{\link{DPMech-class}}.} 13 | 14 | \item{oracle}{a source of random databases. A function returning: list, 15 | matrix/data.frame (data in rows), numeric/character vector of records if 16 | given desired length > 1; or single record given length 1, respectively 17 | a list element, a row/named row, a single numeric/character. Whichever 18 | type is used should be expected by \code{object@target}.} 19 | 20 | \item{n}{database size scalar positive numeric, integer-valued.} 21 | 22 | \item{m}{sensitivity sample size scalar positive numeric, integer-valued.} 23 | 24 | \item{gamma}{RDP privacy confidence level.} 25 | } 26 | \value{ 27 | \code{object} with updated \code{gammaSensitivity} slot. 28 | } 29 | \description{ 30 | Given a constructed \code{\link{DPMech-class}}, complete with \code{target} 31 | function and \code{sensitivityNorm,} and an \code{oracle} for producing 32 | records, samples the sensitivity of the target function to set the 33 | mechanism's \code{sensitivity}. 34 | } 35 | \examples{ 36 | ## Simple example with unbounded data hence no global sensitivity. 37 | f <- function(xs) mean(xs) 38 | m <- DPMechLaplace(target = f, dims = 1) 39 | m@sensitivity ## Inf 40 | m@gammaSensitivity ## NA as Laplace is naturally eps-DP 41 | P <- function(n) rnorm(n) 42 | m <- sensitivitySampler(m, oracle = P, n = 100, gamma = 0.33) 43 | m@sensitivity ## small like 0.03... 44 | m@gammaSensitivity ## 0.33 as directed, now m is (eps,gam)-DP. 45 | 46 | } 47 | \references{ 48 | Benjamin I. P. Rubinstein and Francesco Aldà. "Pain-Free Random Differential 49 | Privacy with Sensitivity Sampling", accepted into the 34th International 50 | Conference on Machine Learning (ICML'2017), May 2017. 51 | } 52 | -------------------------------------------------------------------------------- /man/sensitivitySampler.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sensitivity_sampler.R 3 | \name{sensitivitySampler} 4 | \alias{sensitivitySampler} 5 | \title{Sensitivity sampler for \code{\link{DPMech-class}}'s.} 6 | \usage{ 7 | sensitivitySampler(object, oracle, n, m = NA_integer_, gamma = NA_real_) 8 | } 9 | \arguments{ 10 | \item{object}{an object of class \code{\link{DPMech-class}}.} 11 | 12 | \item{oracle}{a source of random databases. A function returning: list, 13 | matrix/data.frame (data in rows), numeric/character vector of records if 14 | given desired length > 1; or single record given length 1, respectively 15 | a list element, a row/named row, a single numeric/character. Whichever 16 | type is used should be expected by \code{object@target}.} 17 | 18 | \item{n}{database size scalar positive numeric, integer-valued.} 19 | 20 | \item{m}{sensitivity sample size scalar positive numeric, integer-valued.} 21 | 22 | \item{gamma}{RDP privacy confidence level.} 23 | } 24 | \value{ 25 | \code{object} with updated \code{gammaSensitivity} slot. 26 | } 27 | \description{ 28 | Given a constructed \code{\link{DPMech-class}}, complete with \code{target} 29 | function and \code{sensitivityNorm,} and an \code{oracle} for producing 30 | records, samples the sensitivity of the target function to set the 31 | mechanism's \code{sensitivity}. 32 | } 33 | \examples{ 34 | ## Simple example with unbounded data hence no global sensitivity. 35 | f <- function(xs) mean(xs) 36 | m <- DPMechLaplace(target = f, dims = 1) 37 | m@sensitivity ## Inf 38 | m@gammaSensitivity ## NA as Laplace is naturally eps-DP 39 | P <- function(n) rnorm(n) 40 | m <- sensitivitySampler(m, oracle = P, n = 100, gamma = 0.33) 41 | m@sensitivity ## small like 0.03... 42 | m@gammaSensitivity ## 0.33 as directed, now m is (eps,gam)-DP. 43 | 44 | } 45 | \references{ 46 | Benjamin I. P. Rubinstein and Francesco Aldà. "Pain-Free Random Differential 47 | Privacy with Sensitivity Sampling", accepted into the 34th International 48 | Conference on Machine Learning (ICML'2017), May 2017. 49 | } 50 | -------------------------------------------------------------------------------- /man/sensitivitySamplerManual-DPMech-function-numeric-numeric-numeric-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sensitivity_sampler.R 3 | \docType{methods} 4 | \name{sensitivitySamplerManual,DPMech,function,numeric,numeric,numeric-method} 5 | \alias{sensitivitySamplerManual,DPMech,function,numeric,numeric,numeric-method} 6 | \title{Sensitivity sampler for \code{\link{DPMech-class}}.} 7 | \usage{ 8 | 9 | \S4method{sensitivitySamplerManual}{DPMech,`function`,numeric,numeric,numeric}(object, 10 | oracle, n, m, k) 11 | } 12 | \arguments{ 13 | \item{object}{an object of class \code{\link{DPMech-class}}.} 14 | 15 | \item{oracle}{a source of random databases. A function returning: list, 16 | matrix/data.frame (data in rows), numeric/character vector of records if 17 | given desired length > 1; or single record given length 1, respectively 18 | a list element, a row/named row, a single numeric/character. Whichever 19 | type is used should be expected by \code{object@target}.} 20 | 21 | \item{n}{database size scalar positive numeric, integer-valued.} 22 | 23 | \item{m}{sensitivity sample size scalar positive numeric, integer-valued.} 24 | 25 | \item{k}{order statistic index in {1,...,\code{m}}.} 26 | } 27 | \value{ 28 | \code{object} with updated sensitivity parameter. 29 | } 30 | \description{ 31 | Given a constructed \code{\link{DPMech-class}}, complete with \code{target} 32 | function and \code{sensitivityNorm,} and an \code{oracle} for producing 33 | records, samples the sensitivity of the target function to set the 34 | mechanism's \code{sensitivity}. Typically the method 35 | \code{\link{sensitivitySampler}} should be used instead; NOTE this method 36 | does not properly set the \code{gammaSensitivity} slot of 37 | \code{\link{DPMech-class}} unlike the preferred method. 38 | } 39 | \examples{ 40 | ## Simple example with unbounded data hence no global sensitivity. 41 | f <- function(xs) mean(xs) 42 | m <- DPMechLaplace(target = f, dims = 1) 43 | P <- function(n) rnorm(n) 44 | m <- sensitivitySamplerManual(m, oracle = P, n = 100, m = 10, k = 10) 45 | m@sensitivity 46 | 47 | } 48 | \references{ 49 | Benjamin I. P. Rubinstein and Francesco Aldà. "Pain-Free Random Differential 50 | Privacy with Sensitivity Sampling", accepted into the 34th International 51 | Conference on Machine Learning (ICML'2017), May 2017. 52 | } 53 | \seealso{ 54 | \code{\link{sensitivitySampler}} preferred method for sensitivity 55 | sampling. 56 | } 57 | -------------------------------------------------------------------------------- /man/sensitivitySamplerManual-DPMechNumeric-function-numeric-numeric-numeric-method.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sensitivity_sampler.R 3 | \docType{methods} 4 | \name{sensitivitySamplerManual,DPMechNumeric,function,numeric,numeric,numeric-method} 5 | \alias{sensitivitySamplerManual,DPMechNumeric,function,numeric,numeric,numeric-method} 6 | \title{Sensitivity sampler for \code{\link{DPMechNumeric-class}}.} 7 | \usage{ 8 | 9 | \S4method{sensitivitySamplerManual}{DPMechNumeric,`function`,numeric,numeric,numeric}(object, 10 | oracle, n, m, k) 11 | } 12 | \arguments{ 13 | \item{object}{an object of class \code{\link{DPMechNumeric-class}}.} 14 | 15 | \item{oracle}{a source of random databases. A function returning: list, 16 | matrix/data.frame (data in rows), numeric/character vector of records if 17 | given desired length > 1; or single record given length 1, respectively 18 | a list element, a row/named row, a single numeric/character. Whichever 19 | type is used should be expected by \code{object@target}.} 20 | 21 | \item{n}{database size scalar positive numeric, integer-valued.} 22 | 23 | \item{m}{sensitivity sample size scalar positive numeric, integer-valued.} 24 | 25 | \item{k}{order statistic index in {1,...,\code{m}}.} 26 | } 27 | \value{ 28 | \code{object} with updated sensitivity parameter, and (potentially) 29 | \code{dims}. 30 | } 31 | \description{ 32 | Given a constructed \code{\link{DPMechNumeric-class}}, complete with 33 | \code{target} function and \code{sensitivityNorm,} and an \code{oracle} for 34 | producing records, samples the sensitivity of the target function to set the 35 | mechanism's \code{sensitivity}. Typically the method 36 | \code{\link{sensitivitySampler}} should be used instead; NOTE this method 37 | does not properly set the \code{gammaSensitivity} slot of 38 | \code{\link{DPMech-class}} unlike the preferred method. This method can 39 | probe \code{target} to determine response dimension when the 40 | corresponding \code{object@dims} is \code{NA}. 41 | } 42 | \examples{ 43 | ## Simple example with unbounded data hence no global sensitivity. 44 | f <- function(xs) mean(xs) 45 | m <- DPMechLaplace(target = f, dims = 1) 46 | P <- function(n) rnorm(n) 47 | m <- sensitivitySamplerManual(m, oracle = P, n = 100, m = 10, k = 10) 48 | m@sensitivity 49 | 50 | } 51 | \references{ 52 | Benjamin I. P. Rubinstein and Francesco Aldà. "Pain-Free Random Differential 53 | Privacy with Sensitivity Sampling", accepted into the 34th International 54 | Conference on Machine Learning (ICML'2017), May 2017. 55 | } 56 | \seealso{ 57 | \code{\link{sensitivitySampler}} preferred method for sensitivity 58 | sampling. 59 | } 60 | -------------------------------------------------------------------------------- /man/sensitivitySamplerManual.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sensitivity_sampler.R 3 | \name{sensitivitySamplerManual} 4 | \alias{sensitivitySamplerManual} 5 | \title{Sensitivity sampler for \code{\link{DPMech-class}}.} 6 | \usage{ 7 | sensitivitySamplerManual(object, oracle, n, m, k) 8 | } 9 | \arguments{ 10 | \item{object}{an object of class \code{\link{DPMech-class}}.} 11 | 12 | \item{oracle}{a source of random databases. A function returning: list, 13 | matrix/data.frame (data in rows), numeric/character vector of records if 14 | given desired length > 1; or single record given length 1, respectively 15 | a list element, a row/named row, a single numeric/character. Whichever 16 | type is used should be expected by \code{object@target}.} 17 | 18 | \item{n}{database size scalar positive numeric, integer-valued.} 19 | 20 | \item{m}{sensitivity sample size scalar positive numeric, integer-valued.} 21 | 22 | \item{k}{order statistic index in {1,...,\code{m}}.} 23 | } 24 | \value{ 25 | \code{object} with updated sensitivity parameter. 26 | } 27 | \description{ 28 | Given a constructed \code{\link{DPMech-class}}, complete with \code{target} 29 | function and \code{sensitivityNorm,} and an \code{oracle} for producing 30 | records, samples the sensitivity of the target function to set the 31 | mechanism's \code{sensitivity}. Typically the method 32 | \code{\link{sensitivitySampler}} should be used instead; NOTE this method 33 | does not properly set the \code{gammaSensitivity} slot of 34 | \code{\link{DPMech-class}} unlike the preferred method. 35 | } 36 | \examples{ 37 | ## Simple example with unbounded data hence no global sensitivity. 38 | f <- function(xs) mean(xs) 39 | m <- DPMechLaplace(target = f, dims = 1) 40 | P <- function(n) rnorm(n) 41 | m <- sensitivitySamplerManual(m, oracle = P, n = 100, m = 10, k = 10) 42 | m@sensitivity 43 | 44 | } 45 | \references{ 46 | Benjamin I. P. Rubinstein and Francesco Aldà. "Pain-Free Random Differential 47 | Privacy with Sensitivity Sampling", accepted into the 34th International 48 | Conference on Machine Learning (ICML'2017), May 2017. 49 | } 50 | \seealso{ 51 | \code{\link{sensitivitySampler}} preferred method for sensitivity 52 | sampling. 53 | } 54 | -------------------------------------------------------------------------------- /man/setDelta-set.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/privacy_params.R 3 | \name{setDelta<-} 4 | \alias{setDelta<-} 5 | \title{Setter for slot \code{delta}.} 6 | \usage{ 7 | setDelta(object) <- value 8 | } 9 | \arguments{ 10 | \item{object}{the instance of \code{DPParamsDel}.} 11 | 12 | \item{value}{positive numeric \eqn{\delta} value.} 13 | } 14 | \description{ 15 | Use this method instead of slot \code{delta}. 16 | } 17 | \seealso{ 18 | \code{\link{DPParamsDel}}. 19 | } 20 | -------------------------------------------------------------------------------- /man/setEpsilon-set.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/privacy_params.R 3 | \name{setEpsilon<-} 4 | \alias{setEpsilon<-} 5 | \title{Setter for slot \code{epsilon}.} 6 | \usage{ 7 | setEpsilon(object) <- value 8 | } 9 | \arguments{ 10 | \item{object}{the instance of \code{DPParamsEps}.} 11 | 12 | \item{value}{positive numeric \eqn{\epsilon} value.} 13 | } 14 | \description{ 15 | Use this method instead of slot \code{epsilon}. 16 | } 17 | \seealso{ 18 | \code{\link{DPParamsEps}}. 19 | } 20 | -------------------------------------------------------------------------------- /man/setGamma-set.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/privacy_params.R 3 | \name{setGamma<-} 4 | \alias{setGamma<-} 5 | \title{Setter for slot \code{gamma}.} 6 | \usage{ 7 | setGamma(object) <- value 8 | } 9 | \arguments{ 10 | \item{object}{the instance of \code{DPParamsGam}.} 11 | 12 | \item{value}{positive numeric \eqn{\gamma} value.} 13 | } 14 | \description{ 15 | Use this method instead of slot \code{gamma}. 16 | } 17 | \seealso{ 18 | \code{\link{DPParamsGam}}. 19 | } 20 | -------------------------------------------------------------------------------- /present/2017-07-25 launchvic/diffpriv.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 launchvic/diffpriv.pptx -------------------------------------------------------------------------------- /present/2017-07-25 launchvic/handout.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 launchvic/handout.pptx -------------------------------------------------------------------------------- /present/2017-07-25 launchvic/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 launchvic/logo.png -------------------------------------------------------------------------------- /present/2017-07-25 launchvic/pckr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 launchvic/pckr.png -------------------------------------------------------------------------------- /present/2017-07-25 launchvic/poster.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 launchvic/poster.pptx -------------------------------------------------------------------------------- /present/2017-07-25 launchvic/svm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 launchvic/svm.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/.gitignore: -------------------------------------------------------------------------------- 1 | talk-diffpriv.aux 2 | talk-diffpriv.log 3 | talk-diffpriv.nav 4 | talk-diffpriv.out 5 | talk-diffpriv.snm 6 | talk-diffpriv.tex~ 7 | talk-diffpriv.toc 8 | -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/Demos/Demos.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/Demos/sampler.R: -------------------------------------------------------------------------------- 1 | n <- 250 2 | D <- runif(n) 3 | D <- cbind(D, sin(D*10)*D + rnorm(n, mean=0, sd=0.2)) 4 | pck_regression <- function(D, bandwidth = 0.1) { 5 | K <- function(x) exp(-x^2/2) 6 | ids <- sort(D[,1], decreasing = FALSE, index.return = TRUE)$ix 7 | D <- D[ids, ] 8 | n <- nrow(D) 9 | ws <- (D[2:n,1] - D[1:(n-1),1]) * D[2:n,2] 10 | predictor <- function(x) { 11 | sum(ws * sapply((x - D[2:n,1]) / bandwidth, K)) / bandwidth 12 | } 13 | return(predictor) 14 | } 15 | P <- function(n) { # a sampler of random, "plausible", datasets 16 | Dx <- runif(n) 17 | Dy <- rep(0, n) 18 | if (runif(1) < 0.95) Dy <- Dy + Dx 19 | if (runif(1) < 0.5) Dy <- Dy * sin(Dx) 20 | if (runif(1) < 0.5) Dy <- Dy * cos(Dx) 21 | cbind(Dx, Dy + rnorm(n, mean=0, sd=0.2)) 22 | } 23 | 24 | plot(D, pch=20, cex=0.70, xlab="X", ylab="Y", ylim=c(-1,1.5), main="Priestly-Chao Kernel Regression") 25 | model <- pck_regression(D) 26 | xs <- seq(from=0, to=1, length=50) 27 | ys <- sapply(xs, model) 28 | lines(xs, ys, col="red", lwd=2, lty="dashed") 29 | library(diffpriv) 30 | m <- DPMechBernstein(target=pck_regression, latticeK=25, dims=1) 31 | m <- sensitivitySampler(m, oracle=P, n=n, gamma=0.20, m=500) 32 | R <- releaseResponse(m, DPParamsEps(epsilon=5), D) 33 | privmodel <- R$response 34 | ys <- R$response(xs) 35 | lines(xs, ys, col="blue", lwd=2) 36 | 37 | -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/CC-refs.txt: -------------------------------------------------------------------------------- 1 | https://pixabay.com/en/brain-anatomy-neurons-2070412/ 2 | https://commons.wikimedia.org/wiki/File:Synapse_in_brain.jpg 3 | https://commons.wikimedia.org/wiki/File:Brain_power.jpg 4 | https://pixabay.com/en/forward-robot-2083419/ 5 | -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/KDE_utility_vs_privacy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/KDE_utility_vs_privacy.pdf -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/PPTfigs.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/PPTfigs.pptx -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/Privacy-Preserving Mechanisms for SVM Learning.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/Privacy-Preserving Mechanisms for SVM Learning.pdf -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/brain1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/brain1.jpg -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/brain2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/brain2.jpg -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/brain3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/brain3.jpg -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/brain4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/brain4.jpg -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/indistinguishable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/indistinguishable.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/laplace-proof.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/laplace-proof.PNG -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/logo-diffpriv-alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/logo-diffpriv-alert.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/logo-diffpriv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/logo-diffpriv.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/logo-um.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/logo-um.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/logo-uscb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/logo-uscb.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/m-vs-gamma.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/m-vs-gamma.pdf -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/mechanism.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/mechanism.PNG -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/news-godel.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/news-godel.PNG -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/news-medicare.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/news-medicare.PNG -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/news-netflix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/news-netflix.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/oppts.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/oppts.PNG -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/paper-svm-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/paper-svm-1.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/paper-svm-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/paper-svm-2.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/paper-svm-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/paper-svm-3.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/results-bernstein-poly.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/results-bernstein-poly.PNG -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/results-bernstein-svm.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/results-bernstein-svm.PNG -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/samplerhowto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/samplerhowto.png -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/figures/screenshot-homepage.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/figures/screenshot-homepage.PNG -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/laplace.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/laplace.mp4 -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/sampler.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/sampler.mp4 -------------------------------------------------------------------------------- /present/2017-07-25 unimelb/talk-diffpriv.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/2017-07-25 unimelb/talk-diffpriv.pdf -------------------------------------------------------------------------------- /present/automl2017/diffpriv.bib: -------------------------------------------------------------------------------- 1 | @inproceedings{rubinstein2017sampler, 2 | title={Pain-Free Random Differential Privacy with Sensitivity Sampling}, 3 | author={Rubinstein, Benjamin I. P. and Ald{\`a}, Francesco}, 4 | year = {2017}, 5 | booktitle = {Proceedings of the 34th International Conference on Machine Learning (ICML'2017)}, 6 | note={to appear; \url{https://arxiv.org/abs/1706.02562}} 7 | } 8 | 9 | @article{hall2012random, 10 | title={Random Differential Privacy}, 11 | author={Hall, Rob and Rinaldo, Alessandro and Wasserman, Larry}, 12 | journal={Journal of Privacy and Confidentiality}, 13 | volume={4}, 14 | number={2}, 15 | pages={43--59}, 16 | year={2012} 17 | } 18 | 19 | @inproceedings{dwork2006calibrating, 20 | title={Calibrating noise to sensitivity in private data analysis}, 21 | author={Dwork, Cynthia and McSherry, Frank and Nissim, Kobbi and Smith, Adam}, 22 | booktitle={Theory of Cryptography Conference}, 23 | pages={265--284}, 24 | year={2006}, 25 | organization={Springer} 26 | } 27 | 28 | @inproceedings{mcsherry2007mechanism, 29 | title={Mechanism design via differential privacy}, 30 | author={McSherry, Frank and Talwar, Kunal}, 31 | booktitle={48th Annual IEEE Symposium on Foundations of Computer Science, 2007 (FOCS'07)}, 32 | pages={94--103}, 33 | year={2007}, 34 | organization={IEEE} 35 | } 36 | 37 | @article{dwork2014algorithmic, 38 | title={The Algorithmic Foundations of Differential Privacy}, 39 | author={Dwork, Cynthia and Roth, Aaron}, 40 | journal={Foundations and Trends in Theoretical Computer Science}, 41 | volume={9}, 42 | number={3--4}, 43 | pages={211--407}, 44 | year={2014}, 45 | publisher={Now Publishers, Inc.} 46 | } 47 | 48 | @inproceedings{alda2017bernstein, 49 | title={The {B}ernstein mechanism: Function release under differential privacy}, 50 | author={Ald{\`a}, Francesco and Rubinstein, Benjamin I. P.}, 51 | year = {2017}, 52 | booktitle = {Proceedings of the 31st AAAI Conference on Artificial Intelligence (AAAI'2017)}, 53 | pages = {1705--1711} 54 | } 55 | 56 | @article{rubinstein2012svm, 57 | title={Learning in a Large Function Space: Privacy-Preserving Mechanisms for {SVM} Learning}, 58 | author={Rubinstein, Benjamin I. P. and Bartlett, Peter L. and Huang, Ling and Taft, Nina}, 59 | journal={Journal of Privacy and Confidentiality}, 60 | volume={4}, 61 | number={1}, 62 | pages={65--100}, 63 | year={2012} 64 | } 65 | 66 | @inproceedings{chaudhuri2009logistic, 67 | title={Privacy-preserving logistic regression}, 68 | author={Chaudhuri, Kamalika and Monteleoni, Claire}, 69 | booktitle={Advances in Neural Information Processing Systems}, 70 | pages={289--296}, 71 | year={2009} 72 | } 73 | 74 | @article{chaudhuri2011erm, 75 | title={Differentially private empirical risk minimization}, 76 | author={Chaudhuri, Kamalika and Monteleoni, Claire and Sarwate, Anand D}, 77 | journal={Journal of Machine Learning Research}, 78 | volume={12}, 79 | number={Mar}, 80 | pages={1069--1109}, 81 | year={2011} 82 | } 83 | -------------------------------------------------------------------------------- /present/automl2017/diffpriv.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/automl2017/diffpriv.pdf -------------------------------------------------------------------------------- /present/jmlrmloss2017/.gitignore: -------------------------------------------------------------------------------- 1 | cover.docx 2 | cover.pdf 3 | jmlr-microtome.pdf 4 | release.pdf 5 | -------------------------------------------------------------------------------- /present/jmlrmloss2017/rubinstein17a.bib: -------------------------------------------------------------------------------- 1 | @InProceedings{rubinstein2017sampler, 2 | title = {Pain-Free Random Differential Privacy with Sensitivity Sampling}, 3 | author = {Benjamin I. P. Rubinstein and Francesco Ald{\`a}}, 4 | booktitle = {Proceedings of the 34th International Conference on Machine Learning}, 5 | pages = {2950--2959}, 6 | year = {2017}, 7 | editor = {Doina Precup and Yee Whye Teh}, 8 | volume = {70}, 9 | series = {Proceedings of Machine Learning Research}, 10 | publisher = {PMLR} 11 | } 12 | 13 | @article{hall2012random, 14 | title={Random Differential Privacy}, 15 | author={Hall, Rob and Rinaldo, Alessandro and Wasserman, Larry}, 16 | journal={Journal of Privacy and Confidentiality}, 17 | volume={4}, 18 | number={2}, 19 | pages={43--59}, 20 | year={2012} 21 | } 22 | 23 | @inproceedings{dwork2006calibrating, 24 | title={Calibrating noise to sensitivity in private data analysis}, 25 | author={Dwork, Cynthia and McSherry, Frank and Nissim, Kobbi and Smith, Adam}, 26 | booktitle={Theory of Cryptography Conference}, 27 | pages={265--284}, 28 | year={2006}, 29 | organization={Springer} 30 | } 31 | 32 | @inproceedings{mcsherry2007mechanism, 33 | title={Mechanism design via differential privacy}, 34 | author={McSherry, Frank and Talwar, Kunal}, 35 | booktitle={48th Annual IEEE Symposium on Foundations of Computer Science}, 36 | pages={94--103}, 37 | year={2007}, 38 | organization={IEEE} 39 | } 40 | 41 | @article{dwork2014algorithmic, 42 | title={The Algorithmic Foundations of Differential Privacy}, 43 | author={Dwork, Cynthia and Roth, Aaron}, 44 | journal={Foundations and Trends in Theoretical Computer Science}, 45 | volume={9}, 46 | number={3--4}, 47 | pages={211--407}, 48 | year={2014}, 49 | publisher={Now Publishers, Inc.} 50 | } 51 | 52 | @inproceedings{alda2017bernstein, 53 | title={The {B}ernstein mechanism: Function release under differential privacy}, 54 | author={Ald{\`a}, Francesco and Rubinstein, Benjamin I. P.}, 55 | year = {2017}, 56 | booktitle = {Proceedings of the 31st AAAI Conference on Artificial Intelligence}, 57 | pages = {1705--1711} 58 | } 59 | 60 | @article{rubinstein2012svm, 61 | title={Learning in a Large Function Space: Privacy-Preserving Mechanisms for {SVM} Learning}, 62 | author={Rubinstein, Benjamin I. P. and Bartlett, Peter L. and Huang, Ling and Taft, Nina}, 63 | journal={Journal of Privacy and Confidentiality}, 64 | volume={4}, 65 | number={1}, 66 | pages={65--100}, 67 | year={2012} 68 | } 69 | 70 | @inproceedings{chaudhuri2009logistic, 71 | title={Privacy-preserving logistic regression}, 72 | author={Chaudhuri, Kamalika and Monteleoni, Claire}, 73 | booktitle={Advances in Neural Information Processing Systems}, 74 | pages={289--296}, 75 | year={2009} 76 | } 77 | 78 | @article{chaudhuri2011erm, 79 | title={Differentially private empirical risk minimization}, 80 | author={Chaudhuri, Kamalika and Monteleoni, Claire and Sarwate, Anand D}, 81 | journal={Journal of Machine Learning Research}, 82 | volume={12}, 83 | number={Mar}, 84 | pages={1069--1109}, 85 | year={2011} 86 | } 87 | -------------------------------------------------------------------------------- /present/jmlrmloss2017/rubinstein17a.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brubinstein/diffpriv/36d4a0d9b1e76cb15cdee321f5b935c96324c8ef/present/jmlrmloss2017/rubinstein17a.pdf -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(diffpriv) 3 | 4 | test_check("diffpriv") 5 | -------------------------------------------------------------------------------- /tests/testthat/test_bernstein.R: -------------------------------------------------------------------------------- 1 | library(diffpriv) 2 | context("Bernstein polynomials and mechanism") 3 | 4 | test_that(".bernstein_lattice() creates the appropriate lattice", { 5 | latt22 <- .bernstein_lattice(d=2, k=2) 6 | latt11 <- .bernstein_lattice(d=1, k=1) 7 | expect_is(latt11, "matrix") 8 | expect_equal(nrow(latt22), 9) 9 | expect_equal(ncol(latt22), 2) 10 | expect_equal(nrow(latt11), 2) 11 | expect_equal(ncol(latt11), 1) 12 | expect_equal(min(latt22), 0) 13 | expect_equal(max(latt22), 2) 14 | }) 15 | 16 | test_that(".bernstein_lattice() checks invalid input", { 17 | expect_error(.bernstein_lattice(d=1.1, k=2), "integer d", ignore.case=TRUE) 18 | expect_error(.bernstein_lattice(d=0, k=2), "integer d", ignore.case=TRUE) 19 | expect_error(.bernstein_lattice(d=1, k=2.5), "integer k", ignore.case=TRUE) 20 | expect_error(.bernstein_lattice(d=1, k=0), "integer k", ignore.case=TRUE) 21 | }) 22 | 23 | test_that("bernstein() checks invalid input", { 24 | f <- function(xs) xs[1] * sin(xs[2]*10) 25 | d <- 2 26 | k <- 5 27 | expect_error(bernstein(1, dims=d, k=k), "function", ignore.case = TRUE) 28 | expect_error(bernstein(f, dims=1.2, k=k), "integer dims", ignore.case = TRUE) 29 | expect_error(bernstein(f, dims=0, k=k), "integer dims", ignore.case = TRUE) 30 | expect_error(bernstein(f, dims=d, k=2.3), "integer k", ignore.case = TRUE) 31 | expect_error(bernstein(f, dims=d, k=0), "integer k", ignore.case = TRUE) 32 | }) 33 | 34 | test_that("bernstein() can construct S3 class", { 35 | tf <- function(xs) xs[1] * sin(xs[2]*10) 36 | d <- 2 37 | k <- 5 38 | bf <- bernstein(tf, dims = d, k = k) 39 | expect_is(bf, "bernstein") 40 | expect_true(any(names(bf) == "coeffs")) 41 | expect_length(bf$coeffs, (k+1)^d) 42 | }) 43 | 44 | test_that("predict.bernstein() checks invalid input", { 45 | tf <- function(xs) xs[1] * sin(xs[2]*10) 46 | d <- 2 47 | k <- 5 48 | X <- c(0.5, 0.5) 49 | bf <- bernstein(tf, dims = d, k = k) 50 | class(bf) <- "list" 51 | expect_error(predict.bernstein(bf,X), "type 'bernstein'", ignore.case = TRUE) 52 | bf <- bernstein(tf, dims = d, k = k) 53 | expect_error(predict(bf, "a"), "numeric data", ignore.case = TRUE) 54 | expect_error(predict(bf, -1:0), "unit interval", ignore.case = TRUE) 55 | expect_error(predict(bf, 1:2), "unit interval", ignore.case = TRUE) 56 | expect_error(predict(bf, matrix(0:1,ncol=1)), "columns", ignore.case = TRUE) 57 | expect_error(predict(bf, 1), "length", ignore.case = TRUE) 58 | }) 59 | 60 | test_that("predict.bernstein() can compute values", { 61 | tf <- function(xs) xs[1] * sin(xs[2]*10) 62 | d <- 2 63 | k <- 5 64 | bf <- bernstein(tf, dims = d, k = k) 65 | r <- predict(bf, c(0.2, 0.3)) 66 | expect_lte(r, 1) 67 | expect_gte(r, -1) 68 | tf <- function(x) x * sin(x*10) 69 | d <- 1 70 | k <- 5 71 | bf <- bernstein(tf, dims = d, k = k) 72 | expect_length(predict(bf, c(0.2, 0.3)), 2) 73 | }) 74 | 75 | test_that("DPMechBernstein validity checks", { 76 | expect_error(DPMechBernstein(latticeK=1.2, dims=2), 77 | "latticeK should be positive integer", ignore.case = TRUE) 78 | expect_error(DPMechBernstein(latticeK=0, dims=2), 79 | "latticeK should be positive integer", ignore.case = TRUE) 80 | expect_error(DPMechBernstein(dims=1.2, latticeK=2), 81 | "dims should be positive integer", ignore.case = TRUE) 82 | expect_error(DPMechBernstein(dims=0, latticeK=2), 83 | "dims should be positive integer", ignore.case = TRUE) 84 | }) 85 | 86 | test_that("DPMechBernstein show() operates", { 87 | m <- DPMechBernstein() 88 | expect_output(show(m), "bernstein mechanism", ignore.case = TRUE) 89 | }) 90 | 91 | test_that("DPMechBernstein releaseResponse() checks", { 92 | f <- function(X) { X } 93 | d <- 2 94 | k <- 5 95 | m <- DPMechBernstein(target = f, latticeK = k, dims = d, sensitivity = 1) 96 | p <- DPParamsEps(epsilon = 1) 97 | expect_error(releaseResponse(m, privacyParams = p, X = rnorm(2)), 98 | "not a function", ignore.case = TRUE) 99 | }) 100 | 101 | test_that("DPMechBernstein releaseResponse() operates", { 102 | f <- function(X) { function(xs) xs[1] * sin(xs[2]*10) } 103 | d <- 2 104 | k <- 5 105 | m <- DPMechBernstein(target = f, latticeK = k, dims = d, sensitivity = 1) 106 | p <- DPParamsEps(epsilon = 1) 107 | r <- releaseResponse(m, privacyParams = p, X = rnorm(2)) 108 | expect_true(any(names(r) == "response")) 109 | expect_is(r$response, "function") 110 | newX <- c(0.5, 0.5) 111 | newY <- r$response(newX) 112 | expect_is(newY, "numeric") 113 | expect_length(newY, 1) 114 | newX <- matrix(1:4 / 4, nrow=2) 115 | newY <- r$response(newX) 116 | expect_is(newY, "numeric") 117 | expect_length(newY, 2) 118 | }) 119 | 120 | test_that("DPMechBernstein sensitivityNorm() checks invalid input", { 121 | f <- function(D) { 2 } 122 | m <- DPMechBernstein(target = f, latticeK = 10, dims = 1) 123 | expect_error(sensitivityNorm(m,1,2), "not a function", ignore.case = TRUE) 124 | }) 125 | 126 | test_that("DPMechBernstein sensitivityNorm() values in range", { 127 | f <- function(D) { function(x) D*(x * sin(x*10)) } 128 | m <- DPMechBernstein(target = f, latticeK = 10, dims = 1) 129 | X1 <- 1 130 | X2 <- 2 131 | r <- sensitivityNorm(m, X1, X2) 132 | expect_lte(r, abs(X2 - X1)) 133 | expect_gte(r, 0) 134 | }) 135 | -------------------------------------------------------------------------------- /tests/testthat/test_mechanisms.R: -------------------------------------------------------------------------------- 1 | library(diffpriv) 2 | context("Generic DP mechanisms") 3 | 4 | test_that("DPMech show() runs without error", { 5 | qualF <- function(X) { function(r) sum(r == unlist(strsplit(X, ""))) } 6 | rs <- as.list(letters) 7 | m <- DPMechExponential(sensitivity = 5, target = qualF, responseSet = rs) 8 | expect_output(show(m), "exponential mechanism", ignore.case = TRUE) 9 | m@gammaSensitivity <- 0.2 10 | expect_output(show(m), "exponential mechanism", ignore.case = TRUE) 11 | m <- DPMechLaplace(target = function(xs) c(1, 2), sensitivity = 1, dims = 2) 12 | expect_output(show(m), "laplace mechanism", ignore.case = TRUE) 13 | m@gammaSensitivity <- 0.2 14 | expect_output(show(m), "laplace mechanism", ignore.case = TRUE) 15 | m <- DPMechGaussian(target = function(xs) c(1, 2), sensitivity = 1, dims = 2) 16 | expect_output(show(m), "gaussian mechanism", ignore.case = TRUE) 17 | }) 18 | 19 | test_that("DPMechLaplace response dimension", { 20 | m_no <- DPMechLaplace(target = function(xs) 1, sensitivity = 1, dims = 2) 21 | m_ok <- DPMechLaplace(target = function(xs) c(1, 2), sensitivity = 1, dims=2) 22 | m_df <- DPMechLaplace(target = function(xs) 1) 23 | m_ey <- DPMechLaplace(target = function(xs) numeric()) 24 | m_ey@dims <- 0 25 | p <- DPParamsEps() 26 | expect_warning(releaseResponse(m_no, privacyParams = p, X = 1:2), 27 | "Non-private target output has unexpected dimension.", ignore.case = TRUE) 28 | expect_warning(sensitivityNorm(m_no, 1:2, 1:2), 29 | "Non-private target output has unexpected dimension.", ignore.case = TRUE) 30 | expect_silent(releaseResponse(m_ok, privacyParams = p, X = 1:2)) 31 | expect_length(releaseResponse(m_ok, privacyParams = p, X= 1:2)$response, 2) 32 | expect_warning(sensitivityNorm(m_df, 1:2, 1:2), "No expected dim", 33 | ignore.case = TRUE) 34 | expect_equal(sensitivityNorm(m_ey, 1:2, 1:2), 0) 35 | }) 36 | 37 | test_that("DPMechGaussian response dimension", { 38 | m_ok <- DPMechGaussian(target = function(xs) c(1, 2), sensitivity = 1, dims=2) 39 | p <- DPParamsDel(epsilon = 1, delta = 0.1) 40 | expect_length(releaseResponse(m_ok, privacyParams = p, X= 1:2)$response, 2) 41 | }) 42 | 43 | test_that("DPMechGaussian's .numericNorm() is accurate", { 44 | m <- DPMechGaussian(target = function(xs) mean(xs)) 45 | xs <- c(1.5, -2) 46 | expect_equal(.numericNorm(m, xs, -xs), 5) 47 | }) 48 | 49 | test_that("DPMechLaplace checks are comprehensive", { 50 | p <- DPParamsEps(epsilon = 1) 51 | m <- DPMechLaplace(target = function(xs) "a", sensitivity = 1, dims = 1) 52 | expect_error(releaseResponse(m, privacyParams = p, X = 1:3), "numeric", 53 | ignore.case = TRUE) 54 | expect_error(sensitivityNorm(m, X1 = 1:2, X2 = 1:2), "numeric", 55 | ignore.case = TRUE) 56 | m <- DPMechLaplace(target = function(xs) 1, sensitivity = 1, dims = 2) 57 | expect_warning(sensitivityNorm(m, X1 = 1:2, X2 = 1:2), "dimension", 58 | ignore.case = TRUE) 59 | }) 60 | 61 | test_that("DPMechExponential responses in responseSet", { 62 | qualF <- function(X) { function(r) sum(r == unlist(strsplit(X, ""))) } 63 | rs <- as.list(letters) 64 | m <- DPMechExponential(sensitivity = 5, target = qualF, responseSet = rs) 65 | X <- strsplit("the quick brown fox jumps over the lazy dog"," ")[[1]] 66 | p <- DPParamsEps(epsilon = 1) 67 | expect_true(is.element(releaseResponse(m, p, X)$response, rs)) 68 | }) 69 | 70 | test_that("DPMechExponential upgrades to gamma", { 71 | qualF <- function(X) { function(r) sum(r == unlist(strsplit(X, ""))) } 72 | rs <- as.list(letters) 73 | m <- DPMechExponential(sensitivity = 5, target = qualF, responseSet = rs) 74 | m@gammaSensitivity <- 0.1 75 | X <- strsplit("the quick brown fox jumps over the lazy dog"," ")[[1]] 76 | p <- DPParamsEps(epsilon = 1) 77 | r <- releaseResponse(m, p, X) 78 | expect_s4_class(r$privacyParams, "DPParamsGam") 79 | expect_equal(getEpsilon(r$privacyParams), 1) 80 | expect_equal(getDelta(r$privacyParams), 0) 81 | expect_equal(getGamma(r$privacyParams), 0.1) 82 | }) 83 | 84 | test_that("DPMechExponential's Linfty sensitivity norm is accurate", { 85 | qualF <- function(X) { function(r) sum(r == unlist(strsplit(X, ""))) } 86 | rs <- as.list(letters) 87 | m <- DPMechExponential(target = qualF, responseSet = rs) 88 | D1 <- c("abcde", "aaaaa") 89 | D2 <- c("abcde", "fgh") 90 | expect_equal(sensitivityNorm(m, D1, D2), 5) 91 | }) 92 | 93 | test_that("DPMechExponential expects target returns function", { 94 | qualF <- function(X) mean(X) 95 | rs <- as.list(letters) 96 | m <- DPMechExponential(target = qualF, responseSet = rs) 97 | X <- 1:5 98 | expect_error(sensitivityNorm(m, X1 = X, X2 = X), 99 | "not a function", ignore.case = TRUE) 100 | expect_error(releaseResponse(m, privacyParams = DPParamsEps(), X = X), 101 | "not a function", ignore.case = TRUE) 102 | }) 103 | -------------------------------------------------------------------------------- /tests/testthat/test_pparams.R: -------------------------------------------------------------------------------- 1 | library(diffpriv) 2 | context("Privacy parameters") 3 | 4 | test_that("Invalid privacy parameter objects", { 5 | expect_error(DPParamsEps(epsilon = 0)) 6 | expect_error(DPParamsEps(epsilon = 1:2)) 7 | expect_error(DPParamsDel(epsilon = 1, delta = 1)) 8 | expect_error(DPParamsDel(epsilon = 0, delta = 0.5)) 9 | expect_error(DPParamsDel(epsilon = 1, delta = 1:2)) 10 | expect_error(DPParamsGam(epsilon = 1, delta = 0, gamma = 1)) 11 | expect_error(DPParamsGam(epsilon = 0, delta = 0, gamma = 0.05)) 12 | expect_error(DPParamsGam(epsilon = 1, delta = 1, gamma = 0.05)) 13 | expect_error(DPParamsGam(epsilon = 1, delta = 0, gamma = c(0.05, 0.1))) 14 | }) 15 | 16 | test_that("Valid privacy parameter objects", { 17 | expect_equal(DPParamsEps(epsilon = 1)@epsilon, 1) 18 | }) 19 | 20 | test_that("Getters get from privacy parameter objects", { 21 | expect_equal(getEpsilon(DPParamsEps(epsilon=1)), 1) 22 | expect_equal(getEpsilon(DPParamsDel(epsilon=2, delta=0.5)), 2) 23 | expect_equal(getEpsilon(DPParamsGam(epsilon=3, delta=0.5, gamma=0.1)), 3) 24 | expect_equal(getDelta(DPParamsDel(epsilon=2, delta=0.5)), 0.5) 25 | expect_equal(getGamma(DPParamsGam(epsilon=3, delta=0.5, gamma=0.1)), 0.1) 26 | }) 27 | 28 | test_that("Setters set privacy parameter objects", { 29 | x <- DPParamsEps(epsilon = 1) 30 | setEpsilon(x) <- 0.5 31 | expect_equal(getEpsilon(x), 0.5) 32 | x <- DPParamsDel(epsilon = 1, delta = 0.5) 33 | setEpsilon(x) <- 0.5 34 | expect_equal(getEpsilon(x), 0.5) 35 | rm(x) 36 | }) 37 | 38 | test_that("Privacy parameter show() prints", { 39 | p <- DPParamsEps() 40 | expect_output(show(p), "differential privacy level", ignore.case = TRUE) 41 | p <- DPParamsDel() 42 | expect_output(show(p), "differential privacy level", ignore.case = TRUE) 43 | p <- DPParamsGam() 44 | expect_output(show(p), "differential privacy level", ignore.case = TRUE) 45 | }) 46 | 47 | test_that("toGamma() converts to DPParamsGam", { 48 | eps <- 1 49 | del <- 0.1 50 | gam <- 0.2 51 | newgam <- 0.1 52 | ep <- DPParamsEps(epsilon = eps) 53 | dp <- DPParamsDel(epsilon = eps, delta = del) 54 | gp <- DPParamsGam(epsilon = eps, delta = del, gamma = gam) 55 | expect_equal(getEpsilon(toGamma(ep,newgam)), eps) 56 | expect_equal(getDelta(toGamma(ep,newgam)), 0) 57 | expect_equal(getGamma(toGamma(ep,newgam)), newgam) 58 | expect_equal(getEpsilon(toGamma(dp,newgam)), eps) 59 | expect_equal(getDelta(toGamma(dp,newgam)), del) 60 | expect_equal(getGamma(toGamma(dp,newgam)), newgam) 61 | expect_warning(gp <- toGamma(gp,newgam), "on DPParamsGam same as", ignore.case=TRUE) 62 | expect_equal(getGamma(gp), newgam) 63 | }) 64 | -------------------------------------------------------------------------------- /tests/testthat/test_ssampler.R: -------------------------------------------------------------------------------- 1 | library(diffpriv) 2 | context("DPMech sensitivity sampling") 3 | 4 | test_that("sensitivitySampler methods check types", { 5 | m <- DPMechLaplace(target = function(xs) mean(unlist(xs)), dims = 1) 6 | P <- function(n) if (n > 1) as.list(rnorm(n)) else rnorm(1) 7 | expect_error(sensitivitySamplerManual(m, oracle=P, n=1.1, m=100, k=99), 8 | "integer", ignore.case=TRUE) 9 | expect_error(sensitivitySamplerManual(m, oracle=P, n=0, m=100, k=99), 10 | "integer", ignore.case=TRUE) 11 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=100.1, k=99), 12 | "integer", ignore.case=TRUE) 13 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=0, k=0), 14 | "integer", ignore.case=TRUE) 15 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=100, k=99.9), 16 | "integer", ignore.case=TRUE) 17 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=100, k=101), 18 | "k is not in", ignore.case=TRUE) 19 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=100, k=0), 20 | "k is not in", ignore.case=TRUE) 21 | expect_error(.sensitivity_sampler_config(), "specify at least one", 22 | ignore.case = TRUE) 23 | expect_error(.sensitivity_sampler_config(m = 1.1), "m is not", 24 | ignore.case = TRUE) 25 | expect_error(.sensitivity_sampler_config(gamma = 1.1), "gamma is not", 26 | ignore.case = TRUE) 27 | expect_error(.sensitivity_sampler_config(gamma = 0.0001, m = 100), 28 | "must exceed", ignore.case = TRUE) 29 | qualF <- function(X) { function(r) sum(r == unlist(strsplit(X, ""))) } 30 | m <- DPMechExponential(target = qualF, responseSet = as.list(letters)) 31 | library(randomNames) 32 | P <- function(n) randomNames(n) 33 | expect_error(sensitivitySamplerManual(m, oracle=P, n=1.1, m=100, k=99), 34 | "integer", ignore.case=TRUE) 35 | expect_error(sensitivitySamplerManual(m, oracle=P, n=0, m=100, k=99), 36 | "integer", ignore.case=TRUE) 37 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=100.1, k=99), 38 | "integer", ignore.case=TRUE) 39 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=0, k=0), 40 | "integer", ignore.case=TRUE) 41 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=100, k=99.9), 42 | "integer", ignore.case=TRUE) 43 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=100, k=101), 44 | "k is not in", ignore.case=TRUE) 45 | expect_error(sensitivitySamplerManual(m, oracle=P, n=10, m=100, k=0), 46 | "k is not in", ignore.case=TRUE) 47 | }) 48 | 49 | test_that("sensitivitySampler() returns expected responses", { 50 | m <- DPMechLaplace(target = function(xs) mean(unlist(xs)), dims = 1) 51 | expect_identical(m@sensitivity, Inf) 52 | expect_true(is.na(m@gammaSensitivity)) 53 | P <- function(n) if (n > 1) as.list(rnorm(n)) else rnorm(1) 54 | gamma <- 0.33 55 | m <- sensitivitySampler(m, oracle = P, n = 100, gamma = gamma) 56 | expect_lt(m@sensitivity, Inf) 57 | expect_equal(m@gammaSensitivity, gamma) 58 | }) 59 | 60 | test_that("Responses post sensitivitySampler() are RDP", { 61 | dim <- 1 62 | m <- DPMechLaplace(target = function(xs) mean(unlist(xs)), dims = dim) 63 | P <- function(n) if (n > 1) as.list(rnorm(n)) else rnorm(1) 64 | epsilon <- 0.1 65 | gamma <- 0.33 66 | n <- 100 67 | 68 | ## Case: Given gamma only 69 | m <- sensitivitySampler(m, oracle = P, n = n, gamma = gamma) 70 | R <- releaseResponse(m, DPParamsEps(epsilon = epsilon), rnorm(n)) 71 | expect_true(is.element("response", names(R))) 72 | expect_true(is.numeric(R$response)) 73 | expect_length(R$response, dim) 74 | expect_true(is.element("privacyParams", names(R))) 75 | expect_is(R$privacyParams, "DPParamsGam") 76 | expect_equal(getEpsilon(R$privacyParams), epsilon) 77 | expect_equal(getDelta(R$privacyParams), 0) 78 | expect_equal(getGamma(R$privacyParams), gamma) 79 | 80 | ## Case: Given m only 81 | m <- DPMechLaplace(target = function(xs) mean(unlist(xs)), dims = dim) 82 | m <- sensitivitySampler(m, oracle = P, n = n, m = 50) 83 | R <- releaseResponse(m, DPParamsEps(epsilon = epsilon), rnorm(n)) 84 | expect_is(R$privacyParams, "DPParamsGam") 85 | 86 | ## Case: Given both m, gamma 87 | m <- DPMechLaplace(target = function(xs) mean(unlist(xs)), dims = dim) 88 | m <- sensitivitySampler(m, oracle = P, n = n, gamma = gamma, m = 50) 89 | R <- releaseResponse(m, DPParamsEps(epsilon = epsilon), rnorm(n)) 90 | expect_is(R$privacyParams, "DPParamsGam") 91 | }) 92 | 93 | test_that("sensitivitySampler() determines DPMechLaplace@dims", { 94 | m <- DPMechLaplace(target = function(xs) apply(xs, 2, mean)) 95 | P <- function(n) matrix(rnorm(3*n), ncol=3) 96 | m <- sensitivitySampler(m, oracle = P, n = 10, gamma = 0.33) 97 | expect_equal(m@dims, 3) 98 | }) 99 | -------------------------------------------------------------------------------- /tests/testthat/test_utils.R: -------------------------------------------------------------------------------- 1 | library(diffpriv) 2 | context("General utilities") 3 | 4 | test_that(".check_integer requires singleton numeric", { 5 | expect_false(.check_integer(1:3)) 6 | expect_false(.check_integer(as.integer(c()))) 7 | expect_false(.check_integer("foo bar")) 8 | }) 9 | 10 | test_that(".check_integer is true on and only on integral", { 11 | expect_false(.check_integer(1.1)) 12 | expect_false(.check_integer(-2.3)) 13 | expect_true(.check_integer(1)) 14 | expect_true(.check_integer(-2.0)) 15 | }) 16 | 17 | test_that(".rlap errors gracefully on ill-formed input", { 18 | expect_error(.rlap(1.2), "Given sample size is not scalar non-negative integer.") 19 | expect_error(.rlap(-1), "Given sample size is not scalar non-negative integer.") 20 | expect_error(.rlap(1, location="a"), "Given location is a not a scalar numeric.") 21 | expect_error(.rlap(2, location=1:3), "Given location is a not a scalar numeric.") 22 | expect_error(.rlap(1, scale="a"), "Given scale is not scalar non-negative.") 23 | expect_error(.rlap(2, scale=1:2), "Given scale is not scalar non-negative.") 24 | expect_error(.rlap(2, scale=-0.1), "Given scale is not scalar non-negative.") 25 | }) 26 | 27 | test_that(".rlap produces expected numbers of observations", { 28 | expect_equal(length(.rlap(2.0)), 2) 29 | expect_equal(length(.rlap(0)), 0) 30 | expect_equal(length(.rlap(1)), 1) 31 | expect_equal(length(.rlap(1, location=-1)), 1) 32 | expect_equal(length(.rlap(1, location=+1)), 1) 33 | expect_equal(length(.rlap(2, location=1, scale=2)), 2) 34 | }) 35 | 36 | test_that(".l1norm produces expected values", { 37 | expect_equal(.l1norm(numeric()), 0) 38 | expect_equal(.l1norm(c(-1, 0, 0.5)), 1.5) 39 | }) 40 | 41 | test_that(".linfty_norm produces expected values", { 42 | expect_equal(.linfty_norm(numeric()), 0) 43 | expect_equal(.linfty_norm(c(-1, 0, 0.5)), 1) 44 | }) 45 | 46 | test_that(".l2norm produces expected values", { 47 | expect_error(.l2norm("a"), "not numeric", ignore.case = TRUE) 48 | expect_equal(.l2norm(numeric()), 0) 49 | expect_equal(.l2norm(3:4), 5) 50 | }) 51 | 52 | test_that(".constant_target is constant-valued", { 53 | expect_equal(.constant_target(1), 0) 54 | expect_equal(.constant_target(1:3), 0) 55 | expect_equal(.constant_target("a"), 0) 56 | }) 57 | 58 | test_that(".generic_append() can append different types", { 59 | # lists 60 | expect_length(.generic_append(as.list(1:9), 10), 10) 61 | expect_length(.generic_append(list(), 1), 1) 62 | # matrices 63 | expect_equal(nrow(.generic_append(matrix(1:9, nrow=3), 1:3)), 4) 64 | expect_equal(nrow(.generic_append(matrix(nrow=0, ncol=3), 65 | matrix(1:3, nrow=1))), 1) 66 | # data frames 67 | D <- cbind(as.data.frame(matrix(1:9, nrow=3)), letters[1:3]) 68 | Dnew <- cbind(as.data.frame(matrix(1:3, nrow=1)), "d") 69 | names(Dnew) <- names(D) 70 | expect_equal(nrow(.generic_append(D, Dnew)), 4) 71 | # numeric vectors 72 | expect_length(.generic_append(1:9, 10), 10) 73 | expect_length(.generic_append(numeric(), c(1)), 1) 74 | # character vectors 75 | expect_length(.generic_append(letters[1:9], letters[10]), 10) 76 | expect_length(.generic_append(character(0), "the brown fox"), 1) 77 | # rejects unexepcted 78 | expect_error(.generic_append(DPParamsEps(), 2), "unrecognized", 79 | ignore.case = TRUE) 80 | }) 81 | -------------------------------------------------------------------------------- /vignettes/bernstein-concordance.tex: -------------------------------------------------------------------------------- 1 | \Sconcordance{concordance:bernstein.tex:bernstein.Rnw:% 2 | 1 47 1 50 0 1 9 30 1 4 0 6 1 13 0 7 1 12 0 10 1 8 0 % 3 | 31 1 4 0 8 1 4 0 31 1 4 0 11 1 4 0 12 1 8 0 30 1} 4 | -------------------------------------------------------------------------------- /vignettes/diffpriv-concordance.tex: -------------------------------------------------------------------------------- 1 | \Sconcordance{concordance:diffpriv.tex:diffpriv.Rnw:% 2 | 1 86 1 50 0 1 9 130 1 8 0 89 1 8 0 27 1} 3 | -------------------------------------------------------------------------------- /vignettes/diffpriv.bib: -------------------------------------------------------------------------------- 1 | @InProceedings{rubinstein2017sampler, 2 | title = {Pain-Free Random Differential Privacy with Sensitivity Sampling}, 3 | author = {Benjamin I. P. Rubinstein and Francesco Ald{\`a}}, 4 | booktitle = {Proceedings of the 34th International Conference on Machine Learning}, 5 | pages = {2950--2959}, 6 | year = {2017}, 7 | editor = {Doina Precup and Yee Whye Teh}, 8 | volume = {70}, 9 | series = {Proceedings of Machine Learning Research}, 10 | publisher = {PMLR} 11 | } 12 | 13 | @article{hall2012random, 14 | title={Random Differential Privacy}, 15 | author={Hall, Rob and Rinaldo, Alessandro and Wasserman, Larry}, 16 | journal={Journal of Privacy and Confidentiality}, 17 | volume={4}, 18 | number={2}, 19 | pages={43--59}, 20 | year={2012} 21 | } 22 | 23 | @inproceedings{dwork2006calibrating, 24 | title={Calibrating noise to sensitivity in private data analysis}, 25 | author={Dwork, Cynthia and McSherry, Frank and Nissim, Kobbi and Smith, Adam}, 26 | booktitle={Theory of Cryptography Conference}, 27 | pages={265--284}, 28 | year={2006}, 29 | organization={Springer} 30 | } 31 | 32 | @inproceedings{mcsherry2007mechanism, 33 | title={Mechanism design via differential privacy}, 34 | author={McSherry, Frank and Talwar, Kunal}, 35 | booktitle={48th Annual IEEE Symposium on Foundations of Computer Science}, 36 | pages={94--103}, 37 | year={2007}, 38 | organization={IEEE} 39 | } 40 | 41 | @article{dwork2014algorithmic, 42 | title={The Algorithmic Foundations of Differential Privacy}, 43 | author={Dwork, Cynthia and Roth, Aaron}, 44 | journal={Foundations and Trends in Theoretical Computer Science}, 45 | volume={9}, 46 | number={3--4}, 47 | pages={211--407}, 48 | year={2014}, 49 | publisher={Now Publishers, Inc.} 50 | } 51 | 52 | @inproceedings{alda2017bernstein, 53 | title={The {B}ernstein mechanism: Function release under differential privacy}, 54 | author={Ald{\`a}, Francesco and Rubinstein, Benjamin I. P.}, 55 | year = {2017}, 56 | booktitle = {Proceedings of the 31st AAAI Conference on Artificial Intelligence}, 57 | pages = {1705--1711} 58 | } 59 | 60 | @article{rubinstein2012svm, 61 | title={Learning in a Large Function Space: Privacy-Preserving Mechanisms for {SVM} Learning}, 62 | author={Rubinstein, Benjamin I. P. and Bartlett, Peter L. and Huang, Ling and Taft, Nina}, 63 | journal={Journal of Privacy and Confidentiality}, 64 | volume={4}, 65 | number={1}, 66 | pages={65--100}, 67 | year={2012} 68 | } 69 | 70 | @inproceedings{chaudhuri2009logistic, 71 | title={Privacy-preserving logistic regression}, 72 | author={Chaudhuri, Kamalika and Monteleoni, Claire}, 73 | booktitle={Advances in Neural Information Processing Systems}, 74 | pages={289--296}, 75 | year={2009} 76 | } 77 | 78 | @article{chaudhuri2011erm, 79 | title={Differentially private empirical risk minimization}, 80 | author={Chaudhuri, Kamalika and Monteleoni, Claire and Sarwate, Anand D}, 81 | journal={Journal of Machine Learning Research}, 82 | volume={12}, 83 | number={Mar}, 84 | pages={1069--1109}, 85 | year={2011} 86 | } 87 | --------------------------------------------------------------------------------