共计 8837 个字符,预计需要花费 23 分钟才能阅读完成。
一、背景
随着大数据、云计算等技术的倒退,数据隐衷平安问题受到越来越多的器重,各国都在增强数据安全和隐衷爱护。中国在 2017 年施行的《中华人民共和国网络安全法》要求网络运营者不得泄露、篡改、破坏收集的个人信息,并且在于第三方进行数据交易时须要确保合同明确约定拟交易数据的范畴和数据保护任务。欧盟也在 2018 年施行了法案《通用数据保护条例》(General Data Protection Regulation, GDPR)。这些法规的施行要求咱们在应用和替换数据的时候更加审慎,数据源之间彼此成为独立的“数据孤岛”,而人工智能的“魔力”来源于数据,特地是在一些理论利用场景中,无效数据都是“小数据”,须要不同数据源之间合作应用。
比方构建金融畛域反洗钱模型,但每家金融机构只有大量反洗钱案例;在医疗图像钻研中,对于特定病例的有标注图像数据是非常少的;少样本减少了建模的难度甚至无奈撑持建模。
除了这些“小数据”场景,有很多利用场景须要整合多维度的数据来刻画指标。比方金融畛域的风控场景,须要综合思考借贷人的人口属性,信用体现,多头体现,消费行为等,而简直没有一家数据公司能同时领有这么多维度的数据。
在车险定价畛域,除了车辆自身的状况外,车辆的应用状况,行车区域的环境也是影响保期内赔付危险的重要因素,对车险定价影响至关重要,特地是新客的体现数据很少,各方数据无奈无效连贯,难以精准定价。
然而数据隐衷平安法规出台之后,不同机构之间的数据聚合应用更加艰难,这些业务场景急需一项技术来实现数据源之间的平安聚合和建模。联邦学习 (FederatedLearning) 概念的初衷就是为了解决数据孤岛问题,该技术可能让数据在不出库的状况下实现建模工作。上面是维基百科中对联邦学习的定义:
Federated learning (also known as collaborative learning) is a machine learning technique that trains an algorithm across multiple decentralized edge devices or servers holding local data samples, without exchanging them. This approach stands in contrast to traditional centralized machine learning techniques where all the local datasets are uploaded to one server, as well as to more classical decentralized approaches which often assume that local data samples are identically distributed.
这段定义中有两个要害局部:
- machine learning technique:联邦学习实质也是一种机器学习技术
- holding local data samples, without exchanging them: 与将所有数据上传到一个服务器的传统机器学习以及将所有数据上传到一个集群的传统分布式机器学习相比,联邦学习的最大特点是所有数据源方将本人的数据保留在本人的本地,在建模过程中,也不会通过网络间接替换原始数据。
FATE 是微众银行推出的一款联邦学习开源框架,它实现了从数据预处理,特色筛选,建模,模型评估,模型上线整个流程了基本功能,目前也是业界最认可的联邦学习工程化实际,目前在金融信贷管理、批发、智慧城市、智慧安防等利用场景下都获得了胜利。本文将对 FATE 框架进行初步的实践和利用摸索。
二、FATE 介绍
2.1 机器学习背景介绍
图 1:机器学习个别流程
在启动一个机器学习模型我的项目后,个别会经验以下 6 个步骤:
- 导入数据对数据进行预处理: 这一步次要对数据进行荡涤,去除异样样本,标准数据格式等
- 对数据进行剖析:理解数据含意,剖析变量散布,做特色变量衍生等
- 特色工程:筛选特色,比方计算变量 IV, 特色转换,比方归一化、转换为 woe 等
- 训练模型:选定模型,模型调参
- 评估模型:依据我的项目选定模型评估指标, 常见指标有 AUC, KS, Precision, Recall 等
- 模型上线:线上部署,供业务方调用
在介绍联邦学习之前,先以逻辑斯特回归模型 (Logistic Regression, 以下简称 LR) 为例,介绍机器学习中的一些概念。分类和回归问题是机器学习中最常见的两类问题,常见的分类问题能够简化为如下的一个数学问题:Y={y1, y2 ,…,yn}示意分类问题的类别总和, n 为不同类别数,X={x1,x2,…,xm}为所有特色的汇合, m 为特色总量。分类问题的实质是学习一个函数映射 f(X;w) =Y, w 为模型的参数。咱们假如 X 和 Y 之间存在线性关系,即 Y∝ wX,wX∈(-∞ ,∞), 分类问题中 yi 为离散型数据,比方二分类问题,yi ={-1, 1}, 所以会在 wX 上增加一个 sigmoid 函数,该函数能够将 (-∞ ,∞) 之间的数字“压缩”到 (0, 1) 之间,而这个压缩值能够看做是模型的置信度。
图 2: LR 示意图及 sigmoid 函数
以上的一个计算形式 f(X,w)=sigmoid(wX) 就是逻辑斯特回归模型, LR 模型针对每个样本会输入样本对应的置信度,个别地,如果 f(xi,Θ)>=0.5, yi =1 , 反之 yi = -1。
那么,模型的参数 w 如何获取呢?参数 Θ 的学习能够转化为优化问题,在 LR 模型中,损失函数为:
逻辑斯特回归模型常见的参数求解办法为随机梯度降落。随机梯度降落法求参的步骤如下:
- 给定一个优化指标函数 f(X, w)、迭代次数 T 以及学习率 lr, 随机初始化参数 w0;
- 设定初始迭代次数 t =0
- for t = 0, 1, 2, …, T:
- 计算 g =fw’(X,w)
- 更新 w : wt+1 = wt – lr *g
梯度为:
2.2 联邦学习概述
在微众公布的《联邦学习白皮书 v2.0》中,对联邦学习的目标,联邦学习要达到的成果做了进一步论述:
- 各方数据都保留在本地,不泄露隐衷也不违反法规;
- 多个参与者联结数据建设虚构的共有模型,并且独特获益的体系;
- 在联邦学习的体系下,各个参与者的身份和位置平等;
- 联邦学习的建模成果和将整个数据集放在一处建模的成果雷同,或相差不大 (在各个数据的用户对齐(user alignment)或特色对齐(feature alignment) 对齐的条件下);
- 迁徙学习是在用户或者特色不对齐的状况下,也能够在数据间通过替换加密参数达到常识迁徙的成果。
联邦学习依据各个数据持有方 (数据持有方能够大于等于两方,以下为了简化以两方联邦建模为例) 之间用户和特色的散布状况,将联邦学习分为三种:
图 3:联邦学习分类示意图
横向联邦学习:联结建模的单方用户重叠较少,用户特色 X 重叠较多的状况;
纵向联邦学习:联结建模的单方用户重叠较多,用户特色 X 重叠较少的状况;
联邦迁徙学习:联结建模的单方用户以及用户 X 的重叠都较少。
2.3 FATE 框架
图 4: FATA 单方联结建模零碎框架
图 4 展现了一个残缺的 FATE 单方联结建模的零碎框架,微众和合作方别离部署了一个 FATE 集群,单方集群独特组成了一个 FATE 生态系统,单方别离从各自的数据库中抽样全量 ID,对 ID 进行加密求交加,目标是找出单方独特领有的用户 S,提取独特用户集的特色变量 XA, XB 以及体现数据 Y, 进入 FATE 的联邦学习阶段, 模型训练实现后会生成一个联结模型,联结模型别离在 AB 方保留半个模型。联结建模单方能够独特应用模型对全量样本进行离线预测以及在线打分。
图 5 : FATE 技术架构总览
图 5 为 FATE 零碎总体架构,从下往上比拟重要的功能模块:
- Federated Network: 实现 FATE 合作方之间的跨站点通信性能;
- EggRoll: 数据的分布式存储和计算模块;
- Fate Federated ML: 联邦学习算法性能组件,组件内实现了机器学习罕用算法;
- Fate-Flow: 联邦学习建模 pipeline, 模型计算调用入口;
- Fate-Board: 联邦学习建模看板,展示模型的 pipeline, 局部两头后果,模型进度以及模型日志;
- Fate-Serving: 反对联邦学习联结模型部署和在线预测。
在 FATE 零碎中,最外围的局部之一就是 Fate Federated ML,这一部分性能组件实现了机器学习建模过程中的大部分性能:
- 联邦学习样本对齐:private set intersect(PSI), 用于纵向样本对齐,包含基于 RSA+ 哈希等对齐形式
- 联邦特色工程:包含联邦采样,联邦特色分箱,联邦特征选择,联邦相关性,联邦统计等
- 联邦机器学习:联邦 Logistic Regression, LinearRegression, PossionRegression, PossionRegression, 联邦 SecureBoost, 联邦 DNN, 联邦迁徙学习等
- 多方平安计算协定:提供多种平安协定,包含同态加密,SecretShare, RSA, DiffieHellman 等
图 6:FATE 算法列表
2.4 FATE 算法框架
机器学习算法联邦化的底层关键技术是 MPC(Secure multi-party computation)。MPC 是姚期智学生提出的为解决一组互不信赖的参与方之间在爱护隐衷信息以及没有可信第三方的前提下进行协同计算实践框架。多方平安计算可能同时确保输出的隐衷性和计算的正确性,在无可信第三方的前提下通过数学实践保障参加计算的各方成员输出信息不裸露,且同时可能取得精确的运算后果。MPC 有多组算法和实践组成,在 FATE 模型算法中次要应用了同态加密算法。
图 7:FATE 纵向联邦学习基于梯度优化算法的通用框架
在图 7 展现了纵向联邦学习基于梯度优化算法的通用框架,假如企业 A 和企业 B 独特训练一个模型,A 方有本人的数据 X, B 方有 X 和 Y, 因为隐衷爱护起因,AB 不能间接替换数据。为了保障训练过程数据的保密性,退出了可信第三方 C, 整个建模流程如下:
- 由可信第三方 C 创立秘钥对,并将公共秘钥发送给 A 和 B;
- A 方和 B 方对两头后果进行加密和替换。两头后果用来帮忙计算梯度和损失值;
- A 方和 B 方计算加密梯度并别离退出附加掩码。B 方还需计算加密损失。A 方和 B 方将加密的后果发送给 C 方;
- C 方对梯度和损失信息进行解密,并将后果返回 A 方和 B 方。A 方和 B 方解除梯度信息上的掩码,并依据这些梯度信息来更新模型参数。
反复 2 - 4 步直到进行(比方 C 能够依据损失函数值不再变动就进行)。
模型训练实现后,企业 A 和企业 B 别离领有独立的半模型,在预测时,AB 单方须要独特单干来实现模型的预测。
上面以 LR 算法为例,具体论述数据在各方之间的流转。
图 8: 多方联邦 LR 计算模型计算框架
图中 [[*]] 表明对数据进行了同态加密,同态加密技术对明文进行的加法和乘法运算再加密,与加密后对密文进行相应的运算,后果是等价的。目前只能实现加减乘除的同态加密,由 2.1 的介绍可知,在 LR 模型的优化过程中,须要进行 exp 指数操作,为了防止这个操作,在联邦中对 LR 的损失函数进行了泰勒开展,损失函数和梯度转换为:
模型的各个参与方数据计算和流转步骤如下:
2.5 FATE 联结建模实际
FATE github 官方网站 https://github.com/FederatedA… 上有具体的装置领导,有趣味的敌人能够依照领导进行 FATE 部署和装置。
FATE 通过 fateflow 模块启动建模工作,fateflow 以 fate-dsl 语言定义模型的 pipeline, 整个模型的 pipeline 定义分为两个配置文件,dsl.json 配置文件定义模型的流程,conf.json 配置文件制订模型各个模块的参数设定。新版 FATE 公布后,能够反对相似于 sklearn 编程格调的模型 pipeline 进行模型设计,相熟 python 的建模分析师能够更快的上手应用 FATE 构建隐衷平安模型。上面为 FATE LR 模型的 pipeline 代码。
FATE Pipeline:
import argparse
from pipeline.backend.pipeline import PipeLine
from pipeline.component import DataIO
from pipeline.component import Evaluation
from pipeline.component import HeteroLR
from pipeline.component import Intersection
from pipeline.component import Reader
from pipeline.interface import Data
from pipeline.utils.tools import load_job_config
from pipeline.runtime.entity import JobParameters
def main(config=”../../config.yaml”, namespace=””):
# obtain config
if isinstance(config, str):
config = load_job_config(config)
parties = config.parties
guest = parties.guest[0]
host = parties.host[0]
arbiter = parties.arbiter[0]
backend = config.backend
work_mode = config.work_mode
guest_train_data = {"name": "breast_hetero_guest", "namespace": f"experiment{namespace}"}
host_train_data = {"name": "breast_hetero_host", "namespace": f"experiment{namespace}"}
pipeline = PipeLine().set_initiator(role='guest', party_id=guest).set_roles(guest=guest, host=host, arbiter=arbiter)
reader_0 = Reader(name="reader_0")
reader_0.get_party_instance(role='guest', party_id=guest).component_param(table=guest_train_data)
reader_0.get_party_instance(role='host', party_id=host).component_param(table=host_train_data)
dataio_0 = DataIO(name="dataio_0")
dataio_0.get_party_instance(role='guest', party_id=guest).component_param(with_label=True)
dataio_0.get_party_instance(role='host', party_id=host).component_param(with_label=False)
intersection_0 = Intersection(name="intersection_0")
hetero_lr_0 = HeteroLR(name="hetero_lr_0", early_stop="weight_diff", max_iter=10, penalty="L2", tol=0.0001, alpha=0.01,optimizer="rmsprop",batch_size=320,learning_rate=0.15)
evaluation_0 = Evaluation(name="evaluation_0", eval_type="binary")
pipeline.add_component(reader_0)
pipeline.add_component(dataio_0, data=Data(data=reader_0.output.data))
pipeline.add_component(intersection_0, data=Data(data=dataio_0.output.data))
pipeline.add_component(hetero_lr_0, data=Data(train_data=intersection_0.output.data))
pipeline.add_component(evaluation_0, data=Data(data=hetero_linr_0.output.data))
pipeline.compile()
job_parameters = JobParameters(backend=backend, work_mode=work_mode)
pipeline.fit(job_parameters)
# predict
# deploy required components
pipeline.deploy_component([dataio_0, intersection_0, hetero_lr_0])
predict_pipeline = PipeLine()
# add data reader onto predict pipeline
predict_pipeline.add_component(reader_0)
# add selected components from train pipeline onto predict pipeline
# specify data source
predict_pipeline.add_component(pipeline,
data=Data(predict_input={pipeline.dataio_0.input.data: reader_0.output.data}))
# run predict model
predict_pipeline.predict(job_parameters)
pipeline.dump("pipeline_saved.pkl")
if name == “__main__”:
parser = argparse.ArgumentParser("PIPELINE DEMO")
parser.add_argument("-config", type=str,
help="config file")
args = parser.parse_args()
if args.config is not None:
main(args.config)
else:
main()
以上代码实现了一个简略的 LR 模型,上面对代码进行简略解读:
• 代码的 18-23 行:初始化 FATE 建模的相干配置,外面波及到 FATE 中常见的几个概念
party_id: 它是一个 Int 型数字,用来惟一标识一个单边 FATE 物理集群
role: 参加建模的多方在建模工作重负责的角色,一共有三种角色:
guest 为数据利用方,是领有数据标签 y 值的一方, 在一个建模工作中只有一个 guest 方;
host 为数据提供方,只提供建模特色 x, 在一个建模工作中能够有大于等于一个的 host 方参加;
arbiter 为仲裁方,作为可信第三方参加建模过程中的聚合均匀等操作,在 FATE 中中仲裁方能够有 guest 方来负责;
backend:指定分布式计算存储引擎,backend=0,应用 eggroll 作为分布式计算和存储工具,backend= 1 应用 spark 以及 rabbitmq 作为音讯队列,backend=2 应用 spark 和 pulsar 的组合;
work_mode:work_mode=0 为 standalone,work_mode=1 为 cluster;
• 代码 25-26 行:申明 guest 方和 host 方的文件名称,在这段代码中应用了 eggroll 进行分布式计算和存储,在 eggroll 中命名空间 namespace 和表名 name 独特指定一个数据文件;
• 代码 28 行:初始化模型 pipeline, 指定工作发起方以及 guest 方和 host 方对应的 party_id;
• 代码 30-32 行: 定义 reader, 指定 guest 方和 host 方的应用数据;
• 代码 34-36 行:初始化 dataIO, 对单方样本进行初步解析,指定样本中是否蕴含 y 值,这一步也反对数据进行缺失值填充;
• 代码 38 行:初始化 intersect 隐衷求交组件,该组件用来计算多个数据源中的用户 id 交加,并且不泄露除交加外的任何用户 id, FATE 中反对两种隐衷求交形式:RAW 和 RSA, RSA 求交形式的安全性高于 RAW,然而计算和通信代价要高于 RAW 形式;
• 代码 39 行:定义 LR 模型组件,同时指定 LR 模型参数,纵向联邦 LR 模型的参数根本和传统机器学习 LR 的统一;
• 代码 40 行:定义一个模型评估器,评估的模型类型为二分类模型;
• 代码 42-46 行:依照建模流程程序,顺次将以上性能组件退出到 pipeline 中;
• 代码 48-50 行:编译 pipeline;初始化建模工作参数,设定 work_node 以及 backend; 训练 pipeline;
• 代码 54 行:指定 pipeline 上线部署时须要的性能组件;
• 代码 56-62 行: 定义模型预测的 pipeline, 并增加相应组件,与模型训练的 pipeline 相比,次要区别在数据读取器;
• 代码 64 行:应用模型预测;
• 代码 65 行:保留模型。
参考文献:
- 《联邦学习白皮书 v2.0》
- A Quasi-Newton Method Based Vertical Federated Learning Framework for Logistic Regression
- 《联邦学习的钻研与利用》
- 中国工信出版团体《联邦学习 Federated Learning》