纵向联邦学习与特征对齐
纵向联邦学习(Vertical Federated Learning)处理的是样本重叠但特征不同的场景。各方持有同一批用户的不同特征,需要在不暴露原始数据的情况下联合建模。
横向 vs 纵向
| 维度 | 横向联邦 | 纵向联邦 |
|---|---|---|
| 数据划分 | 按样本分(行切分) | 按特征分(列切分) |
| 特征 | 相同 | 不同 |
| 样本 | 不同 | 重叠 |
| 通信 | 梯度/模型参数 | 中间激活/梯度 |
| 代表场景 | 多医院同病种 | 银行+电商同用户 |
隐私求交(PSI)
纵向联邦的前提是找到共有样本(样本对齐),且不泄露非共有样本:
python
# 基于 Hash 的 PSI
class HashBasedPSI:
def __init__(self, hash_funcs):
self.hash_funcs = hash_funcs
def compute_bloom_filter(self, ids):
"""计算布隆过滤器"""
bf = set()
for id_val in ids:
for h in self.hash_funcs:
bf.add(h(str(id_val)))
return bf
def find_intersection(self, local_ids, remote_bf):
"""找出交集(不暴露非交集)"""
intersection = []
for id_val in local_ids:
if all(h(str(id_val)) in remote_bf for h in self.hash_funcs):
intersection.append(id_val)
return intersection纵向联邦训练
SplitNN 方案
python
class VerticalSplitNN:
"""纵向分割神经网络"""
def __init__(self, party_a_model, party_b_model):
self.model_a = party_a_model # 持有前半部分特征
self.model_b = party_b_model # 持有后半部分特征
def forward(self, x_a, x_b):
# Party A: 前向传播到切割层
h_a = self.model_a.forward_bottom(x_a)
# 发送 h_a 给 Party B(加密传输)
h_a_encrypted = encrypt(h_a)
# Party B: 拼接并继续前向
h_b = self.model_b.forward_bottom(x_b)
h_combined = torch.cat([decrypt(h_a_encrypted), h_b], dim=-1)
output = self.model_b.forward_top(h_combined)
return output安全增强
纵向联邦中,中间激活的传输可能泄露信息:
python
# 添加噪声保护中间激活
class SecureVerticalNN(VerticalSplitNN):
def forward(self, x_a, x_b):
h_a = self.model_a.forward_bottom(x_a)
# 添加 DP 噪声保护
noise = torch.randn_like(h_a) * 0.01
h_a_noisy = h_a + noise
# 加密传输
h_a_encrypted = encrypt(h_a_noisy)
# ... 其余同上特征对齐挑战
| 挑战 | 描述 | 解决方案 |
|---|---|---|
| 样本匹配 | 跨方用户ID不同 | PSI + ID 映射 |
| 特征空间对齐 | 特征维度/分布不同 | 联邦表示学习 |
| 时间对齐 | 数据时间戳不一致 | 时序对齐算法 |
| 缺失值 | 部分样本缺失特征 | 联邦填充/忽略 |
纵向联邦关键点
- PSI 是第一步,确保样本对齐
- 中间激活传输必须加密或加噪
- 切割层位置影响通信量和隐私性
- 特征工程比横向联邦更重要
梯度泄露
纵向联邦中,一方可能通过接收到的梯度反推另一方的特征。必须使用梯度裁剪、加噪或加密来防御梯度泄露攻击。