利用RBF作为核函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用RBF作为核函数相关的知识,希望对你有一定的参考价值。

参考技术A 5-2、利用RBF作为核函数

import numpy as np

import matplotlib.pyplot as plt

from sklearn import svm, datasets

plt.rcParams['font.sans-serif'] = ['SimHei']

plt.rcParams['axes.unicode_minus'] = False

iris = datasets.load_iris()

# 为简单起见,选取前两个特征作为分类的输入特征,

# 以便在二维空间画出决策曲线

X = iris.data[:, :2]

y = iris.target

# 设置分类器SVC,核函数为rbf,gamma设置为自动调整

svc = svm.SVC(kernel="rbf", C=1, gamma="auto").fit(X, y)

# 绘图参数

x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1

y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1

h = (x_max / x_min) / 100

xx, yy = np.meshgrid(np.arange(x_min, x_max, h),

                    np.arange(y_min, y_max, h))

plt.subplot(1, 1, 1)

# 利用已有分类器进行预测

Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])

Z = Z.reshape(xx.shape)

# 绘制等高线并填充轮廓

plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)

plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)

plt.xlabel('花萼长度')

plt.ylabel('花萼宽度')

# 限制x的取值范围,便于显示

plt.xlim(xx.min(), xx.max())

plt.title('利用RBF作为核函数')

plt.show()

Sklearn SVM 自定义 rbf 核函数

【中文标题】Sklearn SVM 自定义 rbf 核函数【英文标题】:Sklearn SVM custom rbf kernel function 【发布时间】:2021-12-24 05:07:23 【问题描述】:

我正在为 sklearn 的 SVC 类创建一个自定义 rbf 函数,如下所示:

def rbf_kernel(x, y, gamma):
    dis = np.sqrt(((x.reshape(-1, 1)) - y.reshape(1, -1)) ** 2)
    return np.exp(-(gamma*dis)**2)


def eval_kernel(kernel):
    model = SVC(kernel=kernel, C=C, gamma=gamma, degree=degree, coef0=coef0)
    model.fit(X_train, y_train)
    X_test_predict = model.predict(X_test)
    acc = (X_test_predict == y_test).sum() / y_test.shape[0]
    return acc

for k1, k2 in [('rbf', lambda x, y: rbf_kernel(x, y, gamma))]:
    acc1 = eval_kernel(k1)
    acc2 = eval_kernel(k2)

    assert(abs(acc1 - acc2) < eps)

X_train 的形状是 (396, 10),y_train 是 (396, 10),X_test 是 (132, 10)。 但是,当我尝试运行它时,我收到一条错误消息:

ValueError: X.shape[1] = 3960 should be equal to 396, the number of samples at training time

错误似乎是由于X_test和X_train的维度不同,但是有什么办法可以解决这个错误吗?

提前谢谢你!

【问题讨论】:

为什么X和Y的第一个维度不相等? 【参考方案1】:

你的 rbf 内核写错了。您需要返回一个矩阵,即 (n_samples, n_samples)。在您的代码中,您基本上解开了所有内容,因此出现了错误。您可以参考actual code for rbf_kernel used by sklearn,如果我们插入它会起作用:

from sklearn.datasets import make_classification
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split

X,y = make_classification(528)

X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.25)

def my_kernel(X, Y, gamma=0.1):
    K = euclidean_distances(X, Y, squared=True)
    K *= -gamma
    np.exp(K, K)  # exponentiate K in-place
    return K

def eval_kernel(kernel):
    model = SVC(kernel=kernel,gamma=0.1)
    model.fit(X_train, y_train)
    X_test_predict = model.predict(X_test)
    acc = (X_test_predict == y_test).sum() / y_test.shape[0]
    return acc

eval_kernel('rbf')
0.8409090909090909

eval_kernel(my_kernel)
0.8409090909090909

【讨论】:

以上是关于利用RBF作为核函数的主要内容,如果未能解决你的问题,请参考以下文章

支持向量机高斯核调参小结

SVM+核函数选择

机器学习sklearn----支持向量机SVC核函数性质探索

机器学习sklearn----支持向量机SVC核函数性质探索

机器学习sklearn----支持向量机SVC核函数性质探索

机器学习sklearn----支持向量机SVC核函数性质探索