将稀疏矩阵与 sklearn Affinity Propagation 结合使用

Posted

技术标签:

【中文标题】将稀疏矩阵与 sklearn Affinity Propagation 结合使用【英文标题】:Using a Sparse Matrix with sklearn Affinity Propagation 【发布时间】:2016-06-16 10:52:08 【问题描述】:

我在使用 scipy COO 稀疏矩阵作为 Affinity 传播的输入时遇到问题,但它与 numpy 数组完美配合。

只是一个例子,假设我的相似度矩阵是:

[[1.0, 0.9, 0.2]
 [0.9, 1.0, 0.0]
 [0.2, 0.0, 1.0]]

Numpy 矩阵版本

import numpy as np
import sklearn.cluster

simnp = np.array([[1,0.9,0.2],[0.9,1,0],[0.2,0,1]])
affprop = sklearn.cluster.AffinityPropagation(affinity="precomputed")
affprop.fit(simnp)

按预期工作。

稀疏矩阵版本

import scipy.sparse as sps
import sklearn.cluster

simsps = sps.coo_matrix(([1,1,1,0.9,0.9,0.2,0.2],([0,1,2,0,1,0,2],[0,1,2,1,0,2,0])),(3,3))
affprop = sklearn.cluster.AffinityPropagation(affinity="precomputed")
affprop.fit(simsps)

返回以下错误

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python\Python27\lib\site-packages\sklearn\cluster\affinity_propagation_.py", line 301, in fit
    copy=self.copy, verbose=self.verbose, return_n_iter=True)
  File "C:\Python\Python27\lib\site-packages\sklearn\cluster\affinity_propagation_.py", line 90, in affinity_propagation
    preference = np.median(S)
  File "C:\Python\Python27\lib\site-packages\numpy\lib\function_base.py", line 3084, in median
    overwrite_input=overwrite_input)
  File "C:\Python\Python27\lib\site-packages\numpy\lib\function_base.py", line 2997, in _ureduce
    r = func(a, **kwargs)
  File "C:\Python\Python27\lib\site-packages\numpy\lib\function_base.py", line 3158, in _median
    return mean(part[indexer], axis=axis, out=out)
  File "C:\Python\Python27\lib\site-packages\numpy\core\fromnumeric.py", line 2878, in mean
    out=out, keepdims=keepdims)
  File "C:\Python\Python27\lib\site-packages\numpy\core\_methods.py", line 70, in _mean
    ret = ret.dtype.type(ret / rcount)
ValueError: setting an array element with a sequence.

我的笔记本电脑没有足够的 RAM 来获取密集矩阵,因此想使用稀疏矩阵。

我做错了什么?

谢谢。

【问题讨论】:

一般来说,numpy 函数(例如median)不支持稀疏矩阵。有些东西之所以有效,是因为它们将任务委托给了一个稀疏方法。 sklearn 说可以这样使用稀疏矩阵吗? 嗨,我只是从他们网站上的一行中暗示它:“此外,如果使用密集的相似矩阵,内存复杂度是 O(N^2) 的量级,但如果使用稀疏的相似矩阵,则可以减少使用相似矩阵。” scikit-learn.org/stable/modules/… 当我通过 sklearn 的 'fit()' 方法传递数组时,我所做的是使用 '.toarray()' 方法将稀疏矩阵转换为数组。我不太确定我是否能够减少内存影响。我还得再测试一下。谢谢! 对于内存或速度而言,稀疏矩阵可能没有用处,除非稀疏性(非零值占总数的比例)为 1% 或更少。 您好,感谢您对此进行调查。我只是在估计使用稀疏矩阵对sys.getsizeof() 函数的影响。对于算法,如果小于 0.3,我计划将值设为 0,因为无论如何这将是一个糟糕的匹配。我想我只需要将它转换回密集矩阵,然后再将其传递给 sklearn 方法。谢谢! 【参考方案1】:

http://scikit-learn.org/stable/modules/generated/sklearn.cluster.AffinityPropagation.html

适合(X, y=None) 参数: X:类数组,形状 (n_samples, n_features) 或 (n_samples, n_samples)

预测(X) 参数: X : array-like, sparse matrix, shape (n_samples, n_features)

http://scikit-learn.org/stable/modules/generated/sklearn.cluster.SpectralClustering.html

适合(X, y=None) 参数: X : 类数组或稀疏矩阵,形状 (n_samples, n_features)

所以有些方法确实接受稀疏矩阵。但是AffinityPropagation.fit 并没有提出这样的要求。这是文档遗漏,还是表明它不适用于稀疏矩阵?您的错误表明后者 - 出于某种原因,它尚未适用于稀疏。

我不是scikit-learn 的用户,但我已经回答了一些关于该软件包中稀疏矩阵的问题。我的印象是稀疏的处理相对较新,在某些情况下他们必须使用todense() 将稀疏的转换回密集矩阵。

就像我在评论中所写,numpy 代码本身不能正确处理稀疏矩阵。它仅在将操作委托给稀疏方法时才有效。 np.mediannp.mean 似乎没有正确委派给 sparse.coo_matrix.mean

试试:

np.median(simnp)
np.mean(simnp)
simnp.mean()

【讨论】:

【参考方案2】:

sklearn 当前状态的更新(2019 年 6 月)可能会有用。

在提出原始问题时,已经有 fix 和 issue 报告 AffinityPropagation 无法使用稀疏矩阵。最近(2019 年 5 月)reported again AffinityPropagation 无法处理稀疏矩阵。

总结其实是:

只有当亲和力不是预先计算而是欧几里得(因为它调用了适用于稀疏矩阵的 sklearn.metrics.euclidean_distances)时,拟合才适用于稀疏矩阵。这实际上在内存消耗方面没有任何优势。 如果预先计算了相似性,则拟合将不适用于稀疏矩阵。当前阻塞的代码行似乎是计算中位数。

【讨论】:

以上是关于将稀疏矩阵与 sklearn Affinity Propagation 结合使用的主要内容,如果未能解决你的问题,请参考以下文章

哪个稀疏矩阵表示与 sklearn.svm.LinearSVC 一起使用

将大型 csv 转换为稀疏矩阵以在 sklearn 中使用

将 pandas 稀疏数据帧转换为稀疏 numpy 矩阵以供 sklearn 使用?

使用 sklearn 对大型稀疏矩阵执行 PCA

sklearn svm中的稀疏预计算Gram矩阵?

将 sklearn LogisticRegression 系数链接到稀疏矩阵中的项,并获得统计显着性 / C.I