【问题标题】:How can I replace svm.SVR 'rbf' kernel in sklearn using my own RBF function?如何使用我自己的 RBF 函数替换 sklearn 中的 svm.SVR 'rbf' 内核?
【发布时间】:2019-09-10 06:15:41
【问题描述】:

我已经开发了下面的代码来启动一个 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]。

我难以处理这些错误。谁能帮我让这段代码工作?

【问题讨论】:

    标签: python matrix scikit-learn svm


    【解决方案1】:

    根据this source,我正在寻找的 RBF 函数(将训练特征作为 X 并将测试特征作为 X' 作为输入)和输出 [n_training_samples, n_testing_samples] 如在 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 一样高效的性能。将 cython 库的 static typing 用于索引以及将 memory-views 用于 numpy 数组以加快速度可能会很有用。

    【讨论】:

      【解决方案2】:

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

      背景

      RBF函数定义如下(来自wiki

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

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

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

      【讨论】:

      • 好吧,我应该如何替换 my_rbf 函数并使代码像使用默认内核 = 'rbf' 时一样工作?
      猜你喜欢
      • 2021-12-24
      • 2021-12-09
      • 2018-03-07
      • 1970-01-01
      • 2015-01-22
      • 2017-06-13
      • 2016-02-24
      • 2021-11-24
      • 2020-07-01
      相关资源
      最近更新 更多