【问题标题】:GridSearchCV with custom Kernel带有自定义内核的 GridSearchCV
【发布时间】:2021-05-14 18:45:40
【问题描述】:

我有以下代码:

import numpy as np
from sklearn import svm
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

def tanimotoKernel(xs, ys):
    a = 0
    b = 0
    for x, y in zip(xs, ys):
        a += min(x, y)
        b += max(x, y)
    return a / b

def tanimotoLambdaKernel(xs,ys, gamma = 0.01):
    return np.exp(gamma * tanimotoKernel(xs,ys)) / (np.exp(gamma) - 1)

def GramMatrix(X1, X2, K_function=tanimotoLambdaKernel):
    gram_matrix = np.zeros((X1.shape[0], X2.shape[0]))
    for i, x1 in enumerate(X1):
        for j, x2 in enumerate(X2):
            gram_matrix[i, j] = K_function(x1, x2)
    return gram_matrix

X, y = datasets.load_iris(return_X_y=True)
x_train, x_test, y_train, y_test = train_test_split(X, y)
clf.fit(x_train, y_train)
accuracy_score(clf.predict(x_test), y_test)

clf = svm.SVC(kernel=GramMatrix)

但是,我希望能够用GridSearchCV 调整tanimotoLambdaKernel 的gamma 参数,因为我不想手动测试参数,检查准确性等。

有什么办法吗?

【问题讨论】:

    标签: python python-3.x machine-learning scikit-learn


    【解决方案1】:

    这似乎无法直接实现;内置内核的参数都被烘焙了。

    一种方法是自己传递不同的内核。由于您定义内核的嵌套函数,这有点涉及,所以我使用partial:

    from functools import partial
    param_space = {
        kernel: [
            partial(
                GramMatrix,
                K_function=partial(
                    tanimotoLambdaKernel,
                    gamma=g,
                )
            )
            for g in <your list of gammas>
        ]
    }
    

    想到的另一种方法是自定义类。这在超参数搜索中更清晰,因为“超参数”可以只是 gamma,但在维护类方面可能需要更多工作。在这种情况下,我通过重用gamma 参数来避免覆盖__init__,并将内核设置为fit 时间,以便set_params 对gamma 正常工作。

    class SVC_tanimoto(svm.SVC):
        """SVC with a Tanimoto kernel."""
        def fit(self, X, y, sample_weight=None):
            self.kernel = partial(
                GramMatrix,
                K_function=partial(
                    tanimotoLambdaKernel,
                    gamma=self.gamma,
                )
            )
            super().fit(X, y, sample_weight=sample_weight)
            return self
    

    【讨论】:

      猜你喜欢
      • 2011-12-23
      • 2014-08-28
      • 2021-01-16
      • 2015-12-20
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      • 2015-06-06
      • 1970-01-01
      相关资源
      最近更新 更多