Sklearn FeatureUnion возвращает TypeError: не поддерживается преобразование для типов: (dtype ('int64'), dtype ('O')) - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь объединить два конвейера:

  • pipe_1 возвращает разреженную матрицу с плавающей точкой64
  • pipeline_2 возвращает исходный столбец (str) в виде pandas DataFrame (Ряд не приведет к ошибке ValueError: blocks [0 ,:] имеет несовместимые размеры строк. )

При этом я получаю сообщение об ошибке:

Ошибка типа: нет поддерживаемого преобразования для типов: (dtype ('int64'), dtype ('O'))

Моя цель - найти обобщенный способ сохранить исходный столбец DataFrame в конвейере для последующего использования классификаторами.

Код:

import pandas as pd

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.pipeline import Pipeline, FeatureUnion


class ColumnSelector(BaseEstimator, TransformerMixin):

    def __init__(self, key, transform_function=None):
        self.key = key
        self.transform_function = transform_function

    def fit(self, X, y=None, *parg, **kwarg):
        return self

    def transform(self, X):
        result = X[self.key]
        if self.transform_function:
            result = self.transform_function(result)
        return result


data = [
    {'col1': 'hello my friend', 'col2': 'somestring_'},
    {'col1': 'my friend', 'col2': 'somestring__'},
    {'col1': 'hello friend', 'col2': 'somestring___'}
]
df = pd.DataFrame(data)



pipeline_1 = Pipeline([
    ('selector', ColumnSelector(key='col1')),
    ('vectorizer', CountVectorizer())
])

pipeline_2 = Pipeline([
    ('test', ColumnSelector(key='col2'))#, transform_function=lambda col: col.to_frame())),
])

feats = FeatureUnion([('count_vectorize', pipeline_1), ('original_column', pipeline_2)])

feats.fit_transform(df)

1 Ответ

0 голосов
/ 05 мая 2020

FeatureUnion использует операцию numpy или scipy разреженную, чтобы объединить выходные данные каждой функции в нем. Следовательно, вы не можете иметь никакого шага в FeatureUnion, который может возвращать нечисловые значения.

Если я изменю ваш pipeline2, чтобы он возвращал количество символов в данной строке, он начнет работать.

Примечание: вы можете использовать ColumnTransformer из sklearn.compose.

import pandas as pd

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.pipeline import Pipeline, FeatureUnion


class ColumnSelector(BaseEstimator, TransformerMixin):

    def __init__(self, key, transform_function=None):
        self.key = key
        self.transform_function = transform_function

    def fit(self, X, y=None, *parg, **kwarg):
        return self

    def transform(self, X):
        result = X[self.key]
        if self.transform_function:
            result = self.transform_function(result)
        return result


data = [
    {'col1': 'hello my friend', 'col2': 'somestring_'},
    {'col1': 'my friend', 'col2': 'somestring__'},
    {'col1': 'hello friend', 'col2': 'somestring___'}
]
df = pd.DataFrame(data)



pipeline_1 = Pipeline([
    ('selector', ColumnSelector(key='col1')),
    ('vectorizer', CountVectorizer())
])

pipeline_2 = Pipeline([
    ('test', ColumnSelector(key='col2',transform_function=lambda x: [[len(i)] for i in x]))#, transform_function=lambda col: col.to_frame())),
])

feats = FeatureUnion([('count_vectorize', pipeline_1), ('original_column', pipeline_2)])

feats.fit_transform(df)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...