【联邦学习FATE框架实战】(二)用FATE从零开始实现横向逻辑回归

1. 获取数据集

1.1 下载数据集

  • 数据集:乳腺癌肿瘤数据集(内置在sklearn库)
from sklearn.datasets import load_breast_cancer
import pandas as pd 

breast_dataset = load_breast_cancer()
breast = pd.DataFrame(breast_dataset.data, columns=breast_dataset.feature_names)
breast.head()

在这里插入图片描述

  • 观察数据发现,样本数569,特征数30(10个属性分别以均值mean、标准差std、最差值worst出现),标签(1-良性肿瘤,0-恶性肿瘤)1:0 = 357:212
    在这里插入图片描述

1.2 横向数据集切分

  • 为了模拟横向联邦建模场景,将数据集切分为特征相同的横向联邦形式
  • 切分策略:
    • 前469个数据作为训练数据,后100个数据作为测试数据
    • 训练数据中,前200个作为机构A的数据,存为breast_1_train.csv,后269个数据作为机构B的数据,存为breast_2_train.csv
    • 测试数据不切分,存为breast_eval.csv
  • 数据集完整代码
from sklearn.datasets import load_breast_cancer
import pandas as pd 

breast_dataset = load_breast_cancer()
breast = pd.DataFrame(breast_dataset.data, columns=breast_dataset.feature_names)

breast = (breast-breast.mean())/(breast.std())  # z-score 标准化

col_names = breast.columns.values.tolist()

columns = {}
for idx, n in enumerate(col_names):
	columns[n] = "x%d"%idx 
breast = breast.rename(columns=columns)	

breast['y'] = breast_dataset.target
breast['idx'] = range(breast.shape[0])
idx = breast['idx']
breast.drop(labels=['idx'], axis=1, inplace = True)
breast.insert(0, 'idx', idx)

breast = breast.sample(frac=1) # 打乱数据

train = breast.iloc[:469]
eval = breast.iloc[469:]
breast_1_train = train.iloc[:200]
breast_2_train = train.iloc[200:] 
breast_1_train.to_csv('breast_1_train.csv', index=False, header=True)
breast_2_train.to_csv('breast_2_train.csv', index=False, header=True)
eval.to_csv('breast_eval.csv', index=False, header=True)

2. 通过DSL Conf运行训练和预测任务

  • 可以通过 Flow Client HF提交 conf 和 dsl 来开始训练作业
  • 这个流程包括
    • 数据输入
    • 模型训练
    • 模型评估
  • 注:配置文件中的注释在使用时要去除,否则无法进行 Flow Client 任务

2.1 数据输入

  • 上传数据的配置文件示例可以从以下目录找到

    • example/dsl/v2/upload
      • upload_conf.json 或 upload_tag_conf.json(配置项相同)
      • 该配置文件结构
        {
        	"file": "/data/projects/fate/examples/data/breast_hetero_guest.csv",	// 数据文件路径,相对于当前所在路径
        	"table_name": "breast_hetero_guest",	// 需要转换为DTable格式的表名
        	"namespace": "experiment",// DTable格式的表名对应的命名空间
        	"head": 1,	// 指定数据文件是否包含表头,1: 是,0: 否
        	"partition": 8,	// 指定用于存储数据的分区数
        	"work_mode": 0,	 // 指定工作模式,0: 单机版,1: 集群版
        	"backend": 0	// 指定后端,0:EggRoll, 1: Spark _ RabbitMQ, 2: Spark + Pulsar
        }
        
  • 这里使用较新的dsl v2版本,配置文件如下

    • workspace/HFL_lr/ 是我建立在fate根目录下的目录
    • 上传训练数据至机构1 upload_train_host_conf.json
      {
          "file": "workspace/HFL_lr/breast_1_train.csv",
          "table_name": "homo_breast_1_train",
          "namespace": "homo_host_breast_train",
          "head": 1,
          "partition": 8,
          "work_mode": 0,
          "backend": 0
      }
      
    • 上传训练数据至机构2 upload_train_guest_conf.json
      {
          "file": "workspace/HFL_lr/breast_2_train.csv",
          "table_name": "homo_breast_2_train",
          "namespace": "homo_guest_breast_train",
          "head": 1,
          "partition": 8,
          "work_mode": 0,
          "backend": 0
      }
      
    • 上传测试数据至机构1 upload_eval_host_conf.json
      {
          "file": "workspace/HFL_lr/breast_eval.csv",
          "table_name": "homo_breast_1_eval",
          "namespace": "homo_host_breast_eval",
          "head": 1,
          "partition": 8,
          "work_mode": 0,
          "backend": 0
      }
      
    • 上传测试数据至机构2 upload_eval_guest_conf.json
      {
          "file": "workspace/HFL_lr/ 是我建立在fate根目录下的目录breast_eval.csv",
          "table_name": "homo_breast_2_eval",
          "namespace": "homo_guest_breast_eval",
          "head": 1,
          "partition": 8,
          "work_mode": 0,
          "backend": 0
      }
      
  • 上传数据命令

    workspace/HFL_lr/ 是我建立在fate根目录下的目录
    $ flow data upload -c workspace/HFL_lr/upload_train_host_conf.json 
    $ flow data upload -c workspace/HFL_lr/upload_train_guest_conf.json 
    $ flow data upload -c workspace/HFL_lr/upload_eval_host_conf.json 
    $ flow data upload -c workspace/HFL_lr/upload_eval_guest_conf.json 
    

    在这里插入图片描述
    在这里插入图片描述

    数据上传成功

  • 提示:若出现以下问题,说明

    {                                                                                                                 
    	"retcode": 100,                                                                                               
    	"retmsg": "Fate flow CLI has not been initialized yet or configured incorrectly. Please initialize it before using CLI at the first time. And make sure the address of fate flow server is configured correctly. The configuration file path is: /ai/xwj/federate_learning/fate_dir/standalone_fate_master_1.6.0/venv/lib/python3.6/site-packages/flow_client/settings.yaml."                                                                                       
    }      
    

    说明Flow未初始化,执行命令flow init --ip 127.0.0.1 --port 9380即可

2.2 模型训练

  • 目前,FATE框架提供的 DSL 中,可以将各种任务模块通过一个有向无环图 (DAG) 组织起来。用户可以根据自身的需要,灵活地组合各种算法模块。
  • 这里采用逻辑回归模型。

2.2.1 配置DSL文件

  • 官方提供的示例可以以下目录找到
    • 官方示例中的各种模块说明
      • 数据读取组件(支持图像)
      • reader_0:dataio_0: 数据IO组件,用于将本地数据转为DTable
      • feature_scale_0:特征工程组件
      • homo_lr_0:横向逻辑回归组件
      • evaluation_0:模型评估组件,如果未提供测试数据集则自动使用训练集
    • /examples/dsl/v2/homo_logistic_regression
      {
          "components": {
              "reader_0": {
                  "module": "Reader",
                  "output": {
                      "data": ["data"]
                  }
              },
              "dataio_0": {
                  "module": "DataIO",
                  "input": {
                      "data": {
                          "data": ["reader_0.data"]
                      }
                  },
                  "output": {
                      "data": ["data"],
                      "model": ["model"]
                  }
              },
              "scale_0": {
                  "module": "FeatureScale",
                  "input": {
                      "data": {
                          "data": ["dataio_0.data"]
                      }
                  },
                  "output": {
                      "data": ["data"],
                      "model": ["model"]
                  }
              },
              "homo_lr_0": {
                  "module": "HomoLR",
                  "input": {
                      "data": {
                          "train_data": ["scale_0.data"]
                      }
                  },
                  "output": {
                      "data": ["data"],
                      "model": ["model"]
                  }
              },
              "evaluation_0": {
                  "module": "Evaluation",
                  "input": {
                      "data": {
                          "data": ["homo_lr_0.data"]
                      }
                  },
                  "output": {
                      "data": ["data"]
                  }
              }
          }
      }
      
      • dsl文件中数据流动的如图所示
        在这里插入图片描述

2.2.2 运行配置Submit Runtime Conf

  • 每个模块都有不同的参数需要配置,不同的 party 对于同一个模块的参数也可能有所区别。为了简化这种情况,对于每一个模块,FATE 会将所有 party 的不同参数保存到同一个运行配置文件(Submit Runtime Conf)中,并且所有的 party 都将共用这个配置文件。
  • 除了 DSL 的配置文件之外,用户还需要准备一份运行配置(Submit Runtime Conf)用于设置各个组件的参数。
  • 角色说明
    • arbiter:是用来辅助多方完成联合建模的,它的主要作用是聚合梯度或者模型。比如纵向lr里面,各方将自己一半的梯度发送给arbiter,然后arbiter再联合优化等等。
    • initiator:任务发起人
    • host:数据提供方
    • guest:数据应用方
    • local:本地任务,该角色仅用于 upload 和 download 阶段
  • 官方提供的示例可以以下目录找到
    • /examples/dsl/v2/homo_logistic_regreesion/homo_lr_train_conf.json,对部分内容进行修改
     {
        "dsl_version": 2,
        // 发起人
        "initiator": {
            "role": "guest",
            "party_id": 10000
        },
        // 所有参与此任务的角色
     	// 每一个元素代表一种角色以及承担这个角色的party_id,是一个列表表示同一角色可能有多个实体ID
        "role": {
            "guest": [10000],
            "host": [10000],
            "arbiter": [10000] // 仲裁者
        },
        "job_parameters": {
            "common": {
                "job_type": "train",
                "backend": 0,
                "work_mode": 0
            }
        },
        // 设置模型训练的超参数信息
        "component_parameters": {
            "common": {
                "dataio_0": {
                    "with_label": true,
                    "label_name": "y", 
                    "label_type": "int",
                    "output_format": "dense"
                },
                "homo_lr_0": {
                    "penalty": "L2",
                    "tol": 1e-05,
                    "alpha": 0.01,
                    "optimizer": "sgd",
                    "batch_size": -1,
                    "learning_rate": 0.015,
                    "init_param": {
                        "init_method": "zeros"
                    },
                    "max_iter": 10,
                    "early_stop": "diff",
                    "encrypt_param": {
                        "method": null
                    },
                    "cv_param": {
                        "n_splits": 4,
                        "shuffle": true,
                        "random_seed": 33,
                        "need_cv": false
                    },
                    "decay": 1,
                    "decay_sqrt": true
                },
                "evaluation_0": {
                    "eval_type": "binary"
                }
            },
            "role": {
                "host": {
                    "0": {
                        "reader_0": {
                            "table": {
                                "name": "homo_breast_1_train", // 修改DTable的表名,对应上传数据时配置文件的内容
                                "namespace": "homo_host_breast_train" // 修改命名空间,对应上传数据时配置文件的内容
                            }
                        },
                        "evaluation_0": {"need_run": false}
                    }
                },
                "guest": {
                    "0": {
                        "reader_0": {
                            "table": {
                                "name": "homo_breast_2_train", // 修改DTable的表名,对应上传数据时配置文件的内容
                                "namespace": "homo_guest_breast_train" // 修改命名空间,对应上传数据时配置文件的内容
                            }
                        }
                    }
                }
            }
        }
    }
    

2.2.3 提交任务,训练模型

  • 执行pipeline任务

  • flow job submit -c ${conf_path} -d ${dsl_path}

    参数Flag必要参数说明
    conf_path-c任务配置文件路径
    dsl_path-dDSL文件路径。如果任务是预测任务,可以不输入。

    在这里插入图片描述
    在这里插入图片描述
    需要全部通过,才说明运行成功
    在这里插入图片描述

可以看到训练结果
在这里插入图片描述

在这里插入图片描述

2.3 模型评估

  • 官方示例在目录examples/dsl/v2/homo_logistic_regression
  • homo_lr_train_eval_conf.json
  • homo_lr_train_eval_dsl.json

2.3.1 修改DSL

{
    "components": {
        "reader_0": {
            "module": "Reader",
            "output": {
                "data": ["data"]
            }
        },
        "reader_1": {
            "module": "Reader",
            "output": {
                "data": ["data"]
            }
        },
        "dataio_0": {
            "module": "DataIO",
            "input": {
                "data": {
                    "data": ["reader_0.data"]
                }
            },
            "output": {
                "data": ["data"],
                "model": ["model"]
            }
        },
        "dataio_1": {
            "module": "DataIO",
            "input": {
                "data": {
                    "data": ["reader_1.data"]
                },
                "model": ["dataio_0.model"]
            },
            "output": {
                "data": ["data"],
                "model": ["model"]
            }
        },
        "scale_0": {
            "module": "FeatureScale",
            "input": {
                "data": {
                    "data": ["dataio_0.data"]
                }
            },
            "output": {
                "data": ["data"],
                "model": ["model"]
            }
        },
        "scale_1": {
            "module": "FeatureScale",
            "input": {
                "data": {
                    "data": ["dataio_1.data"]
                },
                "model": ["scale_0.model"]
            },
            "output": {
                "data": ["data"],
                "model": ["model"]
            }
        },
        "homo_lr_0": {
            "module": "HomoLR",
            "input": {
                "data": {
                    "train_data": ["scale_0.data"],
                    "validate_data": ["scale_1.data"]
                }
            },
            "output": {
                "data": ["data"],
                "model": ["model"]
            }
        },
        "evaluation_0": {
            "module": "Evaluation",
            "input": {
                "data": {
                    "data": ["homo_lr_0.data"]
                }
            },
            "output": {
                "data": ["data"]
            }
        }
    }
}

2.3.2 修改conf

{
    "dsl_version": 2,
    "initiator": {
        "role": "guest",
        "party_id": 10000
    },
    "role": {
        "guest": [10000],
        "host": [10000],
        "arbiter": [10000]
    },
    "job_parameters": {
        "common": {
            "job_type": "train",
            "backend": 0,
            "work_mode": 0
        }
    },
    "component_parameters": {
        "common": {
            "dataio_0": {
                "with_label": true,
                "label_name": "y",
                "label_type": "int",
                "output_format": "dense"
            },
            "homo_lr_0": {
                "penalty": "L2",
                "tol": 1e-05,
                "alpha": 0.01,
                "optimizer": "sgd",
                "batch_size": -1,
                "learning_rate": 0.15,
                "init_param": {
                    "init_method": "zeros"
                },
                "encrypt_param": {
                    "method": null
                },
                "max_iter": 10,
                "early_stop": "diff",
                "cv_param": {
                    "n_splits": 4,
                    "shuffle": true,
                    "random_seed": 33,
                    "need_cv": false
                },
                "validation_freqs": 1
            },
            "evaluation_0": {
                "eval_type": "binary"
            }
        },
        "role": {
            "host": {
                "0": {
                    "evaluation_0": {"need_run": false},
                    "reader_1": {
                        "table": {
                            "name": "homo_breast_1_eval",
                            "namespace": "homo_host_breast_eval"
                        }
                    },
                    "reader_0": {
                        "table": {
                            "name": "homo_breast_1_train",
                            "namespace": "homo_host_breast_train"
                        }
                    }
                }
            },
            "guest": {
                "0": {
                    "reader_1": {
                        "table": {
                            "name": "homo_breast_2_eval",
                            "namespace": "homo_guest_breast_eval"
                        }
                    },
                    "reader_0": {
                        "table": {
                            "name": "homo_breast_2_train",
                            "namespace": "homo_guest_breast_train"
                        }
                    }
                }
            }
        }
    }
}

2.3.3 提交任务

  • flow job submit -c ${conf_path} -d ${dsl_path}
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

  • 12
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值