【问题标题】:Cache only a single step in sklearn's Pipeline在 sklearn 的 Pipeline 中只缓存一个步骤
【发布时间】:2021-09-16 15:44:13
【问题描述】:

我想在我的 sklearn 管道中使用 UMAP,并且我想缓存该步骤以加快速度。但是,由于我有自定义 Transformer,the suggested method 不起作用。

示例代码:

from sklearn.preprocessing import FunctionTransformer
from tempfile import mkdtemp
from sklearn.pipeline import Pipeline
from umap import UMAP
from hdbscan import HDBSCAN
import seaborn as sns

iris = sns.load_dataset("iris")
X = iris.drop(columns='species')
y = iris.species

@FunctionTransformer
def transform_something(iris):
    iris = iris.copy()
    iris['sepal_sum'] = iris.sepal_length + iris.sepal_width
    return iris

cachedir = mkdtemp()
pipe = Pipeline([
                 ('transformer', transform_something),
                 ('umap', UMAP()),
                 ('hdb', HDBSCAN()),
                ],
                memory=cachedir
            )

pipe.fit_predict(X)

如果你运行这个,你会得到一个PicklingError,说它不能腌制自定义转换器。但我只需要缓存 UMAP 步骤。有什么建议可以让它发挥作用吗?

【问题讨论】:

标签: python scikit-learn pickle


【解决方案1】:

不是最干净的,但你可以嵌套管道?

pipe = Pipeline(
    [
        ('transformer', transform_something),
        ('the_rest', Pipeline([
            ('umap', UMAP()),
            ('hdb', HDBSCAN()),
        ], memory=cachedir))
    ]
)

【讨论】:

  • 虽然不是一个理想的解决方案,但它确实有效!干杯:)
【解决方案2】:

同样有效的是,不要使用FunctionTransformer,而是像这样从头开始编写自定义转换函数:

from sklearn.base import BaseEstimator, TransformerMixin

class transform_something(BaseEstimator, TransformerMixin):
    def __init__(self):
        pass
        
    def fit(self, X):
        return self

    def transform(self, X):
        X = X.copy()
        X['sepal_sum'] = X.sepal_length + X.sepal_width
        return X

不幸的是,它的代码有点多,但它是可腌制的。

【讨论】:

    猜你喜欢
    • 2019-06-17
    • 2021-01-23
    • 1970-01-01
    • 2019-10-05
    • 2021-08-29
    • 1970-01-01
    • 2019-08-02
    • 2022-09-28
    • 2016-07-15
    相关资源
    最近更新 更多