测试了一下发现联邦学习方式建模和单机直接训练的结果差异很大,以下叙述具体的测试流程。
测试数据集是这样的:
id,y,x1,x2
1001,0,11,5
1002,0,12,10
1003,0,13,15
1004,0,14,20
1005,0,15,25
1006,0,16,30
1007,0,17,35
1008,0,18,40
1009,0,19,45
1010,0,20,50
1011,1,21,55
1012,1,22,60
1013,1,23,65
1014,1,24,70
1015,1,25,75
1016,1,26,80
1017,1,27,85
1018,1,28,90
1019,1,29,95
1020,1,30,100
首先尝试单机,使用最传统的逻辑回归进行训练,编写脚本如下:
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
X = []
y = []
lines = open('data.csv').readlines()
for line in lines[1:]:
line = line.strip()
if not line:
continue
id, _y, _x1, _x2 = line.split(',')
X.append([int(_x1), int(_x2)])
y.append(int(_y))
X_train, y_train = X, y
X_test, y_test = X, y
model = LogisticRegression(max_iter=50)
model.fit(X_train, y_train)
print(model.n_iter_)
print(model.coef_)
print(model.intercept_)
print('--------------------')
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred))
运行结果:
[33]
[[0.14421473 0.72107365]]
[-40.81276865]
--------------------
precision recall f1-score support
0 1.00 1.00 1.00 10
1 1.00 1.00 1.00 10
accuracy 1.00 20
macro avg 1.00 1.00 1.00 20
weighted avg 1.00 1.00 1.00 20
可以看出,迭代了 33 次后收敛,模型参数为 [0.14421473, 0.72107365], -40.81276865
并且以训练集来预测的结果很好,全都预测成功了。
接下来尝试使用 fate 来进行纵向联邦学习
数据拆分为 guest 方的 test_data1.csv
id,y,x1
1001,0,11
1002,0,12
1003,0,13
1004,0,14
1005,0,15
1006,0,16
1007,0,17
1008,0,18
1009,0,19
1010,0,20
1011,1,21
1012,1,22
1013,1,23
1014,1,24
1015,1,25
1016,1,26
1017,1,27
1018,1,28
1019,1,29
1020,1,30
和 host 方的 test_data2.csv
id,x2
1001,5
1002,10
1003,15
1004,20
1005,25
1006,30
1007,35
1008,40
1009,45
1010,50
1011,55
1012,60
1013,65
1014,70
1015,75
1016,80
1017,85
1018,90
1019,95
1020,100
分别 upload 后,在 guset 方创建 dsl 和 conf 文件,参考了test_hetero_lr_job_dsl.json
和 test_hetero_lr_job_conf.json
,去掉了其中特征工程的两个步骤,其他基本没有变化。
其中 dsl 文件如下:
{
"components" : {
"dataio_0": {
"module": "DataIO",
"input": {
"data": {
"data": [
"args.train_data"
]
}
},
"output": {
"data": ["train"],
"model": ["dataio"]
},
"need_deploy": true
},
"hetero_lr_0": {
"module": "HeteroLR",
"input": {
"data": {
"train_data": ["dataio_0.train"]
}
},
"output": {
"data": ["train"],
"model": ["hetero_lr"]
}
},
"evaluation_0": {
"module": "Evaluation",
"input": {
"data": {
"data": ["hetero_lr_0.train"]
}
},
"output": {
"data": ["evaluate"]
}
}
}
}
conf 文件如下:
{
"initiator": {
"role": "guest",
"party_id": 111
},
"job_parameters": {
"work_mode": 1,
"processors_per_node": 1,
"align_task_input_data_partition": true
},
"role": {
"guest": [111],
"host": [222],
"arbiter": [222]
},
"role_parameters": {
"guest": {
"args": {
"data": {
"train_data": [{"name": "testtb", "namespace": "testns"}]
}
},
"dataio_0":{
"with_label": [true],
"label_name": ["y"],
"label_type": ["int"],
"output_format": ["dense"]
}
},
"host": {
"args": {
"data": {
"train_data": [{"name": "testtb", "namespace": "testns"}]
}
},
"dataio_0":{
"with_label": [false],
"output_format": ["dense"]
}
}
},
"algorithm_parameters": {
"hetero_lr_0": {
"penalty": "L2",
"max_iter": 50,
"optimizer": "rmsprop",
"init_param": {
"init_method": "random_uniform"
}
}
}
}
然后发起任务
python fate_flow_client.py -f submit_job -c job_conf.json -d job_dsl.json
等待运行结束后查看结果,发现迭代了 50 次,仍未收敛,输出模型参数为 [0.030564, 0.151934], -0.157896
, 并且对结果的预测的评估也比单机训练的差了不少。
疑问
- 同一份训练数据输出的模型参数为何会有如此大的差异?
- 本例中纵向联邦训练效果不理想的主要原因是什么,调整 dsl 流程或参数可以得到改进吗?
- 如果可以,针对此例的数据集,应该如何调整流程和参数?