Большое спасибо за детали!

аюсь впервые использовать featureunion в конвейере sklearn, чтобы объединить числовые (2 столбца) и текстовые (1 столбец) для классификации нескольких классов.

from sklearn.preprocessing import FunctionTransformer
from sklearn.pipeline import Pipeline
from sklearn.multiclass import OneVsRestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import FeatureUnion

get_text_data = FunctionTransformer(lambda x: x['text'], validate=False)
get_numeric_data = FunctionTransformer(lambda x: x[['num1','num2']], validate=False)

process_and_join_features = FeatureUnion(
         [
            ('numeric_features', Pipeline([
                ('selector', get_numeric_data),
                ('clf', OneVsRestClassifier(LogisticRegression()))
            ])),
             ('text_features', Pipeline([
                ('selector', get_text_data),
                ('vec', CountVectorizer()),
                ('clf', OneVsRestClassifier(LogisticRegression()))
            ]))
         ]
    )

В этом коде «текст» - это текстовые столбцы, а «num1», «num2» - это два числовых столбца.

Сообщение об ошибке

TypeError: All estimators should implement fit and transform. 'Pipeline(memory=None,
 steps=[('selector', FunctionTransformer(accept_sparse=False,
      func=<function <lambda> at 0x7fefa8efd840>, inv_kw_args=None,
      inverse_func=None, kw_args=None, pass_y='deprecated',
      validate=False)), ('clf', OneVsRestClassifier(estimator=LogisticRegression(C=1.0, class_weigh...=None, solver='liblinear', tol=0.0001,
      verbose=0, warm_start=False),
      n_jobs=1))])' (type <class 'sklearn.pipeline.Pipeline'>) doesn't

Любой шаг, который я пропустил?

 Vivek Kumar11 дек. 2017 г., 03:09
Во-первых, ваш'clf', OneVsRestClassifier(LogisticRegression() должен быть третьим шагом в конвейере, а не объединяться на втором этапе с текстом. Во-вторых, пожалуйста, поделитесь некоторыми примерами данных и полной трассировкой стека ошибок. Вы вызываете fit () или предсказывать () на конвейере?
 santoku11 дек. 2017 г., 14:43
спасибо, теперь все понятно

Ответы на вопрос(2)

что @Ken Syme правильно определил проблему и предоставил исправление для того, что вы намерены делать. Однако на тот случай, если вы действительно собираетесь использовать выходные данные классификатора в качестве функции для модели более высокого уровня, ознакомьтесь сэтот блог.

Используя ModelTransformer от Zac, вы можете получить свою трубу следующим образом:

class ModelTransformer(TransformerMixin):

    def __init__(self, model):
        self.model = model

    def fit(self, *args, **kwargs):
        self.model.fit(*args, **kwargs)
        return self

    def transform(self, X, **transform_params):
        return DataFrame(self.model.predict(X))


process_and_join_features = FeatureUnion(
         [
            ('numeric_features', Pipeline([
                ('selector', get_numeric_data),
                ('clf', ModelTransformer(OneVsRestClassifier(LogisticRegression())))
            ])),
             ('text_features', Pipeline([
                ('selector', get_text_data),
                ('vec', CountVectorizer()),
                ('clf', ModelTransformer(OneVsRestClassifier(LogisticRegression())))
            ]))
         ]
)

В зависимости от ваших конкретных следующих шагов вам все еще может понадобиться обернуть FeatureUnion в конвейер (например, с помощью ярлыкаmake_pipeline).

 santoku11 дек. 2017 г., 14:43
Большое спасибо за детали!
 Ken Syme11 дек. 2017 г., 12:21
Хорошая альтернатива!
Решение Вопроса

FeatureUnion следует использовать в качестве шага в конвейере, а не вокруг конвейера. Ошибка, которую вы получаете, заключается в том, что у вас не последний классификатор, а классификатор, который пытается вызватьfit а такжеtransform на всех трансформаторах и классификаторе нетtransform метод.

Просто переделайте, чтобы получить внешний конвейер с классификатором в качестве последнего шага:

process_and_join_features = Pipeline([
    ('features', FeatureUnion([
            ('numeric_features', Pipeline([
                ('selector', get_numeric_data)
            ])),
             ('text_features', Pipeline([
                ('selector', get_text_data),
                ('vec', CountVectorizer())
            ]))
         ])),
    ('clf', OneVsRestClassifier(LogisticRegression()))
])

Также смВот хороший пример на сайте scikit-learn, делающего подобные вещи.

 Marcus V.11 дек. 2017 г., 16:54
Если это не так, все равно читайте Закблог, Это помогло мне понять конвейеры. Блок-схемы довольно ясно показывают, как работают FeatureUnion и Pipeline. На самом деле, я иногда рисую похожие, если мои трубы слишком сложны.
 santoku11 дек. 2017 г., 14:42
спасибо за ваше простое и понятное объяснение! это работает сейчас

Ваш ответ на вопрос