Python: sklearn svm,提供自定义丢失函数

时间:2022-07-21 01:44:48

The way I use sklearn's svm module now, is to use its defaults. However, its not doing particularly well for my dataset. Is it possible to provide a custom loss function , or a custom kernel? If so, what is the way to write such a function so that it matches with what sklearn's svm expects and how to pass such a function to the trainer?

我现在使用sklearn的svm模块的方法是使用它的默认值。但是,它对我的数据集没有特别好。是否可以提供自定义损失函数,或者自定义内核?如果是这样,如何编写这样一个函数,使它与sklearn的svm期望匹配,以及如何将这个函数传递给trainer?

There is this example of how to do it:
SVM custom kernel

有这样一个示例:SVM自定义内核

code cited here:

代码引用:

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)

I'd like to understand the logic behind this kernel. How to choose the kernel matrix? And what exactly is y.T ?

我想理解内核背后的逻辑。如何选择核矩阵?y是什么。T ?

1 个解决方案

#1


1  

To answer your question, unless you have a very good idea of why you want to define a custom kernel, I'd stick with the built-ins. They are very fast, flexible, and powerful, and are well-suited to most applications.

要回答您的问题,除非您非常清楚为什么要定义自定义内核,否则我将坚持使用内置内核。它们非常快速、灵活和强大,非常适合大多数应用程序。

That being said, let's go into a bit more detail:

话虽如此,让我们再深入一点:

A Kernel Function is a special kind of measure of similarity between two points. Basically a larger value of the similarity means the points are more similar. The scikit-learn SVM is designed to be able to work with any kernel function. Several kernels built-in (e.g. linear, radial basis function, polynomial, sigmoid) but you can also define your own.

核函数是两个点之间相似度的一种特殊度量。基本上,相似点的较大值意味着这些点更相似。scikit-learn SVM被设计成能够处理任何内核函数。几个内核内置(例如线性、径向基函数、多项式、sigmoid),但您也可以定义自己的内核。

Your custom kernel function should look something like this:

您的自定义内核函数应该如下所示:

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

The most basic kernel, a linear kernel, would look like this:

最基本的核,线性核,应该是这样的:

def linear_kernel(x, y):
    return np.dot(x, y.T)

Equivalently, you can write

同样,您可以编写

def linear_kernel_2(x, y):
    M = np.array([[1, 0],
                  [0, 1]])
    return np.dot(x, np.dot(M, y.T))

The matrix M here defines the so-called inner product space in which the kernel acts. This matrix can be modified to define a new inner product space; the custom function from the example you linked to just modifies M to effectively double the importance of the first dimension in determining the similarity.

这里的矩阵M定义了内核作用的内积空间。这个矩阵可以修改为定义一个新的内积空间;您链接到的示例中的自定义函数仅修改了M,以有效地使第一个维度在确定相似性方面的重要性增加一倍。

More complicated non-linear modifications are possible as well, but you have to be careful: kernel functions must meet certain requirements (they must satisfy the properties of an inner-product space) or the SVM algorithm will not work correctly.

更复杂的非线性修改也是可能的,但您必须小心:内核函数必须满足某些需求(它们必须满足内部产品空间的属性),否则SVM算法将无法正常工作。

#1


1  

To answer your question, unless you have a very good idea of why you want to define a custom kernel, I'd stick with the built-ins. They are very fast, flexible, and powerful, and are well-suited to most applications.

要回答您的问题,除非您非常清楚为什么要定义自定义内核,否则我将坚持使用内置内核。它们非常快速、灵活和强大,非常适合大多数应用程序。

That being said, let's go into a bit more detail:

话虽如此,让我们再深入一点:

A Kernel Function is a special kind of measure of similarity between two points. Basically a larger value of the similarity means the points are more similar. The scikit-learn SVM is designed to be able to work with any kernel function. Several kernels built-in (e.g. linear, radial basis function, polynomial, sigmoid) but you can also define your own.

核函数是两个点之间相似度的一种特殊度量。基本上,相似点的较大值意味着这些点更相似。scikit-learn SVM被设计成能够处理任何内核函数。几个内核内置(例如线性、径向基函数、多项式、sigmoid),但您也可以定义自己的内核。

Your custom kernel function should look something like this:

您的自定义内核函数应该如下所示:

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

The most basic kernel, a linear kernel, would look like this:

最基本的核,线性核,应该是这样的:

def linear_kernel(x, y):
    return np.dot(x, y.T)

Equivalently, you can write

同样,您可以编写

def linear_kernel_2(x, y):
    M = np.array([[1, 0],
                  [0, 1]])
    return np.dot(x, np.dot(M, y.T))

The matrix M here defines the so-called inner product space in which the kernel acts. This matrix can be modified to define a new inner product space; the custom function from the example you linked to just modifies M to effectively double the importance of the first dimension in determining the similarity.

这里的矩阵M定义了内核作用的内积空间。这个矩阵可以修改为定义一个新的内积空间;您链接到的示例中的自定义函数仅修改了M,以有效地使第一个维度在确定相似性方面的重要性增加一倍。

More complicated non-linear modifications are possible as well, but you have to be careful: kernel functions must meet certain requirements (they must satisfy the properties of an inner-product space) or the SVM algorithm will not work correctly.

更复杂的非线性修改也是可能的,但您必须小心:内核函数必须满足某些需求(它们必须满足内部产品空间的属性),否则SVM算法将无法正常工作。