-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprint_leaf_epsilons.py
38 lines (28 loc) · 1.34 KB
/
print_leaf_epsilons.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import numpy as np
from scipy.optimize import minimize_scalar
from privatree.privatree import _worst_expected_error_pf
def _worst_expected_error_em(n_classes):
def neg_f(p):
# This is the negative of the expression that describes the worst-case
# expected error of permute-and-flip for n candidates.
# Here delta=1 because adding 1 item to the database increases
# sample counts by 1.
return -2 * np.log(1 / p) * (1 - (1 / (1 + (n_classes - 1) * p)))
# we take the negative because we want to maximize
return -minimize_scalar(neg_f, bounds=(0, 1)).fun
max_depth = 4
n_classes = 2
print("Permute-and-flip")
for n_samples in [1_000, 10_000, 100_000]:
for leaf_label_success_prob in [0.9, 0.95, 0.99]:
required_leaf_epsilon = (
_worst_expected_error_pf(n_classes) * (2**max_depth)
) / (n_samples * (1 - leaf_label_success_prob))
print(f"{n_samples}, {leaf_label_success_prob}: {required_leaf_epsilon:.3f}")
print("Exponential mechanism")
for n_samples in [1_000, 10_000, 100_000]:
for leaf_label_success_prob in [0.9, 0.95, 0.99]:
required_leaf_epsilon = (
_worst_expected_error_em(n_classes) * (2**max_depth)
) / (n_samples * (1 - leaf_label_success_prob))
print(f"{n_samples}, {leaf_label_success_prob}: {required_leaf_epsilon:.3f}")