在机器学习领域,支持向量机(SVM
)是一种强大的分类算法,而核函数则是其核心组件之一。
核函数的本质是一个「空间映射工具」。
当原始数据在低维空间中线性不可分时(如环形、月牙形数据),核函数能将数据隐式地映射到更高维的特征空间,使得在高维空间中数据变得线性可分,同时避免直接计算高维特征的爆炸性计算量(即"核技巧")。
本文将介绍核函数的作用、常用类型,并通过 scikit-learn 的实际案例展示其效果。
1. 核心作用
在许多实际场景中,数据往往不是线性可分的,直接应用线性分类器效果不佳。
核函数通过巧妙的数学变换,将数据映射到一个更高维度的空间,在这个空间中,原本线性不可分的数据可能变得线性可分。
这样,SVM
就可以在这个高维空间中找到一个最优的超平面来进行分类。
核函数的核心优势在于它避免了显式地计算高维空间中的坐标,而是通过核技巧直接计算映射后的内积。
这种方法不仅提高了计算效率,还减少了内存消耗,使得 SVM
能够高效地处理大规模数据集。
总的来说,核函数主要为了解决下面几个核心问题:
- 避免直接计算高维空间中的内积(维度爆炸问题,核技巧通过数学变换简化计算)
- 为非线性数据提供高效的分类解决方案
- 通过不同核函数的选择,适应多样化的数据分布特征
2. 常用核函数
一般我们在训练SVM
模型时,常用的核函数主要有4种:
2.1. 线性核函数
线性核函数 (Linear Kernel)是最简单的核函数,其公式为: <math xmlns="http://www.w3.org/1998/Math/MathML"> K ( x , y ) = x T y K(x,y)=x^Ty </math>K(x,y)=xTy。
它适用于线性可分的数据集。
如果数据在原始空间中已经可以通过一个线性超平面进行分类,那么线性核函数是一个高效且简单的选择。
2.2. 多项式核函数
多项式核函数 (Linear Kernel)的公式为: <math xmlns="http://www.w3.org/1998/Math/MathML"> K ( x , y ) = ( x T y + c ) d K(x,y)=(x^Ty+c)^d </math>K(x,y)=(xTy+c)d。
其中, <math xmlns="http://www.w3.org/1998/Math/MathML"> c c </math>c是一个常数项, <math xmlns="http://www.w3.org/1998/Math/MathML"> d d </math>d是多项式的度数。
多项式核函数 可以通过调整 <math xmlns="http://www.w3.org/1998/Math/MathML"> d d </math>d 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> c c </math>c 的值来增加模型的复杂度,从而更好地拟合非线性数据。
它适用于数据具有多项式关系的场景。
2.3. 径向基核函数(RBF)
RBF 核函数 (Radial Basis Function)是SVM
中最常用的核函数之一,其公式为: <math xmlns="http://www.w3.org/1998/Math/MathML"> K ( x , y ) = e x p ( − ∣ ∣ x − y ∣ ∣ 2 2 σ 2 ) K(x,y)=exp(-\frac{||x-y||^2}{2\sigma^2}) </math>K(x,y)=exp(−2σ2∣∣x−y∣∣2)。
其中, <math xmlns="http://www.w3.org/1998/Math/MathML"> σ \sigma </math>σ是控制高斯分布宽度的参数。
RBF 核函数能够将数据映射到无穷维空间,具有很强的灵活性,适用于大多数非线性问题。
它对数据的局部变化非常敏感,能够很好地捕捉数据的复杂结构。
2.4. sigmoid 核函数
Sigmoid 核函数 的公式为: <math xmlns="http://www.w3.org/1998/Math/MathML"> K ( x , y ) = tanh ( a x T y + b ) K(x,y)=\tanh(ax^Ty+b) </math>K(x,y)=tanh(axTy+b)。
其中, <math xmlns="http://www.w3.org/1998/Math/MathML"> a a </math>a和 <math xmlns="http://www.w3.org/1998/Math/MathML"> b b </math>b是参数。
Sigmoid 核函数类似于神经网络中的激活函数,它在某些特定的非线性问题中表现良好,但使用时需要谨慎调整参数,以避免过拟合或欠拟合。
3. 核函数实践
为了展示核函数的作用,我们使用scikit-learn
库构造一个测试数据集,并比较不同核函数的效果。
首先,使用make_moons
函数生成一个非线性可分的数据集。
这个数据集包含两个半月形的类别,用线性分类器很难进行区分。
python
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-learn
的SVC
(支持向量分类器)分别应用线性核函数 、多项式核函数 、RBF 核函数 和 Sigmoid 核函数,并比较它们的效果。
python
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))
运行结果:
plain
线性核函数的准确率: 0.8833333333333333
多项式核函数的准确率: 0.95
RBF 核函数的准确率: 0.9833333333333333
Sigmoid 核函数的准确率: 0.6666666666666666
从结果来看,线性核函数 在这种非线性数据集上的表现一般,而 RBF 核函数 和多项式核函数取得了较好的效果,
Sigmoid 核函数表现最差,它仅在特定场景(如模拟神经网络)可能有用,其他场景下效果普遍较差。
为了更加直观,我们可以把四种核函数的分类结果绘制出来:
python
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
的实验,我们直观地看到了核函数在不同数据集上的效果差异。
在实际项目中,建议根据数据的特点和需求选择合适的核函数,并通过交叉验证等方法调整参数,以达到最佳的分类效果。