μ=0, b=Δf/ε。比Gaussian更尖峰重尾,但提供纯ε-DP(不需要δ)。
差分隐私(Differential Privacy, DP)是信息论中最强的隐私保证之一:你的数据在不在数据集中,对外部观察者来说几乎无法区分。这不是模糊的承诺,而是可量化的数学不等式。
想象你有一份问卷调查结果。差分隐私要求:无论你是否参加了这次调查,最终发布的统计结果看起来几乎一样。你的参与不会显著改变结果——攻击者无法从统计输出反推你的个人数据。
这不是"匿名化"(去标识化经常被破解),不是k-匿名(容易被关联攻击),而是一个可证明的数学保证。
| 参数 | 含义 | 典型取值 | 解释 |
|---|---|---|---|
ε (epsilon) | 隐私预算 | 0.1~10 | 越小越安全。ε=1时有无你的数据,输出概率比≤e≈2.718 |
δ (delta) | 失败概率 | ≤1/n² | 允许极小概率破坏ε-保证。必须远小于1/n |
核心思路:在真实答案上加噪声。关键是加多少、怎么加。
Lap(b)是拉普拉斯分布,Δf是全局敏感度。
例子:计数查询敏感度Δf=1(加/删一个人最多改变计数1)。噪声量:Δf/ε。ε越小噪声越大。
μ=0, b=Δf/ε。比Gaussian更尖峰重尾,但提供纯ε-DP(不需要δ)。
提供(ε,δ)-DP(非纯ε-DP)。噪声更温和,适合高维输出和梯度扰动。
| 特性 | Laplace机制 | Gaussian机制 |
|---|---|---|
| 隐私保证 | 纯ε-DP | (ε,δ)-DP |
| 噪声形状 | 尖峰重尾 | 钟形 |
| 敏感度 | L1(Δ1f) | L2(Δ2f) |
| 适用场景 | 低维、纯DP | 高维、梯度扰动 |
输出是离散选项时,通过打分函数u(D,r)选择:
得分越高被选中概率越大,但按概率采样。典型应用:Apple Popular Emojis、离散优化。
只对超过阈值的查询消耗隐私预算:
# SVT伪代码
T_hat = T + Lap(2*Delta_f / epsilon_1) # 扰动阈值
for query q_i in queries:
noise_i = Lap(4*Delta_f / epsilon_2)
if q_i(D) + noise_i >= T_hat:
output "Above" + noisy_value
else:
output "BOTTOM" # 不消耗额外隐私预算
10次ε=1的查询=ε=10,几乎无隐私。
ε=0.1,k=100:基本ε=10,高级约ε≈2.2。
Abadi等人(2016)引入,用Rényi散度更精确追踪隐私损失。
# pip install dp-accounting
from dp_accounting.rdp import RdpAccountant
import dp_accounting
accountant = RdpAccountant()
for step in range(1000):
accountant.compose(
dp_accounting.GaussianDpEvent(noise_multiplier=1.0),
sampling_probability=0.01
)
eps = accountant.get_epsilon(target_delta=1e-5)
print(f"Total epsilon = {eps:.2f} at delta = 1e-5")
εtotal平均分配。简单但可能浪费。
按查询重要性分配。更高效但需预知优先级。
定期重置。非标准DP,适合实时分析。
适用:人口普查、企业内部分析
适用:Apple/Google大规模数据收集
Warner 1965:以概率p说真话,1-p说假话。当p=eε/(1+eε)时恰好是ε-LDP。
恢复:真实比例=(观察比例-(1-p))/(2p-1)
Apple 2016年iOS 10部署LDP(来源:Apple ML Research):
架构:Opt-in → 设备端ε-LDP → TLS加密每日传输 → 丢弃IP → 跨用例不关联 → 仅输出超阈值统计
核心算法:CMS(已知词典频率估计)、HCMS(Hadamard高效变体)、SFP(未知词典Top-K发现)
客户端:
服务器端:
Google 2014年RAPPOR(来源:google/differential-privacy):
开源工具链:
| 工具 | 语言 | 用途 |
|---|---|---|
| DP Building Blocks | C++,Go,Java | Laplace/Gaussian/Count/Sum/Mean/Quantiles |
| Privacy on Beam | Go | 基于Apache Beam端到端框架 |
| PipelineDP4j | Java/Kotlin/Scala | 基于Beam/Spark端到端 |
| PipelineDP | Python | Google+OpenMined合作 |
| PyDP | Python | OpenMined封装C++库(pip install python-dp) |
| dp_accounting | Python | 隐私预算追踪 |
| DP Auditorium | Python | DP保证审计 |
| ZetaSQL DP CLI | — | DP SQL查询 |
全球最大DP部署(3.3亿人口):
争议:统计学家认为ε≈19.61太大近乎无隐私;普查局认为精度是硬约束。小区域噪声较大。截至写作时争论仍在继续。
ProUnit系统(2020)用DP保护"谁看了你"聚合统计。
OpenDP/SmartNoise。Telemetry也用DP。
RAPPOR收集浏览器统计。
OpenDP+UNHCR,DP保护难民数据统计。
| 参数 | 含义 | 经验值 |
|---|---|---|
| C | 裁剪阈值 | 1.0 |
| σ | 噪声倍率 | 0.5~2.0 |
| q | 采样率 | 0.01~0.1 |
| T | 训练步数 | 越少越好 |
# DP-SGD (TensorFlow Privacy)
# pip install tensorflow-privacy
from tensorflow_privacy.privacy.optimizers.dp_optimizer_keras import DPKerasSGDOptimizer
optimizer = DPKerasSGDOptimizer(
l2_norm_clip=1.0,
noise_multiplier=1.1,
num_microbatches=1,
learning_rate=0.15
)
model.compile(optimizer=optimizer, loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(train_data, epochs=10, batch_size=256)
# 计算隐私保证
from tensorflow_privacy.privacy.analysis import compute_dp_sgd_privacy
eps, d = compute_dp_sgd_privacy.compute_dp_sgd_privacy_lib.compute_dp_sgd_privacy(
n=60000, batch_size=256, noise_multiplier=1.1, epochs=10, delta=1e-5)
print(f"eps={eps:.2f}, delta={d}")
JAX Privacy v0.4.0(2025)支持LLM的DP微调:
防成员推断攻击。DP-SGD保证模型不泄露单条训练数据。ε=3~8保持大部分精度。
了解使用模式不收集原始数据。LDP需百万级用户才能提取有效统计。
防LLM泄露prompt敏感信息。DP扰动输出或DP fine-tuning。
| 库 | 语言 | 特点 | 安装 |
|---|---|---|---|
| Google DP | C++,Go,Java | 生产级,安全噪声生成 | Bazel |
| OpenDP | Rust+Python/R | 哈佛+微软,MIT协议 | pip install opendp |
| PyDP | Python | OpenMined封装Google C++库 | pip install python-dp |
| TF Privacy | Python | DP-SGD优化器+分析工具 | pip install tensorflow-privacy |
| JAX Privacy | Python | DP-SGD/DP-FTRL,支持LLM微调 | pip install git+https://github.com/google-deepmind/jax_privacy |
| Python | Google+OpenMined,基于Beam/Spark | pip install pipeline-dp | |
| dp_accounting | Python | 隐私预算追踪与组合计算 | pip install dp-accounting |
用 OpenDP(Python/R)或 Google DP(C++/Go/Java)。端到端用 Privacy on Beam 或 PipelineDP4j。
TF用户用 TensorFlow Privacy。JAX/Flax用户用 JAX Privacy。需要 LoRA 微调 LLM 用 JAX Privacy。
用 Google 的 ZetaSQL DP CLI,直接对数据集执行 DP SQL。
用 Google 的 DP Auditorium 或 OpenDP 的 stochastic tester。
# OpenDP 快速示例
# pip install opendp
from opendp.transformations import make_sized_bounded_mean
from opendp.measures import fixed_smoothed_max_divergence
from opendp.mod import enable_features
enable_features("contrib")
# 计算有界均值的DP版本
# epsilon=1.0, n=10000, bounds=(0., 100.)
mean = make_sized_bounded_mean(
size=10000,
bounds=(0., 100.),
)
dp_mean = mean >> make_sized_bounded_mean(
size=10000,
bounds=(0., 100.),
).make_privacy_map(
fixed_smoothed_max_divergence(),
d_in=1, # 相邻数据集差1条
)(d_out=1.0) # epsilon=1.0
# PyDP 快速示例
# pip install python-dp
import pydp as dp
from pydp.algorithms.laplacian import BoundedMean
# 计算差分隐私均值
x = BoundedMean(epsilon=0.6, lower_bound=1, upper_bound=10)
result = x.quick_result([5.2, 3.1, 7.8, 4.5, 9.1])
print(f"DP mean: {result:.2f}")
调整ε和数据集大小,观察Laplace噪声对计数查询的影响:
Casacuberta等人(2022,CCS 2022,arXiv:2207.10635)发现所有主流DP库在浮点数运算中存在敏感度低估漏洞:
如果δ=0.01而n=1000,意味着最多有10人的隐私可能被完全破坏——这和"不保护"差不多。δ必须远小于1/n,通常设为1/n2或更小。
DP有后处理性质:对DP输出做任意计算不增加隐私损失。但前提是原始输出确实是DP的。如果你先发布了非DP的中间结果再做DP,隐私已被破坏。
全局敏感度必须考虑最坏情况。例如求和查询的敏感度不是"平均贡献"而是"最大可能贡献"。如果数据范围无界,必须先裁剪(clipping)。
每次查询都消耗预算。如果你"忘记"之前的查询,实际上隐私损失在累积但你不自知。必须使用dp_accounting等工具追踪总预算。
去标识化(删除姓名/ID)不是差分隐私。Netflix Prize数据集即使去标识化,仍可通过电影评分与IMDB关联重新识别用户(Narayanan & Shmatikov, 2008)。
| 场景 | 推荐ε | 说明 |
|---|---|---|
| 高敏感医疗数据 | 0.1~1.0 | 隐私优先,噪声大 |
| 企业内部分析 | 1.0~3.0 | 平衡隐私与精度 |
| 大规模用户统计(LDP) | 2.0~8.0 | 需大量用户聚合 |
| 人口普查 | 1.0~20.0 | 取决于精度需求,争议大 |
| ML训练(DP-SGD) | 3.0~8.0 | 经验上可保持大部分精度 |
# 1. 计数查询 (Laplace机制)
import numpy as np
def dp_count(data, epsilon):
true_count = len(data)
b = 1.0 / epsilon # sensitivity = 1
noise = np.random.laplace(0, b)
return true_count + noise
# 2. 求和查询 (需clipping)
def dp_sum(data, epsilon, lower, upper):
clipped = np.clip(data, lower, upper)
true_sum = np.sum(clipped)
sensitivity = upper - lower # worst case
b = sensitivity / epsilon
noise = np.random.laplace(0, b)
return true_sum + noise
# 3. 均值查询
def dp_mean(data, epsilon, lower, upper):
dp_s = dp_sum(data, epsilon/2, lower, upper)
dp_c = dp_count(data, epsilon/2)
return dp_s / max(dp_c, 1) # 避免除零
# 4. 随机化应答 (LDP)
def randomized_response(truth, epsilon):
p = np.exp(epsilon) / (1 + np.exp(epsilon))
if np.random.random() < p:
return truth
else:
return not truth # 翻转
# 5. 恢复真实比例
def estimate_proportion(reported_yes_rate, epsilon):
p = np.exp(epsilon) / (1 + np.exp(epsilon))
return (reported_yes_rate - (1 - p)) / (2*p - 1)
数据来源与声明
本文内容基于公开学术文献和官方文档编写。未经验证的数据已标注"截至写作时未能确认"。