FATE是微众银行开发的联邦学习平台,是全球首个工业级的联邦学习开源框架,在github上拥有近4000stars,可谓是相当有名气的,该平台为联邦学习提供了完整的生态和社区支持,为联邦学习初学者提供了很好的环境,否则利用python从零开发,那将会是一件非常痛苦的事情。本篇博客内容涉及《联邦学习实战》第六章内容,使用的fate版本为1.6.0,fate的安装已经在这篇博客中介绍,有需要的朋友可以点击查阅。下面就让我们开始吧。
本次实战使用的数据集为波士顿房价预测数据集,并且已经内置在sklearn库中,可以直接加载查看。前五组数据查看如下:
其中y表示房屋的均值价格。
从数据集中抽取前460条数据作为训练数据,将后面100条作为评估测试数据。
housing_1_train.csv
。同样,从这406条训练数据中抽取380条数据和后5个特征,以及标签y,作为公司B的本地数据,文件保存为housing_2_train.csv
。housing_1_eval.csv
。再从这100条测试数据中抽取85条数据和后5个特征,以及标签y,作为公司B的本地测试数据,文件保存为housing_2_eval.csv
。切分代码如下:
from sklearn.datasets import load_boston
import pandas as pd
# 导入并查看数据
boston_dataset = load_boston()
boston = pd.DataFrame(boston_dataset.data, columns=boston_dataset.feature_names)
boston.head()
# z-score标准化
boston = (boston - boston.mean()) / (boston.std())
# 处理属性名
col_names = boston.columns.values.tolist()
columns = {}
for idx, n in enumerate(col_names):
columns[n] = "x%d"%idx
boston = boston.rename(columns=columns)
# 插入每行序号和y
boston['y'] = boston_dataset.target
idx = range(boston.shape[0])
boston.insert(0, 'idx', idx)
# 打乱数据生成csv
boston = boston.sample(frac=1)
train = boston.iloc[:406]
eval = boston.iloc[406:]
housing_1_train = train.iloc[:360,:9]
# 再次打乱训练数据
train = train.sample(frac=1)
housing_2_train = train.iloc[:380,[0,9, 10, 11, 12, 13, 14]]
housing_1_eval = eval.iloc[:80,:9]
# 再次打乱测试数据
eval = eval.sample(frac=1)
housing_2_eval = eval.iloc[:85,[0,9, 10, 11, 12, 13, 14]]
housing_1_train.to_csv('housing_1_train.csv', index=False, header=True)
housing_2_train.to_csv('housing_2_train.csv', index=False, header=True)
housing_1_eval.to_csv('housing_1_eval.csv', index=False, header=True)
housing_2_eval.to_csv('housing_2_eval.csv', index=False, header=True)
按照上述方案切分后,最终两家公司的用户数据交集为85%左右,而测试集的用户交集大约为68%。这里要注意FATE中的数据一定要插入标签,否则第一列会被当作标签,并且在纵向联邦学习寻找标签交集的时候会因为第一列不是标签而是数据无法对齐,出现Count of data_instance is 0
的错误。
纵向联邦训练通常涉及以下四项工作:
在xshell中进入到fate的docker环境,输入
$ rz -be
将本地生成的csv文件上传到example/data
中。
定义上传数据配置文件,将其命名为upload_data.json
,以处理housing_1_train.json
文件为例,配置文件如下:
{
"file": "/fate/example/data/housing_1_train.csv",
"head": 1,
"partition": 8,
"work_mode": 0,
"table_name": "homo_housing_1_train",
"namespace": "homo_host_housing_train"
}
在/fate位置下输入:
python python/fate_flow/fate_flow_client.py -f upload -c upload_data.json
输出如下即上传成功:
{
"data": {
"board_url": "http://127.0.0.1:8080/index.html#/dashboard?job_id=202203150220403776101&role=local&party_id=0",
"job_dsl_path": "/fate/jobs/202203150220403776101/job_dsl.json",
"job_id": "202203150220403776101",
"job_runtime_conf_on_party_path": "/fate/jobs/202203150220403776101/local/job_runtime_on_party_conf.json",
"job_runtime_conf_path": "/fate/jobs/202203150220403776101/job_runtime_conf.json",
"logs_directory": "/fate/logs/202203150220403776101",
"model_info": {
"model_id": "local-0#model",
"model_version": "202203150220403776101"
},
"namespace": "homo_host_housing_eval",
"pipeline_dsl_path": "/fate/jobs/202203150220403776101/pipeline_dsl.json",
"table_name": "homo_housing_1_eval",
"train_runtime_conf_path": "/fate/jobs/202203150220403776101/train_runtime_conf.json"
},
"jobId": "202203150220403776101",
"retcode": 0,
"retmsg": "success"
}
重复上述操作将另外三个csv文件上传即可。其余三个配置文件如下:
{
"file": "/fate/example/data/housing_2_train.csv",
"head": 1,
"partition": 8,
"work_mode": 0,
"table_name": "homo_housing_2_train",
"namespace": "homo_guest_housing_train"
}
{
"file": "/fate/example/data/housing_1_eval.csv",
"head": 1,
"partition": 8,
"work_mode": 0,
"table_name": "homo_housing_1_eval",
"namespace": "homo_host_housing_eval"
}
{
"file": "/fate/example/data/housing_2_eval.csv",
"head": 1,
"partition": 8,
"work_mode": 0,
"table_name": "homo_housing_2_eval",
"namespace": "homo_guest_housing_eval"
}
样本对齐旨在不泄露双方数据的前提下,求取双方用户的交集,从而确定模型训练的训练数据集。
FATE提供多方安全的样本对齐算法,算法基于RSA加密算和散列函数,利用FATE建模时,不需要自己实现样本对齐算法,FATE为模型训练提供了样本对齐的接口。具体的实现将在以后的博客中阐述。
在FATE框架下,模型训练的本质就是修改dsl.json和conf.json两个文件,进入$fate_dir/examples/dsl/v1/hetero_linear_regression
目录中,该目录下已经有很多定义好的dsl和conf配置文件,修改下面两个文件。
首先查看dsl配置文件,定义了四个组件模块:
查看conf文件,需要修改两处地方。
在FATE中,如果仅仅提供了模型训练的数据信息,模型评估使用的是训练数据。如果用独立的测试数据,需要添加新的数据模块。
修改dsl文件,需要在dsl中增加新的测试数据输入模块dataio_1和测试数据样本对齐模块intersection_1。
此外还有模型训练和评估模块:
注意模块都是相互对应的,上一个模块的输出会是下一个模块的输入,千万别弄错了。
接下来是修改conf配置文件,添加品古测试数据集表明和命名空间。此外,还要注意评估模块evaluation_1
,确定评估类型和pos_label,否则会报错Only one class present in y_true. ROC AUC score is not defined in that case
。
花了一天时间,总算是把这一章的代码复现出来,这可能是CSDN上第一篇《联邦学习实战》第六章内容的复现,在没有任何参考的情况下,以及书籍中部分内容描述不清,在复现的时候遇到了许多坑,比如数据标签不插入就没法数据对齐(原书跳过了该步骤),原书中部分name和namespace不对应需要自己注意,原书中评估模块缺少了后面的hetero_linr_1
和evaluation_1
两部分,需要自己添加,以及原书中评估部分的conf.json中,不加上evaluation_1
的参数配置是跑不通代码的。所有这些都让我对FATE有了进一步的理解与认识,希望这篇博客能对部分读者有一定的帮助吧。