scikit klearn中的FeatureUnion和不兼容的行维度

时间:2016-07-19 10:48:27

标签: python scikit-learn pipeline feature-selection grid-search

我已经开始使用scikit学习文本提取。 当我在管道中使用标准函数CountVectorizer和TfidfTransformer时,当我尝试与新功能(矩阵的连接)结合时,我遇到了行维度问题。

这是我的管道:

pipeline = Pipeline([('feats', FeatureUnion([
('ngram_tfidf', Pipeline([('vect', CountVectorizer()),'tfidf', TfidfTransformer())])),
('addned', AddNed()),])), ('clf', SGDClassifier()),])

这是我的类AddNEd,它在每个文档(样本)上添加了30个新闻功能。

class AddNed(BaseEstimator, TransformerMixin):
def __init__(self):
    pass

def transform (self, X, **transform_params):
    do_something
    x_new_feat = np.array(list_feat)
    print(type(X))
    X_np = np.array(X)
    print(X_np.shape, x_new_feat.shape)
    return np.concatenate((X_np, x_new_feat), axis = 1)

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

我的主程序的第一部分

data = load_files('HO_without_tag')
grid_search = GridSearchCV(pipeline, parameters, n_jobs = 1, verbose = 20)
print(len(data.data), len(data.target))
grid_search.fit(X, Y).transform(X)

但我得到了这个结果:

486 486
Fitting 3 folds for each of 3456 candidates, totalling 10368 fits
[CV]feats__ngram_tfidf__vect__max_features=3000....
323
<class 'list'>
(323,) (486, 30)

当然还有Indexerror异常

return np.concatenate((X_np, x_new_feat), axis = 1)
IndexError: axis 1 out of bounds [0, 1

当我在变换函数(类AddNed)中使用参数X时,为什么我没有X的numpy数组(486,3000)形状。我只有(323,)形状。我不明白,因为如果删除Feature Union和AddNed()管道,CountVectorizer和tf_idf可以正确使用正确的功能和正确的形状。 如果有人有想法? 非常感谢。

2 个答案:

答案 0 :(得分:0)

好的,我会尝试提供更多解释。当我说do_something时,我说用X做do_nothing。 在AddNed类中,如果我重写:

def transform (self, X, **transform_params):
    print(X.shape)   #Print X shape on first line before do anything
    print(type(X))   #For information
    do_nothing_withX #Construct a new matrix with a shape (number of samples, 30 new features) 
    x_new_feat = np.array(list_feat) #Get my new matrix in numpy array 
    print(x_new_feat.shape) 
    return x_new_feat

在上面的这个转换情况中,我没有连接X矩阵和新矩阵。我假设功能联盟这样做...... 我的结果是:

486 486   #Here it is a print (data.data, data.target)
Fitting 3 folds for each of 3456 candidates, totalling 10368 fits
[CV] clf__alpha=1e-05, vect__max_df=0.1, clf__penalty=l2, feats__tfidf__use_idf=True, feats__tfidf__norm=l1, clf__loss=hinge, vect__ngram_range=(1, 1), clf__n_iter=10, vect__max_features=3000
(323, 3000) # X shape Matrix
<class 'scipy.sparse.csr.csr_matrix'>
(486, 30) # My new matrix shape
Traceback (most recent call last):
File "pipe_line_learning_union.py", line 134, in <module>
grid_search.fit(X, Y).transform(X)
.....
File "/data/maclearnVE/lib/python3.4/site-packages/scipy/sparse/construct.py", line 581, in bmat
raise ValueError('blocks[%d,:] has incompatible row dimensions' % i)
ValueError: blocks[0,:] has incompatible row dimensions

进一步说,如果我在gridsearchCV上进行交叉验证,只是为了修改样本量:

grid_search = GridSearchCV(pipeline, parameters, cv=2, n_jobs = 1, verbose = 20)

我有这个结果:

486 486
Fitting 2 folds for each of 3456 candidates, totalling 6912 fits
[CV] ......
(242, 3000) #This a new sample size due to cross validation
<class 'scipy.sparse.csr.csr_matrix'>
(486, 30)
..........
ValueError: blocks[0,:] has incompatible row dimensions

当然,如果有必要,我可以提供do_nothing_withX的所有代码。 但是我不明白,这就是为什么样本大小与管道countvectorizer + tdf_idf它不等于用sklearn.datasets.load_files()函数加载的文件数。

答案 1 :(得分:0)

你现在可能已经解决了这个问题,但其他人也可能遇到同样的问题:

(323, 3000) # X shape Matrix
<class 'scipy.sparse.csr.csr_matrix'>

AddNed尝试将矩阵与稀疏矩阵连接起来,稀疏矩阵应首先转换为到密集矩阵。 我发现尝试使用CountVectorizer

的结果时出现同样的错误