核函数,是SVM中为了能够找到非线性数据的线性决策边界,将数据从原始空间x投射到新空间φ(x)的映射关系,SVM中常用的核函数有linear、poly、sigmoid、rbf。

核函数运用场景

linear(线性核):解决线性问题

poly(多项式核):解决偏线性问题

sigmoid(双曲正切核):解决非线性问题

rbf(高斯径向基):解决偏非线性问题

代码示例

1、构造多种数据集

from sklearn.datasets import make_circles, make_blobs, make_moons, make_classification
import matplotlib.pyplot as plt

n_samples = 200

datasets = [
    make_circles(n_samples, factor=0.3, noise=0.2, random_state=0),
    make_moons(n_samples, noise=0.2, random_state=0),
    make_blobs(n_samples, centers=2, random_state=0),
    make_classification(n_samples, n_features=2, n_redundant=0, random_state=0)
]

fig, axes = plt.subplots(2, 2, figsize=(7,7))

for i, (x, y) in enumerate(datasets):
    axes.flat[i].scatter(x[:, 0], x[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.show()

2、创建对比子图

4类数据,对比+4个核函数,总共创建4x5个子图。

from sklearn.svm import SVC
import numpy as np

kernel = ['linear', 'poly', 'rbf', 'sigmoid']

nrows = len(datasets)
ncols = len(kernel) + 1

fig, axes = plt.subplots(nrows, ncols, figsize=(20, 16), subplot_kw={'xticks': [], 'yticks': []})

for row in range(nrows):
    # 画原图
    x, y = datasets[row]
    axes[0][0].set_title('Input')
    axes[row][0].scatter(x[:, 0], x[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k', zorder=10)

plt.tight_layout()
plt.show()

3、效果对比

遍历核函数和数据集,分类并画出决策边界。

# 建模
clf = SVC(kernel=k).fit(x, y)
# 获取分数
score = clf.score(x, y)
# 构建网格,找决策边界
x0_min, x0_max = x[:, 0].min() - 0.5, x[:, 0].max() + 0.5
x1_min, x1_max = x[:, 1].min() - 0.5, x[:, 1].max() + 0.5
# 等分坐标范围
x0, x1 = np.mgrid[x0_min:x0_max:200j, x1_min:x1_max:200j]
# 计算坐标点到决策边界的距离
r = clf.decision_function(np.c_[x0.ravel(), x1.ravel()]).reshape(x0.shape)
# 填充颜色
ax.pcolormesh(x0, x1, r > 0, cmap=plt.cm.Paired)
# 绘制等高线
ax.contour(x0, x1, r, colors=['k', 'k', 'k'], linestyles=['--', '-', '--'], levels=[-1, 0, 1])
# 填充分数
ax.text(0.95, 0.06, ('%.2f' % score).lstrip('0')
        , size=12
        , zorder=15
        # 为分数添加一个白色的格子作为底色
        , bbox=dict(boxstyle='round', alpha=0.8, facecolor='white')
        # 确定文字所对应的坐标轴,就是ax子图的坐标轴本身
        , transform=ax.transAxes
        # 位于坐标轴的什么方向
        , horizontalalignment='right'
    )

对比可见,在四种不同数据集上,rbf都有不错的表现,这也是SVM中,最常用的一个核函数。

本文为 陈华 原创,欢迎转载,但请注明出处:http://ichenhua.cn/read/285