我现在使用sklearn的svm模块的方式是使用其默认值。然而,它在我的数据集上做得不是特别好。是否有可能提供自定义损失函数或自定义核?如果是这样,如何编写这样的函数,使其与sklearn的svm期望匹配,以及如何将这样的函数传递给训练器?
有这样一个例子:
SVM自定义核
代码:
def my_kernel(x, y):
"""
We create a custom kernel:
(2 0)
k(x, y) = x ( ) y.T
(0 1)
"""
M = np.array([[2, 0], [0, 1.0]])
return np.dot(np.dot(x, M), y.T)
我想了解这个内核背后的逻辑。如何选择核矩阵?y.T
到底是什么?
回答您的问题,除非您非常清楚为什么要定义自定义内核,否则我会坚持使用内置内核。它们非常快速、灵活、强大,非常适合大多数应用。
话虽如此,让我们进入更多的细节:
核函数是两点之间相似度的一种特殊度量。基本上,相似性值越大意味着点越相似。scikit-learn支持向量机被设计成能够处理任何核函数。几个内置的内核(例如线性,径向基函数,多项式,sigmoid),但你也可以定义自己的。
您的自定义内核函数应该看起来像这样:
def my_kernel(x, y):
"""Compute My Kernel
Parameters
----------
x : array, shape=(N, D)
y : array, shape=(M, D)
input vectors for kernel similarity
Returns
-------
K : array, shape=(N, M)
matrix of similarities between x and y
"""
# ... compute something here ...
return similarity_matrix
最基本的内核,一个线性内核,看起来是这样的:
def linear_kernel(x, y):
return np.dot(x, y.T)
同样地,你可以写
def linear_kernel_2(x, y):
M = np.array([[1, 0],
[0, 1]])
return np.dot(x, np.dot(M, y.T))
矩阵M
在这里定义了所谓的内积空间,核在其中起作用。这个矩阵可以被修改来定义一个新的内积空间;您链接到的示例中的自定义函数只是修改了M
,以有效地将确定相似性的第一个维度的重要性提高一倍。
更复杂的非线性修改也是可能的,但你必须小心:核函数必须满足某些要求(它们必须满足内积空间的性质),否则SVM算法将无法正常工作。