Scipy稀疏 - 距离矩阵(Scikit或Scipy)

时间:2014-01-13 07:31:31

标签: python numpy scipy scikit-learn sparse-matrix

我正在尝试计算从scikit-learn DictVectorizer返回的Scipy稀疏矩阵上的最近邻居聚类。但是,当我尝试使用scikit-learn计算距离矩阵时,我会使用' euclidean'通过pairwise.euclidean_distancespairwise.pairwise_distances的距离。我的印象是scikit-learn可以计算这些距离矩阵。

我的矩阵非常稀疏,形状为:<364402x223209 sparse matrix of type <class 'numpy.float64'> with 728804 stored elements in Compressed Sparse Row format>

我还在Scipy中尝试了pdistkdtree等方法,但收到了其他无法处理结果的错误。

有谁能请我指出一个能够有效地计算距离矩阵和/或最近邻结果的解决方案吗?

一些示例代码:

import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.neighbors import NearestNeighbors
from sklearn.metrics import pairwise
import scipy.spatial

file = 'FileLocation'
data = []
FILE = open(file,'r')
for line in FILE:
    templine = line.strip().split(',')
    data.append({'user':str(int(templine[0])),str(int(templine[1])):int(templine[2])})
FILE.close()

vec = DictVectorizer()
X = vec.fit_transform(data)

result = scipy.spatial.KDTree(X)

错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/scipy/spatial/kdtree.py", line 227, in __init__
    self.n, self.m = np.shape(self.data)
ValueError: need more than 0 values to unpack

同样,如果我跑:

scipy.spatial.distance.pdist(X,'euclidean')

我得到以下内容:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/scipy/spatial/distance.py", line 1169, in pdist
    [X] = _copy_arrays_if_base_present([_convert_to_double(X)])
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/scipy/spatial/distance.py", line 113, in _convert_to_double
    X = X.astype(np.double)
ValueError: setting an array element with a sequence.

最后,在scikit-learn中运行NearestNeighbor会导致内存错误:

nbrs = NearestNeighbors(n_neighbors=10, algorithm='brute')

2 个答案:

答案 0 :(得分:3)

首先,您不能将KDTreepdist与稀疏矩阵一起使用,您必须将其转换为密集(您可以选择它是否是您的选择):

>>> X
<2x3 sparse matrix of type '<type 'numpy.float64'>'
        with 4 stored elements in Compressed Sparse Row format>

>>> scipy.spatial.KDTree(X.todense())
<scipy.spatial.kdtree.KDTree object at 0x34d1e10>
>>> scipy.spatial.distance.pdist(X.todense(),'euclidean')
array([ 6.55743852])

其次,来自the docs

  

对于小数据样本,高效的强力邻居搜索可能非常具有竞争力。然而,随着样本数量N的增加,蛮力方法很快就变得不可行了。

您可能想尝试一下“ball_tree”&#39;算法并查看它是否可以处理您的数据。

答案 1 :(得分:1)

来自你的评论:

  

由于它是一个稀疏矩阵,我希望有智能计算距离的解决方案,并将结果存储在类似的稀疏矩阵中。

基本数学表明,这只有在输入矩阵包含大量重复项的情况下才有可能,因为对于两个完全相等的点,欧几里德距离仅为零(这实际上是axioms of distance之一)。因此,如果删除重复项,这可能会有效。

否则,根据您的问题,您可以使用sklearn.metrics.pairwise_distances_argmin_min或余弦相似度X * X.T,与欧几里德距离相比具有相反的顺序。