【问题标题】:Sklearn: Text and Numeric features with ColumnTransformer has value errorSklearn:具有 ColumnTransformer 的文本和数字特征具有值错误
【发布时间】:2019-06-29 16:33:27
【问题描述】:

我正在尝试使用 SKLearn 0.20.2 来制作管道,同时使用新的 ColumnTransformer 功能。我的问题是,当我运行我的分类器时:clf.fit(x_train, y_train) 我不断收到错误消息:

ValueError: all the input array dimensions except for the concatenation axis must match exactly

我有一列名为text 的文本块。我所有的其他专栏本质上都是数字的。我正在尝试在我的管道中使用 Countvectorizer,我认为这就是问题所在。非常感谢您的帮助。

在我运行管道并检查我的 x_train/y_train 后,如果有帮助,它看起来像这样(省略通常显示在左列中的行号,并且文本列比图像中显示的要高)。


from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
# plus other necessary modules

# mapped to column names from dataframe
numeric_features = ['hasDate', 'iterationCount', 'hasItemNumber', 'isEpic']
numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median'))
])

# mapped to column names from dataframe
text_features = ['text']
text_transformer = Pipeline(steps=[
    ('vect', CountVectorizer())
])

preprocessor = ColumnTransformer(
    transformers=[('num', numeric_transformer, numeric_features),('text', text_transformer, text_features)]
)

clf = Pipeline(steps=[('preprocessor', preprocessor),
                      ('classifier', MultinomialNB())
                     ])

x_train, x_test, y_train, y_test = train_test_split(features, labels, test_size=0.33)
clf.fit(x_train,y_train)

【问题讨论】:

  • train_test_split 中的featureslabels 是什么? features.shapelabels.shape 的结果?

标签: python machine-learning scikit-learn


【解决方案1】:

如果您运行此代码,Vadim 是正确的

numeric_features = ['hasDate', 'iterationCount', 'hasItemNumber', 'isEpic']
numeric_transformer = SimpleImputer(strategy='median')

num = numeric_transformer.fit_transform(df[numeric_features])

# num.shape  
# (3, 4)

text_features = ['text']
text_transformer = CountVectorizer()

text = text_transformer.fit_transform(df[text_features])

print(text_transformer.get_feature_names())
print(text.toarray())

输出将如下所示。

['text']
[[1]]

这是由于我不止一次遇到的文本过程中的一些小故障。

如果您将 text_features 定义为字符串而不是单元素列表

text_features = 'text'
text_transformer = CountVectorizer()

text = text_transformer.fit_transform(df[text_features])

print(text_transformer.get_feature_names())
print(text.toarray())`

变成这样

['123', '16118', '17569', '456', '8779', '9480']
[[0 0 1 0 1 0]
[0 1 0 0 0 1]
[1 0 0 1 0 0]]

这就是你想要的。

将列名作为列表使 CountVectorizer 由于某种原因只能看到一项

【讨论】:

    【解决方案2】:

    如果您需要理解或调试代码,我想您不应该使用Pipeline。问题在于您的text_transformernumeric_transformer 的输出符合预期:

    # example
    df = pd.DataFrame([['(0,17569)\t1\n(0,8779)\t0\n', 1, 13, 1, 0],
                       ['(0,16118)\t1\n(0,9480)\t1\n', 1, None, 0, 1],
                       ['(0,123)\t1\n(0,456)\t1\n', 1, 15, 0, 0]],
                      columns=('text', 'hasDate', 'iterationCount', 'hasItemNumber', 'isEpic'))
    
    numeric_features = ['hasDate', 'iterationCount', 'hasItemNumber', 'isEpic']
    numeric_transformer = SimpleImputer(strategy='median')
    
    num = numeric_transformer.fit_transform(df[numeric_features])
    
    print(num)
    
    #[[ 1. 13.  1.  0.]
    # [ 1. 14.  0.  1.]
    # [ 1. 15.  0.  0.]]
    

    但是text_transformer 给你一个形状数组(1, 1)。所以,你需要弄清楚,你想如何转换你的text 列:

    text_features = ['text']
    text_transformer = CountVectorizer()
    
    text = text_transformer.fit_transform(df[text_features])
    
    print(text_transformer.get_feature_names())
    print(text.toarray())
    
    #['text']
    #[[1]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-30
      • 2019-04-19
      • 1970-01-01
      • 2017-12-11
      • 2019-10-21
      • 1970-01-01
      • 2016-09-12
      • 2011-09-08
      相关资源
      最近更新 更多