核函数:让支持向量机从“青铜”变“王者”

在机器学习领域,支持向量机(SVM)是一种强大的分类算法,而核函数则是其核心组件之一。

核函数的本质是一个「空间映射工具」。

当原始数据在低维空间中线性不可分时(如环形、月牙形数据),核函数能将数据隐式地映射到更高维的特征空间,使得在高维空间中数据变得线性可分,同时避免直接计算高维特征的爆炸性计算量(即"核技巧")。

本文将介绍核函数的作用、常用类型,并通过 scikit-learn 的实际案例展示其效果。

1. 核心作用

在许多实际场景中,数据往往不是线性可分的,直接应用线性分类器效果不佳。

核函数通过巧妙的数学变换,将数据映射到一个更高维度的空间,在这个空间中,原本线性不可分的数据可能变得线性可分。

这样,SVM 就可以在这个高维空间中找到一个最优的超平面来进行分类。

核函数的核心优势在于它避免了显式地计算高维空间中的坐标,而是通过核技巧直接计算映射后的内积。

这种方法不仅提高了计算效率,还减少了内存消耗,使得 SVM 能够高效地处理大规模数据集。

总的来说,核函数主要为了解决下面几个核心问题:

  1. 避免直接计算高维空间中的内积(维度爆炸问题,核技巧通过数学变换简化计算)
  2. 为非线性数据提供高效的分类解决方案
  3. 通过不同核函数的选择,适应多样化的数据分布特征

2. 常用核函数

一般我们在训练SVM模型时,常用的核函数主要有4种:

2.1. 线性核函数

线性核函数(Linear Kernel)是最简单的核函数,其公式为:$ K(x,y)=x^Ty $。

它适用于线性可分的数据集。

如果数据在原始空间中已经可以通过一个线性超平面进行分类,那么线性核函数是一个高效且简单的选择。

2.2. 多项式核函数

多项式核函数(Linear Kernel)的公式为:(K(x,y)=(x^Ty+c)^d)

其中, $ c $是一个常数项, $ d $是多项式的度数。

多项式核函数可以通过调整 $ d $ 和 $ c $ 的值来增加模型的复杂度,从而更好地拟合非线性数据。

它适用于数据具有多项式关系的场景。

2.3. 径向基核函数(RBF)

RBF 核函数(Radial Basis Function)是SVM中最常用的核函数之一,其公式为:(K(x,y)=exp(-frac{||x-y||^2}{2sigma^2}))

其中, $ sigma $是控制高斯分布宽度的参数。

RBF 核函数能够将数据映射到无穷维空间,具有很强的灵活性,适用于大多数非线性问题。

它对数据的局部变化非常敏感,能够很好地捕捉数据的复杂结构。

2.4. sigmoid 核函数

Sigmoid 核函数的公式为:$ K(x,y)=tanh(ax^Ty+b) $。

其中, $ a $ 和$ b $ 是参数。

Sigmoid 核函数类似于神经网络中的激活函数,它在某些特定的非线性问题中表现良好,但使用时需要谨慎调整参数,以避免过拟合或欠拟合。

3. 核函数实践

为了展示核函数的作用,我们使用scikit-learn库构造一个测试数据集,并比较不同核函数的效果。

首先,使用make_moons函数生成一个非线性可分的数据集。

这个数据集包含两个半月形的类别,用线性分类器很难进行区分。

import matplotlib.pyplot as plt from sklearn.datasets import make_moons  # 生成非线性可分的数据集 X, y = make_moons(n_samples=200, noise=0.1, random_state=42)  # 绘制数据集 plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis') plt.title("非线性可分数据集") plt.show() 

核函数:让支持向量机从“青铜”变“王者”

接下来,我们使用scikit-learnSVC(支持向量分类器)分别应用线性核函数多项式核函数RBF 核函数Sigmoid 核函数,并比较它们的效果。

from sklearn.svm import SVC from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score  # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)  # 线性核函数 svm_linear = SVC(kernel='linear') svm_linear.fit(X_train, y_train) y_pred_linear = svm_linear.predict(X_test) print("线性核函数的准确率:", accuracy_score(y_test, y_pred_linear))  # 多项式核函数 svm_poly = SVC(kernel='poly', degree=3) svm_poly.fit(X_train, y_train) y_pred_poly = svm_poly.predict(X_test) print("多项式核函数的准确率:", accuracy_score(y_test, y_pred_poly))  # RBF 核函数 svm_rbf = SVC(kernel='rbf', gamma='scale') svm_rbf.fit(X_train, y_train) y_pred_rbf = svm_rbf.predict(X_test) print("RBF 核函数的准确率:", accuracy_score(y_test, y_pred_rbf))  # Sigmoid 核函数 svm_sigmoid = SVC(kernel='sigmoid') svm_sigmoid.fit(X_train, y_train) y_pred_sigmoid = svm_sigmoid.predict(X_test) print("Sigmoid 核函数的准确率:", accuracy_score(y_test, y_pred_sigmoid)) 

运行结果:

线性核函数的准确率: 0.8833333333333333 多项式核函数的准确率: 0.95 RBF 核函数的准确率: 0.9833333333333333 Sigmoid 核函数的准确率: 0.6666666666666666 

从结果来看,线性核函数在这种非线性数据集上的表现一般,而 RBF 核函数多项式核函数取得了较好的效果,

Sigmoid 核函数表现最差,它仅在特定场景(如模拟神经网络)可能有用,其他场景下效果普遍较差。

为了更加直观,我们可以把四种核函数的分类结果绘制出来:

plt.figure(figsize=(20, 10)) models = [svm_linear, svm_poly, svm_rbf, svm_sigmoid] for i, model in enumerate(models, 1):     plt.subplot(2, 2, i)      h = 0.02  # 网格间隔     x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1     y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1     xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))     Z = model.predict(np.c_[xx.ravel(), yy.ravel()])     Z = Z.reshape(xx.shape)      plt.contourf(xx, yy, Z, alpha=0.8, cmap="viridis")     plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors="k", cmap="viridis")  plt.tight_layout() plt.show() 

核函数:让支持向量机从“青铜”变“王者”

4. 总结

核函数是支持向量机中不可或缺的组成部分,它通过将数据映射到高维空间,解决了线性不可分问题,使 SVM 能够处理复杂的非线性分类任务。

在实际应用中,选择合适的核函数至关重要。

线性核函数适用于线性可分数据,多项式核函数RBF 核函数则更适合处理非线性问题。

通过基于scikit-learn的实验,我们直观地看到了核函数在不同数据集上的效果差异。

在实际项目中,建议根据数据的特点和需求选择合适的核函数,并通过交叉验证等方法调整参数,以达到最佳的分类效果。

发表评论

评论已关闭。

相关文章