如何使用我自己的 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)
其中 x
和 x'
是两个特征 (X) 向量。
设 H(X)
是一个函数,可以将向量 X
变换到其他维度(通常是非常非常高的维度)。 SVM需要计算特征向量所有组合(即所有H(X)
的)之间的点积。所以如果 H(X1) . H(X2) = K(X1, X2)
则 K
被称为 H
的核函数或核化。因此,K
不是将点 X1
和 X2
转换到非常高的维度并在那里计算点积,而是直接从 X1
和 X2
计算它。
结论
my_rbf
不是有效的内核函数,仅仅是因为它使用了标签 (Y
s)。它应该只在特征向量上。
根据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 可以加快速度。
我已经开发了下面的代码来启动 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)
其中 x
和 x'
是两个特征 (X) 向量。
设 H(X)
是一个函数,可以将向量 X
变换到其他维度(通常是非常非常高的维度)。 SVM需要计算特征向量所有组合(即所有H(X)
的)之间的点积。所以如果 H(X1) . H(X2) = K(X1, X2)
则 K
被称为 H
的核函数或核化。因此,K
不是将点 X1
和 X2
转换到非常高的维度并在那里计算点积,而是直接从 X1
和 X2
计算它。
结论
my_rbf
不是有效的内核函数,仅仅是因为它使用了标签 (Y
s)。它应该只在特征向量上。
根据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 可以加快速度。