Exemplo n.º 1
0
    def test_get_epsilon_R_exceptions(self):
        """ Tests that get_epsilon_R 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_R(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)
Exemplo n.º 2
0
def approximate_sigma_remove_relation(
        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 add/remove 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->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, assumed to be monotonic decreasing.
    :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_R(
        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)
Exemplo n.º 3
0
    def test_get_epsilon_R_regression_valid_params(self):
        """ Tests that results of get_epsilon_R 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), 0.9658229984720059),
            (dict(sigma=sigmas,
                  q=q_values,
                  ncomp=ks,
                  target_delta=1e-3,
                  nx=1E6,
                  L=40.0), 0.9658230049986837),
            (dict(sigma=sigmas,
                  q=q_values,
                  ncomp=ks,
                  target_delta=1e-3,
                  nx=1E5,
                  L=20.0), 0.9658230533746907),
            (dict(sigma=sigmas,
                  q=q_values,
                  ncomp=ks,
                  target_delta=1e-4,
                  nx=1E6,
                  L=20.0), 1.2658081375076573),
            (dict(sigma=sigmas[:-1],
                  q=q_values[:-1],
                  ncomp=ks[:-1],
                  target_delta=1e-3,
                  nx=1E6,
                  L=20.0), 0.9092052395489234),
        ]

        for params, expected in test_data:
            actual = get_epsilon_R(**params)
            self.assertAlmostEqual(expected, actual)
Exemplo n.º 4
0
 def test_get_epsilon_R_invalid_sizes(self):
     with self.assertRaises(ValueError):
         get_epsilon_R(sigma=np.ones(2),
                       q=np.ones(2),
                       ncomp=np.ones(1, dtype=np.int32))
     with self.assertRaises(ValueError):
         get_epsilon_R(sigma=np.ones(2),
                       q=np.ones(1),
                       ncomp=np.ones(2, dtype=np.int32))
     with self.assertRaises(ValueError):
         get_epsilon_R(sigma=np.ones(1),
                       q=np.ones(2),
                       ncomp=np.ones(2, dtype=np.int32))
Exemplo n.º 5
0
#Compute delta in substitute relation
d2 = compute_delta.get_delta_S(q=q,
                               sigma=sigma,
                               target_eps=eps,
                               L=L,
                               nx=nx,
                               ncomp=nc)

# 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
Exemplo n.º 6
0
    def get_epsilon(self, target_delta, q, num_epochs=None, num_iter=None):
        num_iter = self._validate_epochs_and_iter(num_epochs, num_iter, q)

        eps = get_epsilon_R(target_delta, self._dp_scale, q, ncomp=num_iter)
        return eps