Exemplo n.º 1
0
    def total(self, spent_budget=None, slack=None):
        """Returns the total current privacy spend.

        `spent_budget` and `slack` can be specified as parameters, otherwise the class values will be used.

        Parameters
        ----------
        spent_budget : list of tuples of the form (epsilon, delta), optional
            List of tuples of budget spends.  If not provided, the accountant's spends will be used.

        slack : float, optional
            Slack in delta for composition.  If not provided, the accountant's slack will be used.

        Returns
        -------
        epsilon : float
            Total epsilon spend.

        delta : float
            Total delta spend.

        """
        if spent_budget is None:
            spent_budget = self.spent_budget
        else:
            for epsilon, delta in spent_budget:
                check_epsilon_delta(epsilon, delta)

        if slack is None:
            slack = self.slack
        elif not 0 <= slack <= self.delta:
            raise ValueError(
                "Slack must be between 0 and delta ({}), inclusive. Got {}.".
                format(self.delta, slack))

        epsilon_sum, epsilon_exp_sum, epsilon_sq_sum = 0, 0, 0

        for epsilon, _ in spent_budget:
            epsilon_sum += epsilon
            epsilon_exp_sum += (1 - np.exp(-epsilon)) * epsilon / (
                1 + np.exp(-epsilon))
            epsilon_sq_sum += epsilon**2

        total_epsilon_naive = epsilon_sum
        total_delta = self.__total_delta_safe(spent_budget, slack)

        if slack == 0:
            return Budget(total_epsilon_naive, total_delta)

        total_epsilon_drv = epsilon_exp_sum + np.sqrt(
            2 * epsilon_sq_sum * np.log(1 / slack))
        total_epsilon_kov = epsilon_exp_sum + np.sqrt(
            2 * epsilon_sq_sum *
            np.log(np.exp(1) + np.sqrt(epsilon_sq_sum) / slack))

        return Budget(
            min(total_epsilon_naive, total_epsilon_drv, total_epsilon_kov),
            total_delta)
Exemplo n.º 2
0
    def __init__(self,
                 epsilon=float("inf"),
                 delta=1.0,
                 slack=0.0,
                 spent_budget=None):
        check_epsilon_delta(epsilon, delta)
        self.__epsilon = epsilon
        self.__min_epsilon = 0 if epsilon == float("inf") else epsilon * 1e-14
        self.__delta = delta
        self.__spent_budget = []
        self.slack = slack

        if spent_budget is not None:
            if not isinstance(spent_budget, list):
                raise TypeError("spent_budget must be a list")

            for _epsilon, _delta in spent_budget:
                self.spend(_epsilon, _delta)
Exemplo n.º 3
0
    def test_real_inputs(self):
        with self.assertRaises(TypeError):
            check_epsilon_delta("1", "0")

        with self.assertRaises(TypeError):
            check_epsilon_delta(complex(1, 0.5), 0)

        with self.assertRaises(TypeError):
            check_epsilon_delta([1], [0])

        self.assertIsNone(check_epsilon_delta(1, 0))
        self.assertIsNone(check_epsilon_delta(1.0, 0.0))
Exemplo n.º 4
0
    def check(self, epsilon, delta):
        """Checks if the provided (epsilon,delta) can be spent without exceeding the accountant's budget ceiling.

        Parameters
        ----------
        epsilon : float
            Epsilon budget spend to check.

        delta : float
            Delta budget spend to check.

        Returns
        -------
        bool
            True if the budget can be spent, otherwise a :class:`.BudgetError` is raised.

        Raises
        ------
        BudgetError
            If the specified budget spend will result in the budget ceiling being exceeded.

        """
        check_epsilon_delta(epsilon, delta)
        if self.epsilon == float("inf") and self.delta == 1:
            return True

        if 0 < epsilon < self.__min_epsilon:
            raise ValueError(
                "Epsilon must be at least {} if non-zero, got {}.".format(
                    self.__min_epsilon, epsilon))

        spent_budget = self.spent_budget + [(epsilon, delta)]

        if Budget(self.epsilon,
                  self.delta) >= self.total(spent_budget=spent_budget):
            return True

        raise BudgetError(
            "Privacy spend of ({},{}) not permissible; will exceed remaining privacy budget. "
            "Use {}.{}() to check remaining budget.".format(
                epsilon, delta, self.__class__.__name__,
                self.remaining.__name__))
 def __new__(cls, epsilon, delta):
     check_epsilon_delta(epsilon, delta, allow_zero=True)
     return tuple.__new__(cls, (epsilon, delta))
Exemplo n.º 6
0
    def __new__(cls, epsilon, delta):
        from diffprivlib.validation import check_epsilon_delta

        check_epsilon_delta(epsilon, delta, allow_zero=True)
        return tuple.__new__(cls, (epsilon, delta))
Exemplo n.º 7
0
 def test_max_eps_delt(self):
     self.assertIsNone(check_epsilon_delta(float("inf"), 1))
Exemplo n.º 8
0
    def test_wrong_delta(self):
        with self.assertRaises(ValueError):
            check_epsilon_delta(0, -1)

        with self.assertRaises(ValueError):
            check_epsilon_delta(0, 1.1)
Exemplo n.º 9
0
    def test_neg_eps(self):
        with self.assertRaises(ValueError):
            check_epsilon_delta(-1, 0)

        with self.assertRaises(ValueError):
            check_epsilon_delta(-1e-100, 0)
Exemplo n.º 10
0
    def test_all_zero(self):
        with self.assertRaises(ValueError):
            check_epsilon_delta(0, 0)

        with self.assertRaises(ValueError):
            check_epsilon_delta(0.0, 0.0)