def test_two_calls_compute_budgets_raise_exception(self): budget_accountant = NaiveBudgetAccountant(total_epsilon=1, total_delta=1e-6) budget_accountant.request_budget(mechanism_type=MechanismType.LAPLACE) budget_accountant.compute_budgets() with self.assertRaises(Exception): # Budget can be computed only once. budget_accountant.compute_budgets()
def test_request_after_compute_raise_exception(self): budget_accountant = NaiveBudgetAccountant(total_epsilon=1, total_delta=1e-6) budget_accountant.request_budget(mechanism_type=MechanismType.LAPLACE) budget_accountant.compute_budgets() with self.assertRaises(Exception): # Budget can not be requested after it has been already computed. budget_accountant.request_budget( mechanism_type=MechanismType.LAPLACE)
def test_compute_budgets(self): budget_accountant = NaiveBudgetAccountant(total_epsilon=1, total_delta=1e-6) budget1 = budget_accountant.request_budget(noise_kind=NoiseKind.LAPLACE) budget2 = budget_accountant.request_budget( noise_kind=NoiseKind.GAUSSIAN, weight=3) budget_accountant.compute_budgets() self.assertEqual(budget1.eps, 0.25) self.assertEqual(budget1.delta, 0) # Delta should be 0 if mechanism is Gaussian. self.assertEqual(budget2.eps, 0.75) self.assertEqual(budget2.delta, 1e-6)
def test_compute_budgets(self): budget_accountant = NaiveBudgetAccountant(total_epsilon=1, total_delta=1e-6) budget1 = budget_accountant.request_budget( mechanism_type=MechanismType.LAPLACE) budget2 = budget_accountant.request_budget( mechanism_type=MechanismType.GAUSSIAN, weight=3) budget_accountant.compute_budgets() self.assertEqual(budget1.eps, 0.25) self.assertEqual(budget1.delta, 0) # Delta should be 0 if mechanism is Laplace. self.assertEqual(budget2.eps, 0.75) self.assertEqual(budget2.delta, 1e-6)
def test_budget_scopes_no_parentscope(self): budget_accountant = NaiveBudgetAccountant(total_epsilon=1, total_delta=1e-6) # Allocated in the top-level scope with no weight specified budget1 = budget_accountant.request_budget( mechanism_type=MechanismType.LAPLACE) with budget_accountant.scope(weight=0.5): budget2 = budget_accountant.request_budget( mechanism_type=MechanismType.LAPLACE) budget_accountant.compute_budgets() self.assertEqual(budget1.eps, 1.0 / (1.0 + 0.5)) self.assertEqual(budget2.eps, 0.5 / (1.0 + 0.5))
def test_with_noise(self): budget_accountant = NaiveBudgetAccountant(total_epsilon=10, total_delta=1e-5) budget = budget_accountant.request_budget( pipeline_dp.MechanismType.GAUSSIAN) budget_accountant.compute_budgets() params = pipeline_dp.AggregateParams( min_value=0, max_value=1, max_partitions_contributed=1, max_contributions_per_partition=1, noise_kind=NoiseKind.GAUSSIAN, metrics=[pipeline_dp.Metrics.COUNT]) count_accumulator = accumulator.CountAccumulator( accumulator.CountParams(budget, params), list(range(5))) self.assertAlmostEqual(first=count_accumulator.compute_metrics(), second=5, delta=4) count_accumulator.add_value(50) self.assertAlmostEqual(first=count_accumulator.compute_metrics(), second=6, delta=4) count_accumulator.add_value(list(range(49))) self.assertAlmostEqual(first=count_accumulator.compute_metrics(), second=7, delta=4) count_accumulator.add_value('*' * 100) self.assertAlmostEqual(first=count_accumulator.compute_metrics(), second=8, delta=4)
def test_without_noise(self): budget_accountant = NaiveBudgetAccountant(total_epsilon=1000000, total_delta=0.9999999) budget = budget_accountant.request_budget( pipeline_dp.MechanismType.GAUSSIAN) budget_accountant.compute_budgets() no_noise = pipeline_dp.AggregateParams( min_value=0, max_value=1, max_partitions_contributed=1, max_contributions_per_partition=1, noise_kind=NoiseKind.GAUSSIAN, metrics=[pipeline_dp.Metrics.COUNT]) count_accumulator = accumulator.CountAccumulator( accumulator.CountParams(budget, no_noise), list(range(5))) self.assertEqual(count_accumulator.compute_metrics(), 5) count_accumulator = accumulator.CountAccumulator( accumulator.CountParams(budget, no_noise), 'a' * 50) self.assertEqual(count_accumulator.compute_metrics(), 50) count_accumulator = accumulator.CountAccumulator( accumulator.CountParams(budget, no_noise), list(range(50))) count_accumulator.add_value(49) self.assertEqual(count_accumulator.compute_metrics(), 51) count_accumulator_1 = accumulator.CountAccumulator( accumulator.CountParams(budget, no_noise), list(range(50))) count_accumulator_2 = accumulator.CountAccumulator( accumulator.CountParams(budget, no_noise), 'a' * 50) count_accumulator_1.add_accumulator(count_accumulator_2) self.assertEqual(count_accumulator_1.compute_metrics(), 100)
def test_request_budget(self): budget_accountant = NaiveBudgetAccountant(total_epsilon=1, total_delta=0) budget = budget_accountant.request_budget(noise_kind=NoiseKind.LAPLACE) self.assertTrue(budget) # An object must be returned. with self.assertRaises(AssertionError): print(budget.eps) # The privacy budget is not calculated yet. with self.assertRaises(AssertionError): print(budget.delta) # The privacy budget is not calculated yet.
def test_budget_scopes(self): budget_accountant = NaiveBudgetAccountant(total_epsilon=1, total_delta=1e-6) with budget_accountant.scope(weight=0.4): budget1 = budget_accountant.request_budget( mechanism_type=MechanismType.LAPLACE) budget2 = budget_accountant.request_budget( mechanism_type=MechanismType.LAPLACE, weight=3) with budget_accountant.scope(weight=0.6): budget3 = budget_accountant.request_budget( mechanism_type=MechanismType.LAPLACE) budget4 = budget_accountant.request_budget( mechanism_type=MechanismType.LAPLACE, weight=4) budget_accountant.compute_budgets() self.assertEqual(budget1.eps, 0.4 * (1 / 4)) self.assertEqual(budget2.eps, 0.4 * (3 / 4)) self.assertEqual(budget3.eps, 0.6 * (1 / 5)) self.assertEqual(budget4.eps, 0.6 * (4 / 5))