首页 > 解决方案 > AutoML Pipelines:从输入数据中提取标签并在 Neuraxle 或 SKLearn Pipelines 中采样

问题描述

我正在研究一个正在寻找精益 Python AutoML 管道实现的项目。根据项目定义,进入管道的数据采用序列化业务对象的格式,例如(人工示例):

property.json:
{
   "area": "124",
   "swimming_pool": "False",
   "rooms" : [
      ... some information on individual rooms ...
   ]
}

机器学习目标(例如,根据其他属性预测属性是否具有游泳池)存储在业务对象中,而不是在单独的标签向量中交付,并且业务对象可能包含不应用于训练的观察结果。

我在找什么

我需要一个支持初始(或以后)管道步骤的管道引擎,i)动态更改机器学习问题中的目标(例如从输入数据中提取,阈值真实值)和 ii)重新采样输入数据(例如上采样,下采样类,过滤观察)。

理想情况下,管道应如下所示(伪代码):

swimming_pool_pipeline = Pipeline([
    ("label_extractor", SwimmingPoolExtractor()),  # skipped in prediction mode
    ("sampler", DataSampler()),  # skipped in prediction mode
    ("featurizer", SomeFeaturization()),
    ("my_model", FitSomeModel())
])

swimming_pool_pipeline.fit(training_data)  # not passing in any labels
preds = swimming_pool_pipeline.predict(test_data)

管道执行引擎需要满足/允许以下内容:

例子

例如,假设数据如下所示:

property.json:
"properties" = [
    { "id_": "1",
      "swimming_pool": "False",
      ..., 
    },
    { "id_": "2",
      "swimming_pool": "True",
      ..., 
    },
    { "id_": "3",
      # swimming_pool key missing
      ..., 
    }
]

的应用程序SwimmingPoolExtractor()将提取如下内容:

"labels": [
    {"id_": "1", "label": "0"}, 
    {"id_": "2", "label": "1"}, 
    {"id_": "3", "label": "-1"}
]

从输入数据中获取并将其设置为机器学习管道的“目标”。

例如,应用程序DataSampler()还可以包括从整个训练数据集中删除不包含任何swimming_pool-key ( label = -1) 的任何训练实例的逻辑。

后续步骤应使用修改后的训练数据(过滤,不包括用 观察id_=3)来拟合模型。如上所述,在预测模式下,DataSamplerandSwimmingPoolExtractor只会通过输入数据

如何

据我所知,既不neuraxle也不sklearn(对于后者,我确信)提供满足所需功能的管道步骤(从我到目前为止收集的内容来看neuraxle,至少必须支持切片数据,因为它实现了交叉验证元估计器)。

我是否遗漏了什么,或者有没有办法在任何一个管道模型中实现这样的功能?如果没有,在 Python 生态系统中是否有替代列出的库,它们相当成熟并支持此类用例(撇开以这种方式设计管道可能产生的问题)?

标签: pythonscikit-learnpipelineautomlneuraxle

解决方案


“我是否遗漏了什么,或者有没有办法实现这样的功能”

是的,使用 Neuraxle可以轻松完成所有您想做的事情:

  1. 您错过了转换输出数据的输出处理程序!有了这个,您可以将一些内容发送x到管道中(因此实际上不会像您想要的那样y传递任何标签)。fit
  2. 您还错过了仅在火车时转换数据的 TrainOnlyWrapper!这对于在测试时(以及在验证时)停用任何管道步骤很有用。请注意,这种方式在评估验证指标时不会进行数据过滤或重新采样。
  3. 您还可以使用 AutoML 对象进行训练循环。

假设您在“fit”中传递的输入数据是可迭代的东西(例如:不要一次传递整个 json,至少制作可以迭代的东西)。在最坏的情况下,传递一个 ID 列表并执行一个步骤,该步骤将使用一个对象将 ID 转换为其他内容,该对象可以自行获取 json 以使用传递的 ID 执行所需的任何操作。

这是您更新的代码:

from neuraxle.pipeline import Pipeline

class SwimmingPoolExtractor(NonFittableMixin, InputAndOutputTransformerMixin, BaseStep): # Note here: you may need to delete the NonFittableMixin from the list here if you encounter problems, and define "fit" yourself rather than having it provided here by default using the mixin class. 
    def transform(self, data_inputs):
        # Here, the InputAndOutputTransformerMixin will pass 
        # a tuple of (x, y) rather than just x. 
        x, _ = data_inputs

        # Please note that you should pre-split your json into 
        # lists before the pipeline so as to have this assert pass: 
        assert hasattr(x, "__iter__"), "input data must be iterable at least."
        x, y = self._do_my_extraction(x)  # TODO: implement this as you wish!

        # Note that InputAndOutputTransformerMixin expects you 
        # to return a (x, y) tuple, not only x.
        outputs = (x, y) 
        return outputs

class DataSampler(NonFittableMixin, BaseStep):
    def transform(self, data_inputs):
        # TODO: implement this as you wish!
        data_inputs = self._do_my_sampling(data_inputs)

        assert hasattr(x, "__iter__"), "data must stay iterable at least."
        return data_inputs

swimming_pool_pipeline = Pipeline([
    TrainOnlyWrapper(SwimmingPoolExtractor()),  # skipped in `.predict(...)` call
    TrainOnlyWrapper(DataSampler()),  # skipped in `.predict(...)` call
    SomeFeaturization(),
    FitSomeModel()
])

swimming_pool_pipeline.fit(training_data)  # not passing in any labels!
preds = swimming_pool_pipeline.predict(test_data)

请注意,您还可以执行以下操作来替换对 的调用fit

auto_ml = AutoML(
    swimming_pool_pipeline,
    validation_splitter=ValidationSplitter(0.20),  # You can create your own splitter class if needed to replace this one. Dig in the source code of Neuraxle an see how it's done to create your own replacement. 
    refit_trial=True,
    n_trials=10,
    epochs=1,
    cache_folder_when_no_handle=str(tmpdir),
    scoring_callback=ScoringCallback(mean_squared_error, higher_score_is_better=False)  # mean_squared_error from sklearn
    hyperparams_repository=InMemoryHyperparamsRepository(cache_folder=str(tmpdir))
)

best_swimming_pool_pipeline = auto_ml.fit(training_data).get_best_model()
preds = best_swimming_pool_pipeline.predict(test_data)

如果您想使用高级数据缓存功能,请注意

如果要使用缓存,则不应定义任何transform方法,而应定义handle_transform方法(或相关方法),以便在重新采样数据时保持数据“ID”的顺序。Neuraxle 用于处理可迭代数据,这就是为什么我在上面做了一些断言,以确保您的 json 已经过预处理,使其成为某种列表。

其他有用的代码参考:


推荐阅读