def scalar_noise_params(self): return dp_computations.ScalarNoiseParams( self.eps, self.delta, self.aggregate_params.min_value, self.aggregate_params.max_value, self.aggregate_params.min_sum_per_partition, self.aggregate_params.max_sum_per_partition, self.aggregate_params.max_partitions_contributed, self.aggregate_params.max_contributions_per_partition, self.aggregate_params.noise_kind)
def test_l0_sensitivity(self): params = dp_computations.ScalarNoiseParams( eps=1, delta=1e-10, min_value=2, max_value=3, min_sum_per_partition=None, max_sum_per_partition=None, max_partitions_contributed=4, max_contributions_per_partition=5, noise_kind=NoiseKind.LAPLACE) self.assertEqual(params.l0_sensitivity(), 4)
def test_compute_dp_sum(self, bound_per_partition): min_value = max_value = min_sum_per_partition = max_sum_per_partition = None if bound_per_partition: min_sum_per_partition, max_sum_per_partition = 2, 3 else: min_value, max_value = 2, 3 params = dp_computations.ScalarNoiseParams( eps=0.5, delta=1e-10, min_value=min_value, max_value=max_value, min_sum_per_partition=min_sum_per_partition, max_sum_per_partition=max_sum_per_partition, max_partitions_contributed=1, max_contributions_per_partition=1, noise_kind=NoiseKind.LAPLACE) l0_sensitivity = params.l0_sensitivity() if bound_per_partition: linf_sensitivity = params.max_contributions_per_partition * max( params.min_sum_per_partition, params.max_sum_per_partition) else: # bound per contribution linf_sensitivity = params.max_contributions_per_partition * max( params.min_value, params.max_value) # Laplace Mechanism l1_sensitivity = dp_computations.compute_l1_sensitivity( l0_sensitivity, linf_sensitivity) results = [ dp_computations.compute_dp_sum(sum=10, dp_params=params) for _ in range(N_ITERATIONS) ] self._test_laplace_noise(results=results, num_trials=N_ITERATIONS, expected_mean=10, eps=params.eps, l1_sensitivity=l1_sensitivity) # Gaussian Mechanism params.noise_kind = NoiseKind.GAUSSIAN l2_sensitivity = dp_computations.compute_l2_sensitivity( l0_sensitivity, linf_sensitivity) results = [ dp_computations.compute_dp_sum(sum=10, dp_params=params) for _ in range(N_ITERATIONS) ] self._test_gaussian_noise(results=results, expected_mean=10, num_trials=N_ITERATIONS, eps=params.eps, delta=params.delta, l2_sensitivity=l2_sensitivity)
def test_compute_dp_sum_min_max_zero(self): params = dp_computations.ScalarNoiseParams( eps=0.5, delta=1e-10, min_value=0, max_value=0, min_sum_per_partition=None, max_sum_per_partition=None, max_partitions_contributed=1, max_contributions_per_partition=1, noise_kind=NoiseKind.LAPLACE) self.assertEqual(0, dp_computations.compute_dp_sum(10, params))
def test_compute_dp_count_noise_std_gaussian( self, eps: float, delta: float, max_partitions_contributed: int, max_contributions_per_partition: int, expected_std: float): params = dp_computations.ScalarNoiseParams( eps=eps, delta=delta, min_value=0, max_value=0, min_sum_per_partition=None, max_sum_per_partition=None, max_partitions_contributed=max_partitions_contributed, max_contributions_per_partition=max_contributions_per_partition, noise_kind=pipeline_dp.NoiseKind.GAUSSIAN) scale = dp_computations.compute_dp_count_noise_std(params) self.assertAlmostEqual(scale, expected_std)
def test_compute_dp_mean_equal_min_max(self): params = dp_computations.ScalarNoiseParams( eps=0.5, delta=1e-10, min_value=42.0, max_value=42.0, # = min_value min_sum_per_partition=None, max_sum_per_partition=None, max_partitions_contributed=1, max_contributions_per_partition=1, noise_kind=NoiseKind.LAPLACE) count, sum, mean = dp_computations.compute_dp_mean(count=10, normalized_sum=400, dp_params=params) self.assertEqual(mean, 42.0)
def test_compute_dp_count_noise_std_laplace( self, eps: float, max_partitions_contributed: int, max_contributions_per_partition: int): params = dp_computations.ScalarNoiseParams( eps=eps, delta=0, max_partitions_contributed=max_partitions_contributed, max_contributions_per_partition=max_contributions_per_partition, noise_kind=pipeline_dp.NoiseKind.LAPLACE, min_value=0, max_value=0, min_sum_per_partition=None, max_sum_per_partition=None) expected_std = max_partitions_contributed * max_contributions_per_partition / eps * np.sqrt( 2) scale = dp_computations.compute_dp_count_noise_std(params) self.assertAlmostEqual(scale, expected_std, delta=1e-10)
def test_compute_dp_count(self): params = dp_computations.ScalarNoiseParams( eps=0.5, delta=1e-10, min_value=0, max_value=0, min_sum_per_partition=None, max_sum_per_partition=None, max_partitions_contributed=1, max_contributions_per_partition=1, noise_kind=NoiseKind.LAPLACE) l0_sensitivity = params.l0_sensitivity() linf_sensitivity = params.max_contributions_per_partition # Laplace Mechanism l1_sensitivity = dp_computations.compute_l1_sensitivity( l0_sensitivity, linf_sensitivity) results = [ dp_computations.compute_dp_count(count=10, dp_params=params) for _ in range(N_ITERATIONS) ] self._test_laplace_noise(results=results, num_trials=N_ITERATIONS, expected_mean=10, eps=params.eps, l1_sensitivity=l1_sensitivity) # Gaussian Mechanism params.noise_kind = NoiseKind.GAUSSIAN l2_sensitivity = dp_computations.compute_l2_sensitivity( l0_sensitivity, linf_sensitivity) results = [ dp_computations.compute_dp_count(count=10, dp_params=params) for _ in range(N_ITERATIONS) ] self._test_gaussian_noise(results=results, num_trials=N_ITERATIONS, expected_mean=10, eps=params.eps, delta=params.delta, l2_sensitivity=l2_sensitivity)
def test_compute_dp_var(self): params = dp_computations.ScalarNoiseParams( eps=10, delta=1e-10, min_value=1, max_value=20, min_sum_per_partition=None, max_sum_per_partition=None, max_partitions_contributed=1, max_contributions_per_partition=1, noise_kind=NoiseKind.LAPLACE) (count_eps, count_delta), (_, _), (_, _) = dp_computations.equally_split_budget( params.eps, params.delta, 3) l0_sensitivity = params.l0_sensitivity() count_linf_sensitivity = params.max_contributions_per_partition expected_count = 100000 expected_sum = 1000000 expected_mean = 10 expected_var = 100 normalized_sum = -50000 normalized_sum_squares = 10025000 # sum of squares = 20000000 # Laplace Mechanism results = [ dp_computations.compute_dp_var( count=expected_count, normalized_sum=normalized_sum, normalized_sum_squares=normalized_sum_squares, dp_params=params) for _ in range(N_ITERATIONS) ] count_values, sum_values, mean_values, var_values = zip(*results) self._test_laplace_noise( results=count_values, num_trials=N_ITERATIONS, expected_mean=100000, eps=count_eps, l1_sensitivity=dp_computations.compute_l1_sensitivity( l0_sensitivity, count_linf_sensitivity)) self.assertAlmostEqual(np.mean(sum_values), expected_sum, delta=1) self.assertAlmostEqual(np.mean(mean_values), expected_mean, delta=0.00003) self.assertAlmostEqual(np.mean(var_values), expected_var, delta=0.1) # Gaussian Mechanism params.noise_kind = NoiseKind.GAUSSIAN results = [ dp_computations.compute_dp_var( count=expected_count, normalized_sum=normalized_sum, normalized_sum_squares=normalized_sum_squares, dp_params=params) for _ in range(N_ITERATIONS) ] count_values, sum_values, mean_values, var_values = zip(*results) self._test_gaussian_noise( results=count_values, num_trials=N_ITERATIONS, expected_mean=100000, eps=count_eps, delta=count_delta, l2_sensitivity=dp_computations.compute_l2_sensitivity( l0_sensitivity, count_linf_sensitivity)) self.assertAlmostEqual(np.mean(sum_values), expected_sum, delta=5) self.assertAlmostEqual(np.mean(mean_values), expected_mean, delta=0.0002) self.assertAlmostEqual(np.mean(var_values), expected_var, delta=0.5)