Python Scipy:基于阈值稀疏相似性的epsilon邻域
我想知道scipy是否提供了一个选项来实现epsilon邻域搜索的原始但内存友好的方法: 计算我的数据的成对相似性,但将所有小于阈值的相似性Python Scipy:基于阈值稀疏相似性的epsilon邻域,python,numpy,scipy,distance,similarity,Python,Numpy,Scipy,Distance,Similarity,我想知道scipy是否提供了一个选项来实现epsilon邻域搜索的原始但内存友好的方法: 计算我的数据的成对相似性,但将所有小于阈值的相似性epsilon动态设置为零,然后将结果直接作为稀疏矩阵输出 例如,scipy.spatial.distance.pdist()确实很快,但是与我的时间限制相比,内存限制提前达到了,至少如果我使用squareform() 我知道在这种情况下有O(n*log(n))解,但是现在如果结果是稀疏的就足够了。同样很明显,我必须使用相似性而不是距离,但这不应该是一个大问
epsilon
动态设置为零,然后将结果直接作为稀疏矩阵输出
例如,scipy.spatial.distance.pdist()
确实很快,但是与我的时间限制相比,内存限制提前达到了,至少如果我使用squareform()
我知道在这种情况下有O(n*log(n))解,但是现在如果结果是稀疏的就足够了。同样很明显,我必须使用相似性而不是距离,但这不应该是一个大问题,对吧。只要你可以根据距离度量(比如1减去相似性)重新计算相似性度量,那么最有效的解决方案就是使用sklearn 否则,您可以通过将每个点与其他$i-1$点进行比较,并丢弃所有小于阈值的值,来构建自己的scipy.sparse.csr_矩阵 在不知道您的特定相似性度量的情况下,此代码应该大致做到以下几点:
import scipy.sparse as spsparse
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
def sparse_similarity(X, epsilon=0.99, Y=None, similarity_metric=cosine_similarity):
'''
X : ndarray
An m by n array of m original observations in an n-dimensional space.
'''
Nx, Dx = X.shape
if Y is None:
Y=X
Ny, Dy = Y.shape
assert Dx==Dy
data = []
indices = []
indptr = [0]
for ix in range(Nx):
xsim = similarity_metric([X[ix]], Y)
_ , kept_points = np.nonzero(xsim>=epsilon)
data.extend(xsim[0,kept_points])
indices.extend(kept_points)
indptr.append(indptr[-1] + len(kept_points))
return spsparse.csr_matrix((data, indices, indptr), shape=(Nx,Ny))
X = np.random.random(size=(1000,10))
sparse_similarity(X, epsilon=0.95)
您想要使用什么样的相似性度量?根据你的选择,你可以采用不同的选择。我还没有决定,可能最终不会是空间距离。因此,我对时间复杂度为O(n^2)但至少节省一些内存的通用解决方案感兴趣……另一个问题是scipy方法不允许指定要比较的对。例如,如果我首先比较AxA中的所有对和BxB中的所有对,然后我想合并比较并只添加AxB。如果我能将两个数据集A,B传递给我在论文中扫描过的函数(默认值A=B),这将很容易解决,这让我对n^2的时间复杂度是否可以改进有些怀疑。但也许BallTree的空间复杂度至少更低。我会考虑你的意见,并对这件事做进一步的研究。你能建议你第二个选择吗?因为我在python中尝试了一些使用itertools和元素比较的方法,速度慢得离谱……我已经更新了答案,以包含一个粗略的代码片段,但是,在不知道具体的相似性度量的情况下,很难对其进行优化。此外,带有的代码需要两组点,但如果只在一组点内进行比较,则可以进一步优化。希望有帮助。