差分隐私项目实践——统计数据隐私保护

0. 差分隐私简介

随着GDPR法规的实施,各大公司为了避免罚款,开始重视用户个人隐私的保护。差分隐私是近年新兴的一个研究领域,主要研究如何使用数学方法保护数据中的用户个人隐私。

简单而言,差分隐私主要通过给数据增加随机噪音来污染数据,来达到保护隐私的作用。但噪音的多少至关重要,如果噪音太少不足以达到隐私保护的目的,如果噪音太多就会掩盖有价值信息。而具体往数据中增加多少噪音,就是差分隐私需要讨论的问题

1. 问题背景

我们假设一个企业想要发布自己用户的统计信息,例如:T宝计划发布用户每个城市的用户每年平均消费金额,作为某个活动的宣传文案。直观来看,公布城市的统计数据(比如平均值)并不会泄漏任何人的隐私。但在最坏的可能下,少数人的数据会因此而暴露。

具体情景如下:
假设X城市总人数为100人,T宝公布的该城市2018年人均消费金额是1万元,2019年人均消费金额暴增到2万元。
同时你从其他信息渠道得知,某知名富二代Y在2019年搬入X城市。X城市现在的人口是101人。

那么根据平均值的定义,我们可以推算出,客户Y的年消费金额是 2万*101-1万*100=102万

虽然该公司只是公布了X城市两年的人居消费数据,但在不经意间暴露了一位新来客户的信息。这就是差分隐私要解决的问题之一

2. ϵ-差分隐私

开始之前,需要先量化需要解决的问题。在上面的例子中,主要的问题来自于连续公布的两个统计量(1万和2万)相差太大,带来了隐私泄露。

此类问题的解决方案称为ϵ-差分隐私。ϵ-差分隐私是差分隐私的一种,它将需要解决的问题用规范的数学形式描述为:

Pr[A(D)S]Pr[A(D)S]exp(ϵ)

这个公式中,右侧的参数 ϵ 通常为大于0的正实数,是对于隐私的量化约束量。式子右侧exp(ϵ)则为一个大于1的实数。

在公式的左边,DD分别为原数据集和其相邻数据集,这里「相邻」的定义是它们仅仅相差一条数据,可以类比上文例子中2018年的100人和2019年的101人)。

A(D) 代表我们在D 这个数据集上计算的统计量,可以类比上文提到的平均值函数。

Pr[A(D)S] 代表我们在 D 这个数据集上计算的统计量刚好是S的概率。

式子左边则表达的是,在DD两个相邻数据集上计算统计量 A 所得到的结果相同(都是S)的概率的比值应该小于某个大于1的实数(即为exp(ϵ))。避免出现上面的例子里面1万和2万这种巨大的差异。

这个约束条件能够保证个体数据的差异给总体统计量带来的影响在有限范围内,确保了个体的隐私安全。

ϵ-差分隐私中,这种隐私保护的限度取决于 ϵ的取值。当ϵ的取值为0时,代表了极端的隐私保护策略,公式右侧为1,DD两个数据集上计算的统计量必须严格一致。相反,当ϵ的取值为一个非常大的数值(比如100)时,代表了极度宽松的隐私保护策略,此时公式右侧非常大,DD两个数据集上计算的统计量可以有很大的差异。

请注意,ϵ 是主观指定的一个值,一般为1左右,具体的选择方法会在最后讨论。

以上仅仅定义了我们的隐私保护目标,但没有提及如何实现这一隐私保护目标。具体的实现手段有很多,最常用的是接下来介绍的拉普拉斯机制

3. 拉普拉斯机制(The Laplace mechanism)

拉普拉斯机制,也称为噪音增加机制,通过给数据增加噪音来保护隐私。噪音的本质是一个符合拉普拉斯分布的随机数:

noise(x)=12bexp(|x|b)

这个随机噪音的随机程度(方差)取决于它的规模(scale)参数b 。使用拉普拉斯机制前需要先确定参数b的取值。

这个过程需要引入一个新的概念:敏感度(sensitivity)。

4. 敏感度

在差分隐私中,我们把两个相邻样本集(上文中的DD)的统计量的最大差异定义为敏感度(sensitivity):

Δf=maxD,Df(D)f(D)l

敏感度的具体值通过实际所使用的样本集 D 与所使用的统计函数 f()来计算得到。敏感度的计算方法有很多,最原始的方法就是使用蛮力法:尝试从样本集中去除每一个样本,计算去除前后统计函数结果差异,并计算最大的差异作为敏感度,对应的python代码如下:

import numpy as np


def sensitivity(data, agg_func):
    max_diff = 0
    for i in range(len(data)):
        max_diff = max(max_diff, abs( agg_func(data) - agg_func(data[:i] + data[(i+1):]) ))
    return max_diff

sensitivity( [1,2,3,4,5], np.mean)
# output is 0.5

当然这种蛮力法计算敏感度非常低效,我们也可以根据具体的统计函数来进行优化。例如,如果我们需要保护的统计量是平均值,那么可以其敏感度往往取决于数据集中最大和最小的元素。

此外这种计算只考虑到了移除一条数据的敏感度,增加一条新数据的敏感度同样应该考虑在内。比如原数据集是[1,2,3,4,5],我们新增一条数据 100变成[1,2,3,4,5,100],敏感度直接飙升到16.16。这里就有一个新的问题:新增数据不可控的情况下,如何合理估计敏感度?实践中可以采用的方式是约定一个数据的上下限,凡是超过上下限的数据都取边界值。(数据清洗的过程中也会使用类似的方法来清除异常值)

5. 拉普拉斯参数估计

计算得到了上一节中的敏感度Δf以后,我们可以直接使用如下公式设定拉普拉斯随机量的规模参数(scale) b

b=Δfϵ

根据以上参数,在数据集D上计算的统计量f需要加上对应的拉普拉斯噪音,如下:

A(D)=f(D)+ϵ2Δfexp(ϵ|x|Δf)

其中敏感度Δf使用上文中的方法根据具体的数据集和统计量计算;ϵ由使用者根据具体情况指定。

只要使用以上参数生成噪音,就能够保证所得到的统计量能够满足ϵ-差分隐私条件

Pr[A(D)S]Pr[A(D)S]exp(ϵ)

具体证明过程如下(太复杂可以跳过)

考虑到A(D)f(D)增加了噪音的版本,那么Pr[A(D)S]=ϵ2Δfexp(ϵ|f(D)|Δf),因此有:

Pr[A(D)S]Pr[A(D)S]=ϵ2Δfexp(ϵ|f(D)|Δf)ϵ2Δfexp(ϵ|f(D)|Δf)=exp(ϵ|f(D)|Δf)exp(ϵ|f(D)|Δf)=exp(ϵΔf(|f(D)||f(D)|))exp(ϵΔf(|f(D)f(D)|))exp(ϵΔf(Δf))=exp(ϵ)

6. 小结

总结以上内容,在实践中公布敏感数据集的统计量时,可以遵循以下步骤:

  1. 根据数据的敏感程度确定ϵ的取值,如果不知道取多少的话 1 是一个比较中间的选项。更敏感的数据可以选择小于1的值,不那么敏感的数据可以选择更大的ϵ
  2. 根据具体的数据计算数据集D的敏感度Δf=maxD,Df(D)f(D)l,其中DD仅相差一条数据
  3. 计算拉普拉斯随机数的尺度(Scale)参数b=Δfϵ
  4. 最后在公布的数据集统计量上增加对应的拉普拉斯随机数A(D)=f(D)+ϵ2Δfexp(ϵ|x|Δf)

这样就能保证所公布的数据有足够的隐私保护。

当然这套流程仅适用于数据的一次性静态发布。如果有用户反复查询同一个数据集上的统计量,每次都得到了使用不同噪音保护的结果,那么通过大量的查询依旧可以估计出无噪音的真实结果。在这种场景下则需要引入隐私预算(privacy budget)的概念来进一步保护数据隐私。

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据