核函数基础:从线性不可分到高维映射

说实话,我刚接触机器学习那会儿,对核函数也是一头雾水。当时我在做一个文本分类项目,数据在二维空间里根本分不开,就像一团乱麻。后来导师跟我说:「试试核函数吧。」我试了,效果出奇的好。今天我就把这块硬骨头给你啃下来。

什么是核函数?

核函数,说白了就是一个特殊的函数。它接收两个样本点作为输入,输出一个实数。这个实数代表了这两个样本在某个高维空间中的相似度。

你可能会问:「这不就是计算相似度吗?有什么特别的?」

嗯,特别之处在于——它不需要你显式地把数据映射到高维空间。直接算就行。我习惯把核函数比作「隐形传送门」:你输入低维数据,它直接给你高维空间的内积结果,中间过程完全黑盒。

核函数的数学定义:

设 χ 是输入空间(通常是低维欧氏空间),存在一个映射 φ: χ → H,其中 H 是希尔伯特空间(高维特征空间)。核函数 K 满足:

K(x, z) = ⟨φ(x), φ(z)⟩

其中 ⟨·,·⟩ 表示 H 中的内积。

核函数在机器学习中的角色

核函数在机器学习里扮演的角色,我总结为三个关键词:升维、内积、隐式计算。

  • 解决线性不可分问题:原始空间里分不开的数据,映射到高维后往往就线性可分了。我在做手写数字识别时遇到过这种情况,原始像素特征根本分不清 0 和 6,用了 RBF 核之后,准确率直接提升了 15%。
  • 降低计算复杂度:直接做高维映射,计算量是灾难性的。核函数让你在低维空间里完成高维计算,复杂度从 O(d²) 降到 O(d),d 是原始维度。
  • 构建非线性模型:在 SVM、PCA、线性回归等算法中嵌入核函数,就能把它们变成非线性版本。这就是所谓的「核化」。
算法 无核函数 有核函数
SVM 线性分类器 非线性分类器
PCA 线性降维 非线性降维(KPCA)
线性回归 线性拟合 非线性拟合(KRR)

核技巧的本质

核技巧,英文叫 Kernel Trick。它的本质就一句话:用低维空间的内积计算,替代高维空间的内积计算。

举个例子。假设有两个二维样本 x = (x₁, x₂),z = (z₁, z₂)。我想把它们映射到三维空间:

φ(x) = (x₁², x₂², √2·x₁·x₂)

直接计算高维内积:

⟨φ(x), φ(z)⟩ = x₁²·z₁² + x₂²·z₂² + 2·x₁·x₂·z₁·z₂

这个计算量还行。但如果映射到 1000 维呢?直接算就炸了。

现在用核技巧。我定义一个核函数:

K(x, z) = (⟨x, z⟩)²

展开看看:

K(x, z) = (x₁·z₁ + x₂·z₂)²
        = x₁²·z₁² + x₂²·z₂² + 2·x₁·x₂·z₁·z₂

发现没?结果和 ⟨φ(x), φ(z)⟩ 一模一样!但计算量从 O(d²) 降到了 O(d)。

我的经验之谈: 核技巧最妙的地方在于,你甚至不需要知道 φ 的具体形式。只要核函数满足 Mercer 条件(对称且半正定),它就对应某个特征空间中的内积。我曾经踩过一个坑:自己随便定义了一个核函数,结果训练出来的模型完全不收敛。后来一查,那个核函数不满足 Mercer 条件。所以记住:不是所有函数都能当核函数用。

常见核函数一览

实际项目中,我常用的核函数就这几种:

  • 线性核:K(x, z) = ⟨x, z⟩。说白了就是不做映射,适合数据本来就线性可分的情况。
  • 多项式核:K(x, z) = (⟨x, z⟩ + c)ᵈ。d 控制复杂度,c 控制偏移。我一般 d 不超过 3,否则容易过拟合。
  • RBF 核(高斯核):K(x, z) = exp(-γ||x - z||²)。最常用的核函数,没有之一。γ 参数很敏感,我习惯用网格搜索调参。
  • Sigmoid 核:K(x, z) = tanh(α⟨x, z⟩ + c)。某些情况下等价于两层神经网络。

避坑指南: 我曾经在图像分类任务中直接用了 RBF 核,结果训练时间长得离谱。后来发现图像特征维度太高(几千维),RBF 核的 Gram 矩阵计算量是 O(n²·d),n 是样本数。对于高维稀疏数据,线性核往往更高效。记住:核函数不是越复杂越好,适合数据特点才是王道。

核函数的知识体系

下面这张图是我自己梳理的核函数知识结构,帮你快速建立全局认知:

核函数 Kernel 数学定义 Mercer条件 正定性 核技巧本质 隐式映射 低维计算 常见核函数 线性核 多项式核 RBF核 应用:SVM / PCA / 回归 / 聚类 ⚠ 注意事项 核函数选择需结合数据特性,参数调优推荐网格搜索

这张图把核函数的核心脉络理清楚了。从上到下依次是:数学基础 → 核心技巧 → 具体实现 → 实际应用。你想想看,掌握了这个框架,以后遇到任何核函数相关的问题,都能快速定位到对应环节。

核函数与核矩阵

实际编程中,我们很少直接操作核函数。我们操作的是核矩阵(Gram 矩阵)。

给定 n 个样本,核矩阵 K 是一个 n×n 的矩阵,其中 Kᵢⱼ = K(xᵢ, xⱼ)。

核矩阵有两个重要性质:

  • 对称性:Kᵢⱼ = Kⱼᵢ
  • 半正定性:对任意向量 v,有 vᵀKv ≥ 0

这两个性质保证了核函数对应的特征空间是合法的。我在项目中调试核函数时,第一件事就是检查核矩阵是否半正定。如果发现特征值出现负数(由于浮点误差可能极小负数),我会加一个小量 ε 到对角线上做正则化。

# 核矩阵计算示例(Python伪代码)
def compute_kernel_matrix(X, kernel_func):
    n = X.shape[0]
    K = np.zeros((n, n))
    for i in range(n):
        for j in range(n):
            K[i, j] = kernel_func(X[i], X[j])
    # 检查半正定性
    eigenvalues = np.linalg.eigvalsh(K)
    if np.min(eigenvalues) < -1e-10:
        print("警告:核矩阵不是半正定的!")
    return K

小技巧: 实际工程中,我很少自己写核矩阵计算。Scikit-learn 提供了现成的 pairwise_kernels 函数,支持多种核函数,而且底层用 C 加速,比 Python 循环快两个数量级。你想想看,10000 个样本的核矩阵,自己写循环可能要跑几分钟,用现成函数几秒钟就搞定了。

好了,核函数的基础就讲到这里。记住三个核心点:核函数是隐式高维映射的桥梁,核技巧是低维计算高维内积的魔法,核矩阵是实际编程中的操作对象。把这些吃透了,后面学核 SVM、核 PCA 就会轻松很多。

想要更多资料,联系可可