如何使TF-IDF矩阵变得密集?

17

我正在使用TfidfVectorizer将一组原始文档转换为TF-IDF特征矩阵,然后计划将其输入到K均值算法中(我将实现该算法)。在该算法中,我需要计算质心(文章类别)和数据点(文章)之间的距离。我将使用欧几里得距离,因此这两个实体需要具有相同的维度,在我的情况下是 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'>

你能打印出 type(X) 吗? - Will
非常乐意,@Will,我更新了我的问题。 - gsamaras
1个回答

19

这应该就像这样简单:

dense = X.toarray()

TfIdfVectorizer.fit_transform() 返回一个 SciPy 的 csr_matrix() 对象(压缩稀疏行矩阵),该对象有一个toarray()方法可以用于此目的。在 SciPy 中,有几种稀疏矩阵格式,但它们都支持 .toarray() 方法。

需要注意的是,对于大型矩阵,相比于稀疏矩阵,这会使用大量内存,因此通常最好尽可能保持其稀疏。


1
那么也许我应该保持它的稀疏性,并修改我的距离函数,在没有条目时放置0,但我不确定如何做到这一点,我将首先使用密集格式实际实现k-means算法! - gsamaras
1
是的,对于更大的数据集,尽可能保持稀疏状态是必要的。在您尝试迭代稀疏矩阵中的行时,可以尝试一些这里的方法。您可以对它们进行迭代,但是您需要某种返回未填充行/单元格的“0”的生成器。 - Will
1
@gsamaras 不要期望在这种数据上使用 k-means 能得到好的结果。(你可以在稀疏数据上运行 k-means) - Has QUIT--Anony-Mousse
@Anony-Mousse,那主要是为了感受Hadoop,所以我知道。:/ 谢谢Will! - gsamaras
1
@Will 你说得没错,对于大矩阵,稀疏矩阵是最好的选择。然而,我正在尝试使用亲和传播算法进行聚类,如果我提供稀疏矩阵,它会抛出一个错误,因此我不得不使用toarray()函数,但主要问题是它使用了大量的内存,并且会导致我的进程停止运行。我该如何解决这些问题? - Nitesh kumar

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