Python 具有自定义内核的GridSearchCV
我有以下代码:Python 具有自定义内核的GridSearchCV,python,python-3.x,machine-learning,scikit-learn,Python,Python 3.x,Machine Learning,Scikit Learn,我有以下代码: 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, y
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
参数,因为我不想手动测试参数、检查准确性等
有没有办法做到这一点?这似乎不可能直接做到;内置内核的参数都经过了烘焙 一种方法是自己传递不同的内核。这有点复杂,因为您的嵌套函数定义了内核,所以我使用
partial
:
从functools导入部分
参数空间={
内核:[
局部的(
语法矩阵,
K_函数=部分(
达克内尔的塔尼莫托兰,
γ=g,
)
)
对于g in
]
}
另一种方法是定制类。这在hyperparameter搜索中更清晰,因为“hyperparameter”可以是gamma,但在维护类时可能需要做更多的工作。在这种情况下,我通过重用gamma
参数来避免重写\uuuu init\uuu
,并在fit
时间设置内核,以便set\u params
对gamma
正常工作
SVC类_tanimoto(svm.SVC):
“”“带有Tanimoto内核的SVC。”“”
def配合(自身、X、y、样本重量=无):
self.kernel=partial(
语法矩阵,
K_函数=部分(
达克内尔的塔尼莫托兰,
gamma=自我gamma,
)
)
super().配合(X,y,样本重量=样本重量)
回归自我
这似乎不可能直接实现;内置内核的参数都经过了烘焙
一种方法是自己传递不同的内核。这有点复杂,因为您的嵌套函数定义了内核,所以我使用partial
:
从functools导入部分
参数空间={
内核:[
局部的(
语法矩阵,
K_函数=部分(
达克内尔的塔尼莫托兰,
γ=g,
)
)
对于g in
]
}
另一种方法是定制类。这在hyperparameter搜索中更清晰,因为“hyperparameter”可以是gamma,但在维护类时可能需要做更多的工作。在这种情况下,我通过重用gamma
参数来避免重写\uuuu init\uuu
,并在fit
时间设置内核,以便set\u params
对gamma
正常工作
SVC类_tanimoto(svm.SVC):
“”“带有Tanimoto内核的SVC。”“”
def配合(自身、X、y、样本重量=无):
self.kernel=partial(
语法矩阵,
K_函数=部分(
达克内尔的塔尼莫托兰,
gamma=自我gamma,
)
)
super().配合(X,y,样本重量=样本重量)
回归自我
我认为有一种方法可以使用包装器类来完成,我以前看到过,但我一直在搜索它,但找不到它。@另外,我添加了一个自定义类实现,但我还没有测试它是否为超参数搜索正确克隆和设置参数。一些错误与意外的nu
参数有关,而且在那之后,不能克隆对象SVC_tanimoto(gamma=0),因为构造函数或者没有设置或者修改参数gamma
Ugh,当然nu
不应该在那里。我从SVC
复制,它继承自BaseSVC
并设置nu=0
。您可能只从BaseSVC
继承,但最好还是坚持使用SVC
并删除nu
。我将不得不研究gamma
问题,但可能/可能是因为SVC
有自己的gamma
。好吧,双重使用gamma
是错误的根源,但是只在\uuuu init\uuuu
上设置内核比这更麻烦:设置gamma参数不会更改内核中的值。所以我把它移到了“prefit”步骤,并劫持了原始的gamma
来携带这个内核的gamma
(从教学的角度来看,这可能是正确的,我不确定)。我认为有一种方法可以使用包装类来实现它,我在不久前看到过它,但我一直在搜索它,却找不到它。@Norhther,我添加了一个自定义类实现,但尚未测试它是否为超参数搜索正确克隆和设置了参数。意外的nu
参数出现了一些错误,而且在此之后,无法克隆对象SVC_tanimoto(gamma=0),因为构造函数没有设置或修改参数gamma
Ugh,当然nu
不应该在那里。我从SVC
复制,它继承自BaseSVC
并设置nu=0
。您可能只从BaseSVC
继承,但最好还是坚持使用SVC
并删除nu
。我将不得不研究gamma
问题,但可能/可能是因为SVC
有自己的gamma
。好吧,双重使用gamma
是错误的根源,但是只在\uuuu init\uuuu
上设置内核比这更麻烦:设置gamma参数不会更改内核中的值。因此,我将其移动到了“prefit”步骤,并劫持了原始的gamma
,以携带内核的gamma
(从教学角度来看,这可能是正确的,我不确定)。