scikit-learn中’Pipeline’对象没有’get_feature_names’属性

我正在使用mini_batch_kmeans和kmeans算法对一些文档进行聚类。我只是按照scikit-learn网站上的教程进行操作,链接如下:http://scikit-learn.org/stable/auto_examples/text/document_clustering.html

他们使用了一些向量化方法,其中之一是HashingVectorizer。在HashingVectorizer中,他们使用TfidfTransformer()方法创建了一个管道。

# 对HashingVectorizer的输出进行IDF归一化hasher = HashingVectorizer(n_features=opts.n_features,                               stop_words='english', non_negative=True,                               norm=None, binary=False)vectorizer = make_pipeline(hasher, TfidfTransformer())

这样做之后,我得到的vectorizer没有get_feature_names()方法。但由于我使用它进行聚类,我需要使用这个“get_feature_names()”来获取“术语”。

terms = vectorizer.get_feature_names()for i in range(true_k):    print("Cluster %d:" % i, end='')    for ind in order_centroids[i, :10]:        print(' %s' % terms[ind], end='')    print()

我该如何解决这个错误?

我的完整代码如下所示:

X_train_vecs, vectorizer = vector_bow.count_tfidf_vectorizer(_contents)mini_kmeans_batch = MiniBatchKmeansTechnique()# 没有LSA降维的MiniBatchKmeansmini_kmeans_batch.mini_kmeans_technique(number_cluster=8, X_train_vecs=X_train_vecs,                                                vectorizer=vectorizer, filenames=_filenames, contents=_contents, is_dimension_reduced=False)

计数向量化器与tfidf结合使用。

def count_tfidf_vectorizer(self,contents):    count_vect = CountVectorizer()    vectorizer = make_pipeline(count_vect,TfidfTransformer())    X_train_vecs = vectorizer.fit_transform(contents)    print("The count of bow : ", X_train_vecs.shape)    return X_train_vecs, vectorizer

mini_batch_kmeans类如下所示:

class MiniBatchKmeansTechnique():    def mini_kmeans_technique(self, number_cluster, X_train_vecs, vectorizer,                              filenames, contents, svd=None, is_dimension_reduced=True):        km = MiniBatchKMeans(n_clusters=number_cluster, init='k-means++', max_iter=100, n_init=10,                         init_size=1000, batch_size=1000, verbose=True, random_state=42)        print("Clustering sparse data with %s" % km)        t0 = time()        km.fit(X_train_vecs)        print("done in %0.3fs" % (time() - t0))        print()        cluster_labels = km.labels_.tolist()        print("List of the cluster names is : ",cluster_labels)        data = {'filename':filenames, 'contents':contents, 'cluster_label':cluster_labels}        frame = pd.DataFrame(data=data, index=[cluster_labels], columns=['filename', 'contents', 'cluster_label'])        print(frame['cluster_label'].value_counts(sort=True,ascending=False))        print()        grouped = frame['cluster_label'].groupby(frame['cluster_label'])        print(grouped.mean())        print()        print("Top Terms Per Cluster :")        if is_dimension_reduced:            if svd != None:                original_space_centroids = svd.inverse_transform(km.cluster_centers_)                order_centroids = original_space_centroids.argsort()[:, ::-1]        else:            order_centroids = km.cluster_centers_.argsort()[:, ::-1]        terms = vectorizer.get_feature_names()        for i in range(number_cluster):            print("Cluster %d:" % i, end=' ')            for ind in order_centroids[i, :10]:                print(' %s' % terms[ind], end=',')            print()            print("Cluster %d filenames:" % i, end='')            for file in frame.ix[i]['filename'].values.tolist():                print(' %s,' % file, end='')            print()

回答:

Pipeline没有get_feature_names()方法,因为为Pipeline实现这个方法并不简单——需要考虑管道的所有步骤来获取特征名称。请参见https://github.com/scikit-learn/scikit-learn/issues/6424https://github.com/scikit-learn/scikit-learn/issues/6425等——有很多相关的工单和几次尝试修复它。

如果你的管道很简单(TfidfVectorizer后接MiniBatchKMeans),那么你可以从TfidfVectorizer中获取特征名称。

如果你想使用HashingVectorizer,情况会更复杂,因为HashingVectorizer设计上不提供特征名称。HashingVectorizer不存储词汇表,而是使用哈希值——这意味着它可以在线应用,并且不需要任何RAM——但权衡之处正是你无法获得特征名称。

尽管如此,还是有可能从HashingVectorizer中获取特征名称的;要做到这一点,你需要对一组文档应用它,存储哪些哈希值对应哪些单词,这样就可以了解这些哈希值的含义,即特征名称是什么。可能会有冲突,所以无法100%确定特征名称是正确的,但通常这种方法可以正常工作。这种方法在eli5库中实现;请参见http://eli5.readthedocs.io/en/latest/tutorials/sklearn-text.html#debugging-hashingvectorizer以获取示例。你将不得不做类似的事情,使用InvertableHashingVectorizer

from eli5.sklearn import InvertableHashingVectorizerivec = InvertableHashingVectorizer(vec)  # vec是一个HashingVectorizer实例# X_sample是从contents中抽取的样本;你可以使用整个contents数组,或者例如每10个元素抽取一个ivec.fit(content_sample)  hashing_feat_names = ivec.get_feature_names()

然后你可以使用hashing_feat_names作为你的特征名称,因为TfidfTransformer不会改变输入向量的大小,只是对相同的特征进行缩放。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注