如何使用sklearn正确地混合特征稀疏矩阵?

5
前几天,我正在处理一个需要提取多种类型特征矩阵的机器学习任务。我将这些特征矩阵保存为numpy数组以便稍后在某个估算器中使用它们(这是一个分类任务)。最终,当我想要使用所有特征时,我只需将这些矩阵连接起来以获得一个大的特征矩阵。当我获得这个大的特征矩阵后,我将其呈现给了一个估算器。
我不知道是否这是正确处理具有许多模式(计数)的特征矩阵的方法。还有哪些其他方法可以正确混合多种类型的特征?然而,查看文档,我发现FeatureUnion似乎可以做到这一点。
例如,假设我想创建一个由3种矢量化方法TfidfVectorizerCountVectorizerHashingVectorizer组成的大型特征矩阵,这就是我根据文档示例尝试的内容:
#Read the .csv file
import pandas as pd
df = pd.read_csv('file.csv',
                     header=0, sep=',', names=['id', 'text', 'labels'])

#vectorizer 1
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vect = TfidfVectorizer(use_idf=True, smooth_idf=True,
                             sublinear_tf=False, ngram_range=(2,2))
#vectorizer 2
from sklearn.feature_extraction.text import CountVectorizer
bow = CountVectorizer(ngram_range=(2,2))

#vectorizer 3
from sklearn.feature_extraction.text import HashingVectorizer
hash_vect = HashingVectorizer(ngram_range=(2,2))


#Combine the above vectorizers in one single feature matrix:

from sklearn.pipeline import  FeatureUnion
combined_features = FeatureUnion([("tfidf_vect", tfidf_vect),
                                  ("bow", bow),
                                  ("hash",hash_vect)])

X_combined_features = combined_features.fit_transform(df['text'].values)
y = df['labels'].values

#Check the matrix
print X_combined_features.toarray()

然后:

[[ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 ..., 
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]]

拆分数据:

from sklearn import cross_validation
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X_combined_features,y, test_size=0.33)

我有几个问题: 将几个特征提取器混合以产生大的特征矩阵是正确的方法吗?并且假设我创建了自己的“向量化器”,它们返回稀疏矩阵,如何正确地使用FeatureUnion接口将它们与上述3个特征混合? 更新: 假设我有一个像这样的矩阵: 矩阵A((152,33))
[[ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 ..., 
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]
 [ 0.  0.  0. ...,  0.  0.  0.]]

使用我的向量化器,它返回一个numpy array,我得到了这个特征矩阵:
矩阵 B ((152, 10))
[[4210  228   25 ...,    0    0    0]
 [4490  180   96 ...,   10    4    6]
 [4795  139    8 ...,    0    0    1]
 ..., 
 [1475   58    3 ...,    0    0    0]
 [4668  256   25 ...,    0    0    0]
 [1955  111   10 ...,    0    0    0]]

矩阵 C ((152, 46))

[[ 0  0  0 ...,  0  0  0]
 [ 0  0  0 ...,  0  0 17]
 [ 0  0  0 ...,  0  0  0]
 ..., 
 [ 0  0  0 ...,  0  0  0]
 [ 0  0  0 ...,  0  0  0]
 [ 0  0  0 ...,  0  0  0]]

我该如何使用 numpy.hstackscipy.sparse.hstack 或者 FeatureUnion 正确地合并 A、B 和 C?你们认为这是一种适用于任何机器学习任务的正确流程吗?
1个回答

6
这是混合多个特征提取器以产生大型特征矩阵的正确方法吗?
就结果的正确性而言,您的方法是正确的,因为 FeatureUnion 在输入数据上运行每个单独的转换器,并水平连接生成的矩阵。但是,这不是唯一的方法,哪种方法在效率方面更好将取决于您的使用情况(稍后会更详细地介绍)。
假设我创建了自己的“向量化器”,它们返回稀疏矩阵,如何正确使用FeatureUnion接口将它们与以上3个特征混合?
使用 FeatureUnion ,您只需要将新的转换器附加到转换器列表中:
custom_vect = YourCustomVectorizer()
combined_features = FeatureUnion([("tfidf_vect", tfidf_vect),
                                  ("bow", bow),
                                  ("hash", hash_vect),
                                  ("custom", custom_vect])

然而,如果您的输入数据和大多数转换器都是固定的(例如,当您尝试包含新转换器时),上述方法会导致多次重新计算。在这种情况下,另一种替代方法是预先计算转换器的中间结果(矩阵或稀疏矩阵)并手动使用 numpy.hstackscipy.sparse.hstack 进行连接。

如果您的输入数据始终在变化,但转换器列表固定,则 FeatureUnion 提供更多方便。它的另一个优点是它有 n_jobs 选项,可以帮助您并行化拟合过程。


顺便说一下:混合哈希向量化器与其他向量化器似乎有点奇怪,因为哈希向量化器通常用于不能使用精确版本时。


谢谢你的帮助。我想到一个问题是维度怎么处理?如何合并矩阵并注意它们的维度? - tumbleweed
1
你能详细解释一下你所说的“照顾”维度是什么意思吗?使用适当的numpy/scipy堆叠函数,合并后的维度(X.shape[1])是各个特征矩阵维度的总和。 - YS-L
感谢支持,我已经添加了一个示例并修改了问题。 - tumbleweed
1
我认为你必须在FeatureUnionhstack之间做出选择。实际上,hstack方法与您手动执行FeatureUnion的工作相同。请选择其中一个,而不是两个都使用。 - YS-L
最后,您能否提供一个示例,以便更好地了解这个问题?感谢您的帮助! - tumbleweed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接