【问题标题】:Sklearn Pipeline all the input array dimensions for the concatenation axis must match exactlySklearn Pipeline 连接轴的所有输入数组维度必须完全匹配
【发布时间】:2020-07-25 12:00:15
【问题描述】:
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.pipeline import Pipeline
from sklearn.svm import LinearSVC
from sklearn.preprocessing import MinMaxScaler
from sklearn.compose import ColumnTransformer

data = [[1, 3, 4, 'text', 'pos'], [9, 3, 6, 'text more', 'neg']]
data = pd.DataFrame(data, columns=['Num1', 'Num2', 'Num3', 'Text field', 'Class'])

tweet_text_transformer = Pipeline(steps=[
    ('count_vectoriser', CountVectorizer()),
    ('tfidf', TfidfTransformer())
])

numeric_transformer = Pipeline(steps=[
    ('scaler', MinMaxScaler())
])

preprocessor = ColumnTransformer(transformers=[
    # (name, transformer, column(s))
    ('tweet', tweet_text_transformer, ['Text field']),
    ('numeric', numeric_transformer, ['Num1', 'Num2', 'Num3'])
])

pipeline = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('classifier', LinearSVC())
])

X_train = data.loc[:, 'Num1':'Text field']
y_train = data['Class']
pipeline.fit(X_train, y_train)

我不明白这个错误来自哪里:

ValueError:连接轴的所有输入数组维度必须完全匹配,但沿维度 0,索引 0 处的数组大小为 1,索引 1 处的数组大小为 2

【问题讨论】:

  • 请提供完整的错误输出。
  • 我有这个完全相同的错误。你有想过吗?

标签: python scikit-learn


【解决方案1】:

原因

问题出在preprocessor 管道中,该管道的工作方式是tweet_text_transformer 的输出和numeric_transformer 的输出水平堆叠,要成功实现这一点,输出(tweet_text_transformer 和 numeric_transformer)必须具有相同的行数(即:轴 0 或维度 0 中的元素数)

但是当上面的流水线执行tweet_text_processor时,虽然我们期望它在现实中给出具有4个元素的2 * 2矩阵,因为CountVectorizer将输出存储为稀疏矩阵,它会删除矩阵中的所有零(以节省内存)这将数组减少到 2*2 矩阵,但其中只有 3 个元素,当它与 numeric_transformer 的输出堆叠时,它不满足上述条件(因为数字转换器将在轴 0 中有两个元素,而 twwet_text_processor 将不是)

Output of the explination

解决方案

  • 创建一个自定义转换器,将这个稀疏矩阵转换为 numpy 数组
  • 此外,由于只有一列,因此请压缩 Pandas 数据框以将其转换为 Panadas 系列
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.pipeline import Pipeline
from sklearn.svm import LinearSVC
from sklearn.preprocessing import MinMaxScaler
from sklearn.compose import ColumnTransformer

data = [[1, 3, 4, 'text', 'pos'], [9, 3, 6, 'text more', 'neg']]
data = pd.DataFrame(data, columns=['Num1', 'Num2', 'Num3', 'Text field', 'Class'])



class TweetTextProcessor(BaseEstimator, TransformerMixin):
    def __init__(self):
        self.tweet_text_transformer = Pipeline(steps=[
        ('count_vectoriser', CountVectorizer()),
        ('tfidf', TfidfTransformer())    ])
       
        
    def fit(self, X, y=None):
        return self

    def transform(self, X, y=None):
       
        return  self.tweet_text_transformer.fit_transform(X.squeeze()).toarray()
        




numeric_transformer = Pipeline(steps=[
    ('scaler', MinMaxScaler())
])

preprocessor = ColumnTransformer(transformers=[
    ('tweet', TweetTextProcessor(), ['Text field']),
    ('numeric', numeric_transformer, ['Num1', 'Num2', 'Num3'])
])

pipeline = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('classifier', LinearSVC())
])

X_train = data.loc[:, 'Num1':'Text field']
y_train = data['Class']
pipeline.fit(X_train, y_train)

上面的代码应该可以工作,否则请告诉我,或者如果解释不清楚(希望是这样)

【讨论】:

    猜你喜欢
    • 2021-05-09
    • 2020-02-19
    • 2018-07-08
    • 2017-10-20
    • 1970-01-01
    • 2019-05-16
    • 2017-11-26
    • 2020-02-03
    • 2020-08-02
    相关资源
    最近更新 更多