Я построил пользовательский конвейер sklearn следующим образом:
pipeline = make_pipeline(
SelectColumnsTransfomer(features_to_use),
ToDummiesTransformer('feature_0', prefix='feat_0', drop_first=True, dtype=bool), # Dummify customer_type
ToDummiesTransformer('feature_1', prefix='feat_1'), # Dummify the feature
ToDummiesTransformer('feature_2', prefix='feat_2'), # Dummify
ToDummiesTransformer('feature_3', prefix='feat_3'), # Dummify
)
pipeline.fit(df)
Классы SelectColumnsTransfomer
и ToDummiesTransformer
являются пользовательскими шагами sklearn, реализующими BaseEstimator
и TransformerMixin
.
Для сериализации этого объекта я использую
from sklearn.externals import joblib
joblib.dump(pipeline, 'data_pipeline.joblib')
но когда я делаю десериализацию с
pipeline = joblib.load('data_pipeline.joblib')
Я получаю AttributeError: module '__main__' has no attribute 'SelectColumnsTransfomer'
.
Я прочитал другие подобные вопросы и следовал инструкции в этом посте здесь , но не смог решить проблему.
Я копирую вставки классов и импортирую их в код. Если я создаю упрощенную версию этого упражнения, все работает, проблема возникает из-за того, что я запускаю некоторые тесты с pytest, и когда я запускаю pytest, кажется, что он не видит мои пользовательские классы, фактически есть другая часть ошибки
self = <sklearn.externals.joblib.numpy_pickle.NumpyUnpickler object at 0x7f821508a588>, module = '__main__', name = 'SelectColumnsTransfomer'
, который намекает мне на то, что NumpyUnpickler
не видит SelectColumnsTransfomer
, даже если в тесте он импортирован.
Мой тестовый код
import pytest
from app.pipeline import * # the pipeline objects
# SelectColumnsTransfomer and ToDummiesTransformer
# are here!
@pytest.fixture(scope="module")
def clf():
pipeline = joblib.load("persistence/data_pipeline.joblib")
return clf
def test_fake(clf):
assert True