-
Notifications
You must be signed in to change notification settings - Fork 18
/
privacy_risk_score_utils.py
99 lines (84 loc) · 4.92 KB
/
privacy_risk_score_utils.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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import numpy as np
import matplotlib.pyplot as plt
def distrs_compute(tr_values, te_values, tr_labels, te_labels, num_bins=5, log_bins=True, plot_name=None):
### function to compute and plot the normalized histogram for both training and test values class by class.
### we recommand using the log scale to plot the distribution to get better-behaved distributions.
num_classes = len(set(tr_labels))
sqr_num = np.ceil(np.sqrt(num_classes))
tr_distrs, te_distrs, all_bins = [], [], []
plt.figure(figsize = (15,15))
plt.rc('font', family='serif', size=10)
plt.rc('axes', linewidth=2)
for i in range(num_classes):
tr_list, te_list = tr_values[tr_labels==i], te_values[te_labels==i]
if log_bins:
# when using log scale, avoid very small number close to 0
small_delta = 1e-10
tr_list[tr_list<=small_delta] = small_delta
te_list[te_list<=small_delta] = small_delta
n1, n2 = np.sum(tr_labels==i), np.sum(te_labels==i)
all_list = np.concatenate((tr_list, te_list))
max_v, min_v = np.amax(all_list), np.amin(all_list)
plt.subplot(sqr_num, sqr_num, i+1)
if log_bins:
bins = np.logspace(np.log10(min_v), np.log10(max_v),num_bins+1)
weights = np.ones_like(tr_list)/float(len(tr_list))
h1, _,_ = plt.hist(tr_list,bins=bins,facecolor='b',weights=weights,alpha = 0.5)
plt.gca().set_xscale("log")
weights = np.ones_like(te_list)/float(len(te_list))
h2, _, _ = plt.hist(te_list,bins=bins,facecolor='r',weights=weights,alpha = 0.5)
plt.gca().set_xscale("log")
else:
bins = np.linspace(min_v, max_v,num_bins+1)
weights = np.ones_like(tr_list)/float(len(tr_list))
h1, _,_ = plt.hist(tr_list,bins=bins,facecolor='b',weights=weights,alpha = 0.5)
weights = np.ones_like(te_list)/float(len(te_list))
h2, _, _ = plt.hist(te_list,bins=bins,facecolor='r',weights=weights,alpha = 0.5)
tr_distrs.append(h1)
te_distrs.append(h2)
all_bins.append(bins)
if plot_name == None:
plot_name='./tmp'
plt.savefig(plot_name+'.png', bbox_inches='tight')
tr_distrs, te_distrs, all_bins = np.array(tr_distrs), np.array(te_distrs), np.array(all_bins)
return tr_distrs, te_distrs, all_bins
def risk_score_compute(tr_distrs, te_distrs, all_bins, data_values, data_labels):
### Given training and test distributions (obtained from the shadow classifier),
### compute the corresponding privacy risk score for training points (of the target classifier).
def find_index(bins, value):
# for given n bins (n+1 list) and one value, return which bin includes the value
if value>=bins[-1]:
return len(bins)-2 # when value is larger than any bins, we assign the last bin
if value<=bins[0]:
return 0 # when value is smaller than any bins, we assign the first bin
return np.argwhere(bins<=value)[-1][0]
def score_calculate(tr_distr, te_distr, ind):
if tr_distr[ind]+te_distr[ind] != 0:
return tr_distr[ind]/(tr_distr[ind]+te_distr[ind])
else: # when both distributions have 0 probabilities, we find the nearest bin with non-zero probability
for t_n in range(1, len(tr_distr)):
t_ind = ind-t_n
if t_ind>=0:
if tr_distr[t_ind]+te_distr[t_ind] != 0:
return tr_distr[t_ind]/(tr_distr[t_ind]+te_distr[t_ind])
t_ind = ind+t_n
if t_ind<len(tr_distr):
if tr_distr[t_ind]+te_distr[t_ind] != 0:
return tr_distr[t_ind]/(tr_distr[t_ind]+te_distr[t_ind])
risk_score = []
for i in range(len(data_values)):
c_value, c_label = data_values[i], data_labels[i]
c_tr_distr, c_te_distr, c_bins = tr_distrs[c_label], te_distrs[c_label], all_bins[c_label]
c_index = find_index(c_bins, c_value)
c_score = score_calculate(c_tr_distr, c_te_distr, c_index)
risk_score.append(c_score)
return np.array(risk_score)
def calculate_risk_score(tr_values, te_values, tr_labels, te_labels, data_values, data_labels,
num_bins=5, log_bins=True):
########### tr_values, te_values, tr_labels, te_labels are from shadow classifier's training and test data
########### data_values, data_labels are from target classifier's training data
########### potential choice for the value -- entropy, or modified entropy, or prediction loss (i.e., -np.log(confidence))
tr_distrs, te_distrs, all_bins = distrs_compute(tr_values, te_values, tr_labels, te_labels,
num_bins=num_bins, log_bins=log_bins)
risk_score = risk_score_compute(tr_distrs, te_distrs, all_bins, data_values, data_labels)
return risk_score