快速的核矩阵计算 Python
我想在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语言的速度。