예제 #1
0
    def test_get_epsilon_S_exceptions(self):
        """ Tests that get_epsilon_S raises errors when encountering instabilities."""
        nc = 10
        ks = 10 * np.ones(
            nc, dtype=np.int32
        )  #number of compositions for each value of (q,sigma)

        with self.assertRaises(ValueError):
            get_epsilon_S(sigma=np.linspace(0.0005, 0.0015, nc),
                          q=np.linspace(0.15, 0.25, nc),
                          ncomp=ks,
                          target_delta=1e-4,
                          nx=1E6,
                          L=40.0)
예제 #2
0
파일: dputil.py 프로젝트: DPBayes/d3p
def approximate_sigma(target_eps: float,
                      delta: float,
                      q: float,
                      num_iter: int,
                      tol: Optional[float] = 1e-4,
                      force_smaller: Optional[bool] = False,
                      maxeval: Optional[int] = 10) -> Tuple[float, float, int]:
    """ Approximates the sigma corresponding to a target privacy epsilon using
    the Fourier Accountant for the substitute relation.

    Uses a bracketing approach where an initial rough estimate of lower and upper
    bounds for sigma is iteratively shrunk. Each iteration fits a logarithmic
    function eps,precision->sigma to the bounds which is evaluated at target_eps
    to get the next estimate for sigma, which is in turn used to update the bounds.

    :param compute_eps_fn: Privacy accountant function returning epsilon for
        a given sigma and precision scale; assumed to be monotonic decreasing in sigma.
    :param target_eps: The desired target epsilon.
    :param delta: The delta privacy parameter.
    :param q: The subsampling ratio.
    :param num_iter: The number of batch iterations.
    :param tol: Absolute tolerance for the epsilon corresponding to the returned
        value for sigma, i.e., `abs(compute_eps_fn(sigma_opt) - target_eps) < tol`
    :param force_smaller: Require that the returned value for sigma results
        in an epsilon that is strictly smaller than `target_eps`. This may
        slightly violate `tol`.
    :param maxeval: Maximum number of evaluations of `compute_eps_fn`. The
        function aborts the search for sigma after `maxeval` function evaluations
        were made and returns the current best estimate. In that case, `tol`
        is violated but `force_smaller` is still adhered to.
    :return: Tuple consisting of
        1) the determined value for sigma
        2) the corresponding espilon
        3) the number of function evaluations made
    """
    L = max(20, target_eps * 2)
    compute_eps = lambda sigma, precision=1: get_epsilon_S(
        delta,
        sigma,
        q,
        ncomp=num_iter,
        L=L * precision,
        nx=1e6 * (L * precision) / 20)

    return _approximate_sigma(compute_eps, target_eps, q, tol, force_smaller,
                              maxeval)
예제 #3
0
 def test_get_epsilon_S_invalid_sizes(self):
     with self.assertRaises(ValueError):
         get_epsilon_S(sigma=np.ones(2),
                       q=np.ones(2),
                       ncomp=np.ones(1, dtype=np.int32))
     with self.assertRaises(ValueError):
         get_epsilon_S(sigma=np.ones(2),
                       q=np.ones(1),
                       ncomp=np.ones(2, dtype=np.int32))
     with self.assertRaises(ValueError):
         get_epsilon_S(sigma=np.ones(1),
                       q=np.ones(2),
                       ncomp=np.ones(2, dtype=np.int32))
예제 #4
0
    def test_get_epsilon_S_regression_valid_params(self):
        """ Tests that results of get_epsilon_S did not drift from last version."""
        nc = 10
        sigmas = np.linspace(1.6, 1.8, nc)
        q_values = np.linspace(0.05, 0.06, nc)
        ks = 10 * np.ones(
            nc, dtype=np.int32
        )  #number of compositions for each value of (q,sigma)

        test_data = [
            (dict(sigma=sigmas,
                  q=q_values,
                  ncomp=ks,
                  target_delta=1e-3,
                  nx=1E6,
                  L=20.0), 1.849343750228688),
            (dict(sigma=sigmas,
                  q=q_values,
                  ncomp=ks,
                  target_delta=1e-3,
                  nx=1E6,
                  L=40.0), 1.8493437498330085),
            (dict(sigma=sigmas,
                  q=q_values,
                  ncomp=ks,
                  target_delta=1e-3,
                  nx=1E5,
                  L=20.0), 1.8493437767177145),
            (dict(sigma=sigmas[:-1],
                  q=q_values[:-1],
                  ncomp=ks[:-1],
                  target_delta=1e-4,
                  nx=1E6,
                  L=20.0), 2.157488007444617),
        ]

        for params, expected in test_data:
            actual = get_epsilon_S(**params)
            self.assertAlmostEqual(expected, actual)
예제 #5
0
# Examples for computing epsilon as a function of delta

delta = 1e-7

#Compute epsilon in remove/add relation
e1 = compute_eps.get_epsilon_R(q=q,
                               sigma=sigma,
                               target_delta=delta,
                               L=L,
                               nx=nx,
                               ncomp=nc)

#Compute epsilon in substitute relation
e2 = compute_eps.get_epsilon_S(q=q,
                               sigma=sigma,
                               target_delta=delta,
                               L=L,
                               nx=nx,
                               ncomp=nc)

# Examples for varying sigma and q

L = 20
nx = 2E6
nc = 10
sigmas = np.linspace(1.6, 1.8, nc)
q_values = np.linspace(0.05, 0.06, nc)
k = 10 * np.ones(nc)  #number of compositions for each value of (q,sigma)

eps = 1.5

d1 = compute_delta_var.get_delta_R(q_t=q_values,