我正在尝试为库中的svm.SVR
方法定义一些著名的内核,例如 RBF、双曲正切、傅里叶等sklearn
。我开始工作rbf
(我知道 svm 中有一个用于 rbf 的默认内核,但我需要定义一个以便以后能够自定义它),并在这里找到了一些有用的链接并选择了这个:
def my_kernel(X,Y):
K = np.zeros((X.shape[0],Y.shape[0]))
for i,x in enumerate(X):
for j,y in enumerate(Y):
K[i,j] = np.exp(-1*np.linalg.norm(x-y)**2)
return K
clf=SVR(kernel=my_kernel)
我使用这个是因为我可以将它用于我的火车(形状为 [3850,4])和具有不同形状的测试数据(形状为 [1200,4])。但问题是它太慢了,我必须等待很长时间才能得到结果。我什至在 cython 中使用了静态类型和内存视图,但它的性能不如默认的svm
rbf 内核。我还发现了这个链接,它是关于同样的问题,但是使用它numpy.einsum
并且numexpr.evaluate
对我来说有点困惑。事实证明,就速度性能而言,这是最好的代码:
从 scipy.linalg.blas 导入 sgemm
def app2(X, gamma, var):
X_norm = -gamma*np.einsum('ij,ij->i',X,X)
return ne.evaluate('v * exp(A + B + C)', {\
'A' : X_norm[:,None],\
'B' : X_norm[None,:],\
'C' : sgemm(alpha=2.0*gamma, a=X, b=X, trans_b=True),\
'g' : gamma,\
'v' : var\
})
此代码仅适用于一个输入 (X),我找不到针对我的情况修改它的方法(两个输入具有两种不同的大小 - 内核函数获取形状为 (m,n) 和 (l,n) 的矩阵并根据svm docs输出 (m,l )。我想我只需要K[i,j] = np.exp(-1*np.linalg.norm(x-y)**2)
在第二个代码中替换第一个代码即可加快速度。任何帮助将不胜感激。