二元随机响应(Binary Randomized Response, RR)的翻转概率

随机响应(Randomized Response)机制


✅ 回答核心:

p = 1 1 + e ε 才是「翻转概率」 \boxed{p = \frac{1}{1 + e^{\varepsilon}}} \quad \text{才是「翻转概率」} p=1+eε1才是「翻转概率」

而:
q = e ε 1 + e ε 是「保留真实值」的概率 \boxed{q = \frac{e^{\varepsilon}}{1 + e^{\varepsilon}}} \quad \text{是「保留真实值」的概率} q=1+eεeε是「保留真实值」的概率


✅ 为什么 p 才是翻转概率?

随机响应机制:用于二元隐私(0 或 1)

给定真实值 x ∈ {0,1},你不直接返回 x,而是使用以下方式:

  • 以概率 q = e ε 1 + e ε q = \frac{e^\varepsilon}{1 + e^\varepsilon} q=1+eεeε 保留 x
  • 以概率 p = 1 1 + e ε p = \frac{1}{1 + e^\varepsilon} p=1+eε1 返回 1 - x(翻转)

公式来源(源自 Local Differential Privacy 的 Binary Randomized Response):

隐私预算 ε 输出 1 的概率(如果 x=1) 输出 1 的概率(如果 x=0)
ε = ∞ 1(永远保留) 0(永远不翻转)
ε = 0 0.5(完全随机) 0.5(完全随机)

这满足 ε-LDP 要求的最小扰动机制。


✅ 举个例子:

假设真实值为 1,ε = 1:

  • q = e 1 1 + e 1 ≈ 0.731 q = \frac{e^1}{1 + e^1} ≈ 0.731 q=1+e1e1≈0.731 → 有 73.1% 概率返回 1(保留真实值)
  • p = 1 1 + e 1 ≈ 0.269 p = \frac{1}{1 + e^1} ≈ 0.269 p=1+e11≈0.269 → 有 26.9% 概率返回 0(翻转)

所以 p 是翻转概率,你撒谎的概率!


✅ 总结对比:

名称 公式 含义
翻转概率 1 1 + e ε \boxed{\frac{1}{1 + e^\varepsilon}} 1+eε1 "撒谎"的概率
保留真实值的概率 e ε 1 + e ε \frac{e^\varepsilon}{1 + e^\varepsilon} 1+eεeε 说实话的概率
总和 两者之和为 1 分别处理真实值/扰动

✅ 一句话总结:

p = 1 / (1 + exp(ε)) 是你翻转真实值(加噪声)的概率 ------ 所以它才叫 翻转概率


🧠 代码1:

python 复制代码
def matrix_randomized_response(x, eps):
    x = x.to(torch.bool)
    em = math.exp(eps)
    flip_prob = 1.0 / (em + 1)  # 翻转概率
    p = torch.full_like(x, 1 - flip_prob, dtype=torch.float32)  # 保留概率
    keep_mask = torch.bernoulli(p).to(torch.bool)
    x_noised = (~(x ^ keep_mask)).to(torch.float)
    return x_noised

我们来逐行详细解读 这段 matrix_randomized_response 函数,重点也会解释提到的核心扰动表达式:


✅ 目标:

这个函数实现 Binary Randomized Response (BRR) :对布尔矩阵 x 进行局部差分隐私(LDP)扰动,即:

对于每个元素:
以概率 e ε 1 + e ε \frac{e^\varepsilon}{1 + e^\varepsilon} 1+eεeε 保留原值,
以概率 1 1 + e ε \frac{1}{1 + e^\varepsilon} 1+eε1 翻转(扰动)它


🔍 逐行解释:


python 复制代码
x = x.to(torch.bool)
  • 把输入 x 强制转为布尔型(0/1)
  • 假设原始 x 是邻接矩阵或 one-hot 标签

python 复制代码
em = math.exp(eps)
flip_prob = 1.0 / (em + 1)
  • 计算 e ε e^\varepsilon eε,这是 LDP 中用于设定隐私保护强度的值
  • 计算翻转概率:
    flip_prob = 1 1 + e ε \text{flip\_prob} = \frac{1}{1 + e^\varepsilon} flip_prob=1+eε1

python 复制代码
p = torch.full_like(x, 1 - flip_prob, dtype=torch.float32)
  • 构造与 x 同形状的张量,每个值为「保留原值的概率」
    1 − flip_prob = e ε 1 + e ε 1 - \text{flip\_prob} = \frac{e^\varepsilon}{1 + e^\varepsilon} 1−flip_prob=1+eεeε

python 复制代码
keep_mask = torch.bernoulli(p).to(torch.bool)
  • p 进行伯努利采样,得到一个布尔掩码:

    • True 表示保留原值
    • False 表示需要翻转

✅ 🔍 解读核心扰动表达式:

python 复制代码
x_noised = (~(x ^ keep_mask)).to(torch.float)

这行做的是:

✴️ 布尔异或(XOR):

  • x ^ keep_mask

    • keep_mask=True(保留):x ^ True = not x
    • keep_mask=False(翻转):x ^ False = x
      所以直接 x ^ keep_mask反了

✴️ 再加一个 ~(取反)修正逻辑:

  • ~(x ^ keep_mask) 恰好实现:
x keep_mask x ^ keep_mask ~(x ^ keep_mask) 结果解释
0 True 1 0 保留 0 ✅
1 True 0 1 保留 1 ✅
0 False 0 1 翻转成 1 ✅
1 False 1 0 翻转成 0 ✅

.to(torch.float)

  • 最后把布尔张量转为浮点数张量(0.0 / 1.0),用于模型继续计算

✅ 最终效果:

这段代码实现的是对二值矩阵 x 中的每个值:

  • 以概率 e ε 1 + e ε \frac{e^\varepsilon}{1 + e^\varepsilon} 1+eεeε 保留
  • 以概率 1 1 + e ε \frac{1}{1 + e^\varepsilon} 1+eε1 翻转(扰动)

这是 Binary Randomized Response 的标准实现,适用于差分隐私保护场景。


🧠 代码2:

python 复制代码
def rr_adj():
     p = 1.0/(1.0+math.exp(self.eps_a))
     res = ((adj + torch.bernoulli(torch.full((n, n), p)).to(device)) % 2).float()
     res.fill_diagonal_(0)
     return res

🔧 函数定义:

① 计算扰动概率:

python 复制代码
p = 1.0 / (1.0 + math.exp(self.eps_a))
  • self.eps_a 是图结构扰动的隐私预算(epsilon)
  • 公式来自 Binary Randomized Response
  • p = 1 1 + e ε p = \frac{1}{1 + e^{\varepsilon}} p=1+eε1 是"翻转边"的概率(即扰动概率)

② 生成随机掩码并执行扰动:

python 复制代码
res = ((adj + torch.bernoulli(torch.full((n, n), p)).to(device)) % 2).float()
  • torch.full((n, n), p):创建一个全为 p 的二维张量,大小为 n × n n \times n n×n,和邻接矩阵 adj 一样大

  • torch.bernoulli(...):对每个元素独立进行伯努利采样(值为 1 的概率为 p,表示翻转)

  • adj + ...:相当于原始邻接矩阵加上"翻转掩码"

  • % 2:实现XOR(异或),即:

    • 0 + 1 = 1 (加边)
    • 1 + 1 = 0 (删边)
    • 0 + 0 = 0 (保持原样)
  • .float():把最终的布尔(0/1)结果转成浮点张量

🔁 最终效果:以概率 p 对每个边进行是否存在的翻转


③ 去除对角线(防止自环):

python 复制代码
res.fill_diagonal_(0)
  • 强制将所有的对角线元素(即 self-loop)设为 0,防止扰动产生自环

✅ 总结一下逻辑:

这个函数 rr_adj() 实现的是:

对输入图的邻接矩阵 adj

  • 对每一条边(包括 0)以概率 1 1 + e ε \frac{1}{1 + e^{\varepsilon}} 1+eε1 进行翻转(1→0,0→1)
  • 对角线(self-loops)始终设为 0

📌 关键点理解:

步骤 解释
torch.bernoulli(p) 决定是否翻转
% 2 实现 XOR 翻转
fill_diagonal_(0) 保证图中没有自环
eps_a 越大 翻转概率越小,扰动越少,隐私越弱
eps_a = 0 翻转概率 = 0.5,最随机,最大隐私保护

在这个上下文中:% 2 确实等价于 XOR(异或)操作,当我们处理的是布尔值或 0/1 值的张量时。


✅ 举个例子来说明:

设有两个值 ab,都在 {0, 1} 之间(也就是二值):

a b a + b (a + b) % 2 a ^ b (XOR)
0 0 0 0 0
0 1 1 1 1
1 0 1 1 1
1 1 2 0 0

✅ 在 PyTorch 中:

  • a ^ b 是布尔类型的异或(必须是 bool)
  • (a + b) % 2 是数值类型的异或等价操作(适用于 int/float 形式)

✅ 总结:

表达式 类型要求 等价含义
a ^ b 布尔张量 异或(推荐用于 bool)
(a + b) % 2 数值张量(0/1) 异或(等价,更通用)

✅ 一句话评价:

  • matrix_randomized_response() 更通用、更清晰、语义更明确。
  • ⚠️ rr_adj() 更简洁,但逻辑上容易误解,并且不适合复用到非邻接矩阵。

🔍 逐点比较:

rr_adj() matrix_randomized_response()
✅ 功能完整 是(扰动 + 去自环) 是(扰动,适合任意矩阵)
📦 可复用性 差,只能用于邻接矩阵 强,可用于标签、特征、邻接等
💬 表达语义 模糊,% 2 实现 XOR 不直观 清晰,显示 ^ 表达异或逻辑
📐 翻转概率显式 是,直接使用 1 1 + e ε \frac{1}{1+e^\varepsilon} 1+eε1 是,明确区分"翻转/保留"概率
🚫 特殊处理对角线 有(显式 fill_diagonal_) 无(需调用者自行处理)
⚙️ 类型控制 隐式处理,全部 float 明确布尔处理,更安全
相关推荐
天荒地老笑话么2 小时前
静态 IP 规划:掩码/网关/DNS 的正确组合
网络·网络协议·tcp/ip·网络安全
大方子20 小时前
【PolarCTF】rce1
网络安全·polarctf
枷锁—sha21 小时前
Burp Suite 抓包全流程与 Xray 联动自动挖洞指南
网络·安全·网络安全
聚铭网络1 天前
聚铭网络再度入选2026年度扬州市网络和数据安全服务资源池单位
网络安全
darkb1rd1 天前
八、PHP SAPI与运行环境差异
开发语言·网络安全·php·webshell
世界尽头与你1 天前
(修复方案)基础目录枚举漏洞
安全·网络安全·渗透测试
枷锁—sha2 天前
【SRC】SQL注入快速判定与应对策略(一)
网络·数据库·sql·安全·网络安全·系统安全
liann1192 天前
3.1_网络——基础
网络·安全·web安全·http·网络安全
ESBK20252 天前
第四届移动互联网、云计算与信息安全国际会议(MICCIS 2026)二轮征稿启动,诚邀全球学者共赴学术盛宴
大数据·网络·物联网·网络安全·云计算·密码学·信息与通信
旺仔Sec2 天前
一文带你看懂免费开源 WAF 天花板!雷池 (SafeLine) 部署与实战全解析
web安全·网络安全·开源·waf