快速的核矩阵计算 Python

1 投票
2 回答
3533 浏览
提问于 2025-04-17 02:07

我想在Python中尽可能快地计算一个核矩阵:输入是一个矩阵X,大小是样本数乘以特征数,输出应该是一个对称矩阵D,大小是样本数乘以样本数。

我现在使用的方法虽然是基于迭代器的,但由于使用了for循环,速度真的很慢……有没有人能想到更好的方法?

谢谢!

到目前为止,我的方法是:

from itertools import combinations
def computeKernel(X,dlambda):
    nsamples=X.shape[0]
    D=numpy.zeros((nsamples,nsamples))
    for el in combinations(range(nsamples),2):
        i,j=el
        D[el]=quadraticChiDist(X[i,:],X[j,:])


    D=D+D.T
    D=numpy.exp(-dlambda*D/255)
    D=numpy.eye(D)+D    
    return D

其中,quadraticChiDist是一个函数,它会对X中每一对行进行计算。

2 个回答

0

经过一番搜索,我发现最好的解决办法可能是使用scipy里的pdist函数。这个函数可以计算几种不同的距离,或者你也可以传入一个自定义的函数来计算距离。不过,这个函数的速度非常快(因为它是用C语言实现的),对于提供的距离计算来说效果很好,但如果你传入自定义的函数,速度就没那么快了。实际上,在这种情况下,它的效果和用纯Python写的for循环差不多。

1

你可以通过替换内部循环来将运行时间减半。

for i in range(nsamples):
    for j in range(i):
        D[i,j]=quadraticChiDist(X[i,:],X[j,:])
        D[j,i]=D[i,j]

即使 quadraticChiDist 不是对称的,这也没关系,因为你可以通过(你是不是忘了除以2了?)来对你的矩阵进行对称处理:

D = D + D.T

为了进一步提高速度,我建议优化 quadraticChiDist 的速度。

另外,我推荐你看看 http://cython.org/,特别是 http://docs.cython.org/src/tutorial/numpy.html。这样在很多情况下,你可以获得接近C语言的速度。

撰写回答