我想创建一个多输出分类器。然而,我的难题在于每个输出的正标签分布差异很大,例如,输出1的正标签比例为2%,而输出2的正标签比例为20%。因此,我希望将每个输出的数据采样和模型拟合分成多个流(多个子pipeline),每个子pipeline分别进行过采样,并且过采样和分类器的超参数也分别进行优化。
例如,假设我有以下代码:
from sklearn.linear_model import LogisticRegressionfrom imblearn.over_sampling import SMOTEfrom imblearn.pipeline import PipelineX = # 此处为某些输入特征数组y = np.array([[0,1], [0,1], [0,0], [1,0], [0,0]]) # 不平衡的标签分布y_1 = y[:, 0]y_2 = y[:, 1]param_grid_shared = {'oversampler__sampling_strategy': [0.2, 0.4, 0.5], 'logit__C': [1, 0.1, 0.01]}pipeline_output_1 = Pipeline([('oversampler', SMOTE()), ('logit', LogisticRegression())])grid_1 = GridSearchCV(pipeline_output_1, param_grid_shared)grid_1.fit(X, y_1)pipeline_output_2 = Pipeline([('oversampler', SMOTE()), ('logit', LogisticRegression())])grid_2 = GridSearchCV(pipeline_output_2, param_grid_shared)grid_2.fit(X, y_2)
我想将它们结合起来,创建类似于以下内容的东西:
multi_pipe = Pipeline([(将X和y分成多个流的操作) ((pipe_1, pipeline_output_1), (pipe_2, pipeline_output_2)), # 分别优化的两个pipeline (为每个pipeline分别评估和选择超参数) (将pipeline 1和pipeline 2的输出结合起来的操作) ])
在Neuraxle或Sklearn中
MultiOutputClassifier显然不适合这种情况,我现在不太确定该从哪里寻找解决方案。
回答:
我创建了一个问题,并提出了以下想法:
pipe_1_with_oversampler_1 = Pipeline([ Oversampler1().assert_has_services(DataRepository), Pipeline1()])pipe_2_with_oversampler_2 = Pipeline([ Oversampler2().assert_has_services(DataRepository), Pipeline2()])multi_pipe = Pipeline([ DataPreprocessingStep(), # 在一次运行中使用`multi_pipe.fit(...)`为每个pipeline分别评估和选择超参数: FeatureUnion([ AutoML(pipe_1_with_oversampler_1, **automl_args_1), AutoML(pipe_2_with_oversampler_2, **automl_args_2) ]), # 然后使用feature union将pipeline 1和pipeline 2的输出结合起来。 # 也可以进行预处理和后处理。 PostprocessingStep(),])
为了实现这一点,可以将AutoML对象重构为一个常规步骤,从而可以在一个步骤中使用它。