Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Scipy:基于阈值稀疏相似性的epsilon邻域_Python_Numpy_Scipy_Distance_Similarity - Fatal编程技术网

Python 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))解,但是现在如果结果是稀疏的就足够了。同样很明显,我必须使用相似性而不是距离,但这不应该是一个大问

我想知道scipy是否提供了一个选项来实现epsilon邻域搜索的原始但内存友好的方法:

计算我的数据的成对相似性,但将所有小于阈值的相似性
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和元素比较的方法,速度慢得离谱……我已经更新了答案,以包含一个粗略的代码片段,但是,在不知道具体的相似性度量的情况下,很难对其进行优化。此外,带有的代码需要两组点,但如果只在一组点内进行比较,则可以进一步优化。希望有帮助。