scikit klearn 中的 FeatureUnion 和不兼容的行维度
Posted
技术标签:
【中文标题】scikit klearn 中的 FeatureUnion 和不兼容的行维度【英文标题】:FeatureUnion in scikit klearn and incompatible row dimension 【发布时间】:2016-11-22 05:18:51 【问题描述】:我已经开始使用 scikit learn 进行文本提取。 当我在管道中使用标准函数 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 可以使用正确的功能和正确的形状正常工作。 如果有人有想法? 非常感谢。
【问题讨论】:
您不能删除管道中的行,因为您的转换只影响X
,而不影响y
。
对不起,也许我错过了一些东西,但我没有删除行......我想。我想将具有新功能的 (486, 30) 新矩阵 (AddNed Pipeline) 添加到 (486,3000) 矩阵 (Pipeline count vectorizer+tdf_idf)。问题是我加载 (load_files) 486 个文件,我将它们处理为 (vectorizer + tdf_idf) 但我没有 486 个样本(只有 323 个)。
我不明白发生了什么,尤其是在do_something
。如果您可以创建一个可重现的示例,我相信我们可以提供帮助。
【参考方案1】:
你现在可能已经解决了,但其他人可能有同样的问题:
(323, 3000) # X shape Matrix
<class 'scipy.sparse.csr.csr_matrix'>
AddNed
尝试将一个矩阵与一个稀疏矩阵连接起来,稀疏矩阵应该首先被转换为密集矩阵。
我在尝试使用 CountVectorizer
的结果时发现了同样的错误
【讨论】:
【参考方案2】:好的,我会尝试给出更多解释。当我说 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的所有代码。 但我不明白,这就是为什么管道计数向量器+tdf_idf 的样本大小不等于使用 sklearn.datasets.load_files() 函数加载的文件数。
【讨论】:
以上是关于scikit klearn 中的 FeatureUnion 和不兼容的行维度的主要内容,如果未能解决你的问题,请参考以下文章
吴裕雄 python 机器学习——人工神经网络感知机学习算法的应用