我正在尝试计算从scikit-learn DictVectorizer
返回的Scipy稀疏矩阵上的最近邻居聚类。但是,当我尝试使用scikit-learn计算距离矩阵时,我会使用' euclidean'通过pairwise.euclidean_distances
和pairwise.pairwise_distances
的距离。我的印象是scikit-learn可以计算这些距离矩阵。
我的矩阵非常稀疏,形状为:<364402x223209 sparse matrix of type <class 'numpy.float64'>
with 728804 stored elements in Compressed Sparse Row format>
。
我还在Scipy中尝试了pdist
和kdtree
等方法,但收到了其他无法处理结果的错误。
有谁能请我指出一个能够有效地计算距离矩阵和/或最近邻结果的解决方案吗?
一些示例代码:
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')
答案 0 :(得分:3)
首先,您不能将KDTree
和pdist
与稀疏矩阵一起使用,您必须将其转换为密集(您可以选择它是否是您的选择):
>>> 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
,与欧几里德距离相比具有相反的顺序。