首页 文章

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

提问于
浏览
5

我试图在scikit-learn的 DictVectorizer 返回的Scipy稀疏矩阵上计算最近邻居聚类 . 但是,当我尝试使用scikit-learn计算距离矩阵时,我通过 pairwise.euclidean_distancespairwise.pairwise_distances 使用'euclidean'距离得到错误消息 . 我的印象是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 回答

  • 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'算法并查看它是否可以处理您的数据 .

  • 1

    从你的评论:

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

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

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

相关问题