使用 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;它可能会起作用。
假设我有一个数据管道,它进行预处理并在最后有一个估算器。现在,如果我只想在管道的最后一步更改 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)
编辑:
当您关注问题中的模型,而
我的理解是只有拟合后的pipeline会被保存到缓存中,数据不会被保存,所以这个方案并没有达到只对数据进行一次预处理的目的。
我没能找到任何有助于数据缓存的 sklearn 功能。一个好的实现是分别缓存对 fit()
、transform()
和 fit_transform()
的每次调用的输出,以便每次访问相应的输出对象时读取底层数据缓存。
只有当输出对象是可迭代对象时,此实现才有意义,在这种情况下,每次调用 iter(cached_ouput)
都会打开 cached_output
的底层缓存文件以供读取。
我刚找到cachetools;它可能会起作用。