将具有两个以上参数的自定义内核传递给 scikit-learn 中的 svm.SVC

数据挖掘 Python scikit-学习 支持向量机
2021-10-09 00:20:29

我正在尝试使用接受 3 个参数的自定义内核,以及 sk-learn 中的 SVM:

def k_gaussian(_x1, _x2, _sigma):
    normsq = np.square(np.linalg.norm(_x1-_x2))
    return np.exp(- normsq/(2 * np.square(sigma)))

根据文档,自定义内核必须只有两个参数,svm.SVC类将使用给定的输入数据自动处理。我们被告知以如下形式传递自定义内核:

clf = svm.SVC(kernel=my_kernel)

但是,我正在处理一项任务,该任务要求我们对不同值的 SVM 性能进行实验_sigma

在这种情况下,我怎样才能做到这一点?我可以传递类似的东西吗?:

clf = svm.SVC(kernel=k_gaussian(_sigma=2)) 

装饰器之类的东西会在这里帮助我吗?

1个回答

这可以通过像这样的闭包来完成:

代码:

def build_k_gaussian(sigma):

    def k_gaussian(_x1, _x2):
        diff = _x1[:, np.newaxis] - _x2
        normsq = np.square(np.linalg.norm(diff, axis = 2))
        return np.exp(- normsq / (2 * np.square(sigma)))

    return k_gaussian

clf = svm.SVC(kernel=build_k_gaussian(sigma=2))

这是如何运作的?

该函数在被调用 k_gaussian时定义。将能够访问函数创建时的值。这称为闭包。build_k_gaussian()k_gaussiansigma

所以最后,build_k_gaussian返回一个带两个参数的函数,也就是需要的kernel参数。

根据Using Python functions as kernels on scikit-learn

您的内核必须将两个形状矩阵 (n_samples_1, n_features) 和 (n_samples_2, n_features) 作为参数,并返回一个形状为 (n_samples_1, n_samples_2) 的内核矩阵。

因此,您需要对所有样本对应用核函数,因此 diff广播_x1矩阵并从 中的所有样本中减去所有_x2样本_x1你必须计算范数axis=2