【问题标题】:Clustering of sparse matrix in python and scipypython和scipy中稀疏矩阵的聚类
【发布时间】:2012-05-23 10:47:58
【问题描述】:

我正在尝试使用 python 和 scipy 对一些数据进行聚类,但由于我不明白的原因,以下代码不起作用:

from scipy.sparse import *
matrix = dok_matrix((en,en), int)

for pub in pubs:
    authors = pub.split(";")
    for auth1 in authors:
        for auth2 in authors:
            if auth1 == auth2: continue
            id1 = e2id[auth1]
            id2 = e2id[auth2]
            matrix[id1, id2] += 1

from scipy.cluster.vq import vq, kmeans2, whiten
result = kmeans2(matrix, 30)
print result

上面写着:

Traceback (most recent call last):
  File "cluster.py", line 40, in <module>
    result = kmeans2(matrix, 30)
  File "/usr/lib/python2.7/dist-packages/scipy/cluster/vq.py", line 683, in kmeans2
    clusters = init(data, k)
  File "/usr/lib/python2.7/dist-packages/scipy/cluster/vq.py", line 576, in _krandinit
    return init_rankn(data)
  File "/usr/lib/python2.7/dist-packages/scipy/cluster/vq.py", line 563, in init_rankn
    mu  = np.mean(data, 0)
  File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line 2374, in mean
    return mean(axis, dtype, out)
TypeError: mean() takes at most 2 arguments (4 given)

当我使用 kmenas 而不是 kmenas2 时,出现以下错误:

Traceback (most recent call last):
  File "cluster.py", line 40, in <module>
    result = kmeans(matrix, 30)
  File "/usr/lib/python2.7/dist-packages/scipy/cluster/vq.py", line 507, in kmeans
    guess = take(obs, randint(0, No, k), 0)
  File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line 103, in take
    return take(indices, axis, out, mode)
TypeError: take() takes at most 3 arguments (5 given)

我认为我遇到了问题,因为我使用的是稀疏矩阵,但我的矩阵太大而无法容纳内存。有没有办法使用来自 scipy 的标准聚类算法和稀疏矩阵?还是我必须自己重新实现它们?

我创建了一个新版本的代码来处理向量空间

el = len(experts)
pl = len(pubs)
print el, pl

from scipy.sparse import *
P = dok_matrix((pl, el), int)

p_id = 0
for pub in pubs:
    authors = pub.split(";")
    for auth1 in authors:
        if len(auth1) < 2: continue
        id1 = e2id[auth1]
        P[p_id, id1] = 1

from scipy.cluster.vq import kmeans, kmeans2, whiten
result = kmeans2(P, 30)
print result

但我仍然收到错误:

TypeError: mean() 最多接受 2 个参数(给定 4 个)

我做错了什么?

【问题讨论】:

    标签: numpy scipy cluster-analysis data-mining k-means


    【解决方案1】:

    或者,如果您正在寻找聚类图,我会看看 NetworkX。这对你来说可能是一个有用的工具。我建议这样做的原因是因为它看起来像您希望与作者网络一起使用的数据。因此,使用 NetworkX,您可以放入邻接矩阵并找出哪些作者聚集在一起。

    如需进一步阐述,您可以查看我之前提出的一个问题here

    【讨论】:

      【解决方案2】:

      我可以建议scikit-learn 的“亲和传播”吗?在我一直在做的工作中,我发现它通常能够在我的数据集中找到“自然”发生的集群。算法的输入是任意相似性度量的亲和矩阵或相似性矩阵。

      我对您手头的数据类型没有很好的处理,所以我不能说这种方法对您的数据集的确切适用性,但也许值得一试,也许?

      【讨论】:

      • 感谢您的重播,我来看看亲和力传播。
      【解决方案3】:

      K-means 不能在距离矩阵上运行。

      需要一个向量空间来计算均值,这就是它被称为 k-means 的原因。如果您想使用距离矩阵,您需要研究纯粹基于距离的算法,例如 DBSCAN 和 OPTICS(都在 Wikipedia 上)。

      【讨论】:

      • 真的,我错过了这一点。问题仍然是 k-means 如何知道给定矩阵是距离矩阵?我以为我可以将任意矩阵加载到 k-means 中并得到一些(可能毫无意义)的答案。
      • 在您的代码中,P 仍然是一个相似度矩阵。您将无法使用邻接矩阵运行 k-means。 k-means 仅适用于 欧几里得距离,因为 mean 仅最小化欧几里得距离。也许还有其他 Minkowski 范数,但 k-means 不会以任意距离收敛,因为 mean 可能不会减少它们的方差
      • 所以如果你想对图进行聚类,那么你不能使用k-means。它仅适用于欧几里得空间中的点。而且您的合著者图不是欧几里得空间。
      • 好的,不明白你的意思。如果p_id 不总是0,那确实是一个向量空间。但它仍然不适用于k-means,因为它太稀疏和二进制。您会看到类似“是出版物 1-100 的 0.01% 的作者”和此类工件的意思。均值不适用于该向量空间。同时,由于它是非常高维的,欧式距离将变得毫无意义。因此,由于 k-means 试图最小化无意义的欧式距离,因此 k-means 结果将毫无意义。它真的只适用于低亮度。
      • DBSCAN 和 OPTICS 可以工作。因为它们不需要向量,所以它们不会直接受到维度灾难的影响——只要你能给出一个有用的距离函数,它们就可以工作。因此,首先您需要了解您的域中的“相似性”。当对象足够相似以进行聚类时,DBSCAN 需要一个相似度阈值。如果您将此设置为“已共同撰写文章”并将 minpts 设置为 2,您将只检测连接的子图。您首先需要改进距离函数以获得更有用的结果!
      猜你喜欢
      • 2023-04-10
      • 1970-01-01
      • 2014-10-15
      • 2015-05-08
      • 1970-01-01
      • 1970-01-01
      • 2016-01-26
      • 2017-03-26
      • 2017-03-31
      相关资源
      最近更新 更多