AutoML Pipelines:从输入数据中提取标签并在 Neuraxle 或 SKLearn Pipelines 中采样

AutoML Pipelines: Label extraction from input data and sampling within Neuraxle or 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)

流水线执行引擎需要fulfill/allow以下内容:

例子

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

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 的观察)来拟合模型。如上所述,在预测模式下,DataSamplerSwimmingPoolExtractor 只会通过输入数据

如何

据我所知,neuraxlesklearn(我确信对于后者)都没有提供满足所需功能的管道步骤(根据我目前收集到的 neuraxle至少必须支持切片数据,因为它实现了交叉验证元估计器)。

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

"Am I missing something, or is there a way to implement such functionality"

是的,所有您想做的事都可以用 Neuraxle 相当容易完成:

  1. 您错过了 output handlers to transform output data!有了这个,您可以在管道内将一些 x 发送到 y(因此实际上不会像您想要的那样将任何标签传递给 fit)。
  2. 您还错过了 TrainOnlyWrapper to transform data only at train time!这对于在测试时(以及验证时)停用任何管道步骤很有用。请注意,通过这种方式,它不会在评估验证指标时进行数据过滤或重采样。
  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 已经过预处理,因此它是某种列表。

其他有用的代码参考: