连续性数据可以通过拉普拉斯机制计算差分隐私,只需直接在回复的数值结果上增加噪声即可。如果我们想返回一个准确结果(即不能直接在结果上增加噪声),同时还要保证回复过程满足差分隐私,该怎么办呢?一种解决方法是使用指数机制(Exponential Mechanism)
指数机制 的实现方式是将每个可能的输出结果与真实结果之间的差异量作为指数分布的参数,然后以指数分布的概率密度函数为概率分布,随机生成一个输出结果。这样,与真实结果差异较小的输出结果被选中的概率更大,从而保证了输出结果的准确性。
- 有一个集合 R
- 指定一个全局敏感度为Δu 的评分函数u(x,r)(Δu =1 表示增加或者删除一个时,噪声最大的变化是1)
- 当 ∈R 时,输出的概率与下述表达式成正比:
在足球协会的一次在线选举投票中,共收到100张投票。根据实际得票情况,张三获得了50票,李四获得了35票,王五获得了15票。然而,在这个场景中,隐私保护至关重要,因此不能透露具体的票数分配给每位候选人。
投票记录中只包含候选人的名称,而没有具体的数值。因此,我们将通过添加一些干扰来表达每位候选人胜出的概率,而不是提供他们的实际得票数.
套用到指数机制上,对应的代码如下所示:
# -*- coding: utf-8 -*- #指定字符集
import numpy as np
# 指数机制生成噪声数据
def calc_proportion(epsilon, value, delta):
return np.exp(epsilon*value/(2*delta))
def exponential(vote_count,epsilon,delta):
# 计算每个分数的输出概率
probabilities = [calc_proportion(epsilon, vote_count[i], delta) for i in range(len(candidate))]
# 对概率进行归一化处理,使概率和等于1
return probabilities / np.linalg.norm(probabilities, ord=1)
if __name__ =='__main__':
candidate = ['zhangsan', 'lisi', 'wangwu']
vote_count = [50, 35, 15]
epsilon = 0.1 # ε
delta = 1 # 敏感度
probabilities = exponential(vote_count,epsilon,delta)
print(probabilities)
# 根据概率分布选择回复结果
print(np.random.choice(candidate, 1, p=probabilities)[0])
执行之后的结果如下所示:
张三以 60.74% 的概率胜出
当张三的得票为 49,李四得票为 36 时,结果如下所示:
张三以 58.66% 的概率胜出
exp(-0.1) < (60.75%/59.55%) < exp(0.1)
当 ε= 0 时,结果如下所示:
输出的内容基础都差不多,但是数据没法使用
当 ε= 0.5 时,结果如下所示:
当 ε= 1 时,结果如下所示:
可见当ε增大时,得票最多的选项,其胜出概率被极度放大了。因此,ε的选择,需要在保障数据可用的前提下进行权衡。