使用 scikit Pipeline 测试模型但仅预处理一次数据

Using scikit Pipeline for testing models but preprocessing data only once

假设我有一个数据管道,它进行预处理并在最后有一个估算器。现在,如果我只想在管道的最后一步更改 estimator/model,我该怎么做而不重新预处理相同的数据。下面是一个代码示例

pipe = make_pipeline(
    ColumnSelector(columns),
    CategoricalEncoder(categories),
    FunctionTransformer(pd.get_dummies, validate=False),
    StandardScaler(scale),
    LogisticRegression(),
)

现在我想更改模型以使用 Ridge 或除 LogisticRegression 之外的其他模型。如何在不重新进行预处理的情况下执行此操作?

编辑:我可以从以下类型的管道中获取转换后的数据吗

pipe = make_pipeline(
        ColumnSelector(columns),
        CategoricalEncoder(categories),
        FunctionTransformer(pd.get_dummies, validate=False),
        StandardScaler(scale)
    )

对于计算量大的转换器,可以使用caching。由于您没有提供转换器,这里是 link 中 sklearn 示例的扩展,其中两个模型使用缓存管道进行网格搜索:

from tempfile import mkdtemp
from shutil import rmtree
from sklearn.externals.joblib import Memory
from sklearn.pipeline import Pipeline
from sklearn.decomposition import PCA
from sklearn.svm import LinearSVC
from sklearn.linear_model import ElasticNet
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_digits

# Create a temporary folder to store the transformers of the pipeline
cachedir = mkdtemp()
memory = Memory(cachedir=cachedir, verbose=10)

# the pipeline
pipe = Pipeline([('reduce_dim', PCA()),
                ('classify', LinearSVC())],
                memory=memory)
# models to try
param_grid = {"classify" : [LinearSVC(), ElasticNet()]}

# do the gridsearch on the models
grid = GridSearchCV(pipe, param_grid=param_grid)
digits = load_digits()
grid.fit(digits.data, digits.target)

# delete the temporary cache before exiting
rmtree(cachedir)

编辑:

当您关注问题中的模型,而 关注参数时,我不会认为它是完全重复的。但是,根据您的具体问题,那里提出的解决方案与此处设置的 param_grid 相结合也是一个很好的,甚至可能是更好的解决方案。

我的理解是只有拟合后的pipeline会被保存到缓存中,数据不会被保存,所以这个方案并没有达到只对数据进行一次预处理的目的。

我没能找到任何有助于数据缓存的 sklearn 功能。一个好的实现是分别缓存对 fit()transform()fit_transform() 的每次调用的输出,以便每次访问相应的输出对象时读取底层数据缓存。

只有当输出对象是可迭代对象时,此实现才有意义,在这种情况下,每次调用 iter(cached_ouput) 都会打开 cached_output 的底层缓存文件以供读取。

我刚找到cachetools;它可能会起作用。