我正在研究用于大学任务的KNN算法,目前我正在努力寻找存储为Scipy lil_matrix的每个训练向量之间的欧几里德距离(由于其中值的稀疏性)矢量),以及存储为1 xn lil_matrix的测试向量,原因与上述相同。
要计算出欧几里德距离,然后执行以下代码:
for positiveIndex, positivesComparison in enumerate(positives):
result.append((spatial.distance.euclidean(positivesComparison.todense(),sentenceVector.todense() ), positiveIndex, 1))
其中sentenceVector是1行的lil_matrix,而positives是大小为n x m的lil_matrix。
我想尝试找出更快的东西,而不是逐行遍历正面矩阵并每次评估欧氏距离,并且可以运行正面矩阵和sentenceVector矢量之间的欧氏距离,并返回1 xm矩阵与欧氏距离。 我想这样做的原因是当前系统的计算速度相对较慢,因为它基本上是一个NM时间复杂度,因为我需要计算多个句子测试。 这是可能的,如果是的话,我该怎么做?
注意,任务是使用KNN算法的不同K值来评估性能,而不是KNN的实际实现(尽管我们不允许使用KNN库来完成任务)
答案 0 :(得分:4)
您可以非常轻松地计算批次欧几里德距离:
In [10]: a = np.random.random(size=(4,5))
In [11]: b = np.random.random(size=(1,5))
In [12]: from scipy.spatial.distance import euclidean
In [13]: [euclidean(aa, b) for aa in a]
Out[13]: [1.1430615949614429, 0.568517046878056, 1.3302284168375587, 1.0581730230363529]
In [14]: np.sqrt(np.sum((a - b)**2, axis=1))
Out[14]: array([ 1.1431, 0.5685, 1.3302, 1.0582])
但是我们想要使用稀疏矩阵,这会让事情变得更加困难:
In [22]: import scipy.sparse as ss
In [23]: sa = ss.lil_matrix(a)
In [24]: sb = ss.lil_matrix(b)
In [25]: np.sqrt(np.sum((sa - sb)**2, axis=1)) # <-- ValueError: inconsistent shapes
可以这样做,但您需要使用some tricks。
更重要的是,你应该看看你的矢量究竟有多大(以及多么稀疏)。你可能会更快离开所有密集的东西,它肯定会让你头疼。
最后,我会避免使用LIL格式矩阵,因为它们是最慢的格式之一。对于您的情况,请查看CSR格式。
编辑:我忘记了最简单的解决方案:使用scikit-learn!
In [36]: from sklearn.metrics import pairwise_distances
In [37]: pairwise_distances(a, b)
Out[37]:
array([[ 1.1431],
[ 0.5685],
[ 1.3302],
[ 1.0582]])
In [38]: pairwise_distances(sa, sb)
Out[38]:
array([[ 1.1431],
[ 0.5685],
[ 1.3302],
[ 1.0582]])