关于 Fate 和单机直接训练效果差别的疑问

测试了一下发现联邦学习方式建模和单机直接训练的结果差异很大,以下叙述具体的测试流程。

测试数据集是这样的:

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.jsontest_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, 并且对结果的预测的评估也比单机训练的差了不少。


疑问

  1. 同一份训练数据输出的模型参数为何会有如此大的差异?
  2. 本例中纵向联邦训练效果不理想的主要原因是什么,调整 dsl 流程或参数可以得到改进吗?
  3. 如果可以,针对此例的数据集,应该如何调整流程和参数?

你可能感兴趣的:(关于 Fate 和单机直接训练效果差别的疑问)