我试图在scikit-learn的 DictVectorizer
返回的Scipy稀疏矩阵上计算最近邻居聚类 . 但是,当我尝试使用scikit-learn计算距离矩阵时,我通过 pairwise.euclidean_distances
和 pairwise.pairwise_distances
使用'euclidean'距离得到错误消息 . 我的印象是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')
2 回答
首先,你不能使用
KDTree
和pdist
与稀疏矩阵,你必须将其转换为密集(你的选择是否是你的选择):二,来自the docs:
您可能想尝试'ball_tree'算法并查看它是否可以处理您的数据 .
从你的评论:
基本数学表明,这只有在输入矩阵包含大量重复项的情况下才有可能,因为对于两个完全相等的点,欧几里德距离仅为零(这实际上是axioms of distance之一) . 因此,如果您删除重复项,这可能会有效 .
否则,根据您的问题,您可能能够使用
sklearn.metrics.pairwise_distances_argmin_min
或余弦相似度X * X.T
,与欧几里德距离相比具有相反的顺序 .