无法在scikit-learn中使用FeatureUnion因为维度不同

14 投票
2 回答
6615 浏览
提问于 2025-04-21 04:31

我正在尝试使用 FeatureUnion 从一个数据结构中提取不同的特征,但因为维度不匹配而失败了,出现了这个错误:ValueError: blocks[0,:] has incompatible row dimensions


实现方式

我的 FeatureUnion 是这样构建的:

    features = FeatureUnion([
        ('f1', Pipeline([
            ('get', GetItemTransformer('f1')),
            ('transform', vectorizer_f1)
        ])),
        ('f2', Pipeline([
            ('get', GetItemTransformer('f2')),
            ('transform', vectorizer_f1)
        ]))
    ])

GetItemTransformer 用来从同一个数据结构中提取不同部分的数据。这个想法在 这里 的 scikit-learn 问题追踪器中有描述。

这个数据结构本身是以 {'f1': data_f1, 'f2': data_f2} 的形式存储的,其中 data_f1 是不同长度的不同列表。


问题

因为 Y 向量和数据字段不同,我猜测错误是由此引起的,但我该如何调整这个向量,使它在两种情况下都能适用呢?

2 个回答

3

我不知道这是否适合你的问题,但我们在稍微不同的情况下遇到了同样的错误,并且刚刚解决了它。

我们的 f1 是每个包含15个数字的列表,而我们需要对 f2 进行tf-idf处理。这导致了同样的错误,提示行的维度不兼容。

在用调试工具检查后,我们发现进入 hstack() 调用的矩阵形状有些微妙的不同:一个是 (2569,),另一个是 (2659, 706)

如果我们把 f1 转换成一个二维的numpy数组,形状就变成了 (2659, 15),这样 hstack 调用就能正常工作了。

这个转换大概是这样的: f1 = np.array(list(f1))

7

这是我找到的有效方法:

class ArrayCaster(BaseEstimator, TransformerMixin):
  def fit(self, x, y=None):
    return self

  def transform(self, data):
    print data.shape
    print np.transpose(np.matrix(data)).shape
    return np.transpose(np.matrix(data))

FeatureUnion([('text', Pipeline([
            ('selector', ItemSelector(key='text')),
            ('vect', CountVectorizer(ngram_range=(1,1), binary=True, min_df=3)),
            ('tfidf', TfidfTransformer())
          ])
        ),

        ('other data', Pipeline([
            ('selector', ItemSelector(key='has_foriegn_char')),
            ('caster', ArrayCaster())
          ])
        )])

撰写回答