如何使用我自己的 RBF 函数替换 sklearn 中的 svm.SVR 'rbf' 内核?

How can I replace svm.SVR 'rbf' kernel in sklearn using my own RBF function?

我已经开发了下面的代码来启动 svm 方法的项目:

import numpy as np
import pandas as pd

from sklearn import svm
from sklearn.datasets import load_boston
from sklearn.metrics import mean_absolute_error

housing = load_boston()
df = pd.DataFrame(np.c_[housing['data'], housing['target']],
              columns= np.append(housing['feature_names'], ['target']))

features = df.columns.tolist()
label = features[-1]
features = features[:-1]

x_train = df[features].iloc[:400]
y_train = df[label].iloc[:400]

x_test = df[features].iloc[400:]
y_test = df[label].iloc[400:]

svr = svm.SVR(kernel='rbf')
svr.fit(x_train, y_train)
y_pred = svr.predict(x_test)

print(mean_absolute_error(y_pred, y_test))

现在我想使用我定制的 rbf 内核,它是:

def my_rbf(feat, lbl):
#feat = feat.values
    #lbl = lbl.values
    ans = np.array([])
    gamma = 0.000005
    for i in range(len(feat)):
        ans = np.append(ans, np.exp(-gamma * np.dot(feat[i]-lbl[i], feat[i]-lbl[i])))

    return ans

然后我更改了 svm.SVR(kernel=my_rbf) 但是在以任何方式修改它时我遇到了很多错误。我还尝试使用像 np.dot(feat-lbl,feat-lbl) 这样的简单函数,它在 SVR.fit 方法中工作正常,但在 svr.predict 中发生了一些错误,表明输入矩阵的形状必须像 [n_samples_test, n_samples_train].

我无法处理这些错误。谁能帮我使这段代码工作?

您编写的自定义内核方法 my_rbf 同时使用了 X(特征)和 y(标签)。您无法在预测期间评估此功能,因为您无权访问标签。自定义内核如果有缺陷。

背景

RBF函数定义如下(来自wiki

其中 xx' 是两个特征 (X) 向量。

H(X) 是一个函数,可以将向量 X 变换到其他维度(通常是非常非常高的维度)。 SVM需要计算特征向量所有组合(即所有H(X)的)之间的点积。所以如果 H(X1) . H(X2) = K(X1, X2)K 被称为 H 的核函数或核化。因此,K 不是将点 X1X2 转换到非常高的维度并在那里计算点积,而是直接从 X1X2 计算它。

结论 my_rbf 不是有效的内核函数,仅仅是因为它使用了标签 (Ys)。它应该只在特征向量上。

根据this source, RBF function which I was looking for (takes training featues as X and testing features as X' as inputs) and outputs [n_training_samples, n_testing_samples] as explained more thoroughly in docs,是这样的:

def my_kernel(X,Y):
    K = np.zeros((X.shape[0],Y.shape[0]))
    for i,x in enumerate(X):
        for j,y in enumerate(Y):
            K[i,j] = np.exp(-1*np.linalg.norm(x-y)**2)
    return K

clf=SVR(kernel=my_kernel)

结果完全等于:

clf=SVR(kernel="rbf",gamma=1)

就速度而言,它缺乏与默认 svm 库 rbf 一样高效的性能。对 numpy 数组使用 static typing of cython library for indexes and also using memory-views 可以加快速度。