如何使 TF-IDF 矩阵密集?

Posted

技术标签:

【中文标题】如何使 TF-IDF 矩阵密集?【英文标题】:How to make TF-IDF matrix dense? 【发布时间】:2016-05-08 15:47:50 【问题描述】:

我正在使用TfidfVectorizer 将原始文档集合转换为 TF-IDF 特征矩阵,然后我计划将其输入到 k-means 算法(我将实现)。在该算法中,我将不得不计算质心(文章类别)和数据点(文章)之间的距离。我将使用欧几里得距离,所以我需要这两个实体具有相同的维度,在我的情况下为max_features。这是我所拥有的:

tfidf = TfidfVectorizer(max_features=10, strip_accents='unicode', analyzer='word', stop_words=stop_words.extra_stopwords, lowercase=True, use_idf=True)
X = tfidf.fit_transform(data['Content']) # the matrix articles x max_features(=words)
for i, row in enumerate(X):
    print X[i]

但是X 似乎是一个稀疏(?)矩阵,因为输出是:

  (0, 9)    0.723131915847
  (0, 8)    0.090245047798
  (0, 6)    0.117465276892
  (0, 4)    0.379981697363
  (0, 3)    0.235921470645
  (0, 2)    0.0968780456528
  (0, 1)    0.495689001273

  (0, 9)    0.624910843051
  (0, 8)    0.545911131362
  (0, 7)    0.160545991411
  (0, 5)    0.49900042174
  (0, 4)    0.191549050212

  ...

我认为(0, col) 表示矩阵中的列索引,它实际上就像一个数组,其中每个单元格都指向一个列表。

如何将此矩阵转换为密集矩阵(以便每一行具有相同的列数)?


>print type(X)
<class 'scipy.sparse.csr.csr_matrix'>

【问题讨论】:

你能print type(X)吗? 很高兴@Will,我更新了我的问题。 【参考方案1】:

这应该很简单:

dense = X.toarray()

TfIdfVectorizer.fit_transform() 正在返回一个 SciPy csr_matrix()(压缩稀疏行矩阵),它有一个专门用于此目的的 toarray() 方法。 SciPy 中有多种格式的稀疏矩阵,但它们都有一个.toarray() 方法。

请注意,对于大型矩阵,与稀疏矩阵相比,这将使用大量内存,因此通常尽可能长时间保持稀疏是一个好方法。

【讨论】:

那么也许我应该让它稀疏并在没有条目时将我的距离函数更改为 0,但我不知道该怎么做,我将使用密集格式来实际实现 k -表示算法优先! 是的,对于更大的数据集,您需要尽可能保持稀疏。在您尝试遍历稀疏矩阵中的行的示例中,请尝试一些方法here。您可以迭代它们,但您只需要某种类型的生成器,它为未填充的行/单元格返回 0s。 @gsamaras 不期望 k-means 对此类数据有好的结果。 (您可以在稀疏数据上运行 k-means) @Anony-Mousse,这主要是为了了解 Hadoop,所以是的,我知道。 :/ 谢谢威尔! @Will 你说得对,Will,对于大型矩阵备件矩阵是最好的。但是,我试图使用亲和传播进行聚类,如果我提供备用矩阵,它会引发错误,因此我不得不使用 toarray(),但主要问题是它使用了大量 RAM 并杀死了我的进程。我该如何克服这些问题?

以上是关于如何使 TF-IDF 矩阵密集?的主要内容,如果未能解决你的问题,请参考以下文章

如何标准化 SVM 的 tf-idf 向量?

将 tf-idf 值添加为矩阵中的列

K- 表示为 tf-idf 矩阵定义初始中心

如何让TF-IDF学习具有更高优先级的文档的一部分?

基于TF-IDF编码进行文本聚类分析:文档成对相似性计算层次聚类(链接矩阵树形图dendrogram绘制聚类标签)

TF-IDF 简单使用 - NLTK/Scikit 学习