06 非线性模型

90 分钟学习安排:何时需要非线性?

  • 目标:
    • 比较分段、QDA 与核方法;

    • 计算包含先验和行列式项的 QDA 分数;

    • 检查 Gram 矩阵;

    • 区分“事先选择模型的测试期描述”与“在训练期验证上选择复杂度”。

  • 课堂安排:
    • 基础回顾与非线性问题 15 分钟 → QDA 25 分钟 → 核技巧 20 分钟 → 福耀玻璃案例 20 分钟 → 测试数据使用检查 10 分钟。

    • KPCA/KSVM 推导为拓展内容。

  • 先修先答: 两类均值相同但协方差不同,LDA 与 QDA 中谁能利用这一差异?
  • 反馈: QDA;它为每类估计 \(\Sigma_k\),代价是参数更多、方差更大。

本章核心问题

当现实世界不是线性时,我们该怎么办?

我们之前的学习大多集中在线性模型,它们是计量经济学和机器学习的基石。

但是,现实世界中的经济和金融关系往往是复杂的、非线性的。

线性模型的局限性:一个直观例子

假设我们用线性回归拟合一组明显呈曲线关系的数据。

线性边界 ✕ 同心圆数据 → 需要曲线边界

观察

模型系统性地低估了两端,高估了中间。均方误差(MSE)很高。

现实中的非线性关系

  • 信贷违约风险:
    • 收入与违约率的关系可能不是线性的。

    • 极低和极高收入人群的风险可能都较低,而中等收入人群由于过度杠杆,风险反而更高。

  • 资产收益率: 资产收益与市场因子的关系(Beta)可能随市场波动性变化而变化,呈现非线性。
  • 消费者行为: 价格折扣对销量的提升效应会逐渐减弱,呈现饱和曲线,而非直线。

我们的探索之旅:三条非线性路径

本章我们将系统地学习三类强大的非线性模型,以应对线性模型的局限性。

非线性模型探索路径 依次展示三种非线性模型:分段线性、二次判别分析(QDA)和核方法。 起点 线性模型 1. 分段线性 用多条直线逼近 2. QDA 直接拟合曲线 3. 核方法 (Kernel Trick) 升维打击,化曲为直

第一部分:分段线性判别

分段线性判别:最直观的“蛮力”方法

核心思想

如果一条直线不行,那就用多条直线来拼接和逼近。

. . .

这个策略通常分为两步:

  1. 子类划分 (Subclass Partitioning): 将原始的某一类(例如蓝色点)进一步细分为多个子类,使得每个子类都能够与其他类别线性可分。
  2. 同类合并 (Class Merging): 在做出最终决策时,将所有属于同一原始大类的子类的预测结果合并。

分段线性判别的几何直观 (1/3)

首先,我们有一个无法被单一直线分开的数据集。

初始非线性分类问题 一个无法被线性模型完美分割的典型数据集,其中紫色点和蓝色点呈月亮形分布。 客户指标 1 客户指标 2 存在风险 (Class 0) 信用良好 (Class 1)

分段线性判别的几何直观 (2/3)

我们将“信用良好”(蓝色)的客户群体,想象成两个潜在的子群体。然后我们用两条不同的直线来分割。

  • 直线1: 分开了紫色群体和蓝色“左下”子群体。
  • 直线2: 分开了紫色群体和蓝色“右上”子群体。
分段线性判别思想 紫色和蓝色点集,被两条独立的红色和橙色虚线分割。 直线 1 直线 2

分段线性判别的几何直观 (3/3)

最终的决策边界,是由这两条直线的一部分组合而成的“V”形。

最终的分段线性边界 两条直线的一部分组成一个V形,分割了数据点。 最终决策边界

关联思想:决策树

决策树模型本质上也是在进行一种分段划分。它通过一系列与坐标轴平行的“分割”,将特征空间切分成多个矩形区域。

决策树与空间划分 左侧是一个简单的决策树,右侧是其在二维特征空间中对应的矩形划分。 X1 < 0.5? 类别 0 X2 < 0.6? 类别 1 类别 0 特征空间 特征 X1 特征 X2 X1 = 0.5 X2 = 0.6

分段线性判别的优势与局限

优势 (Pros) 局限 (Cons)
思想简单,易于理解 如何划分子类是关键难题
可以利用现有的线性模型算法 子类数量需要预先设定 (超参数)
只要分段足够多,可以拟合任意复杂的形状 容易产生过拟合 (Overfitting)
与决策树等模型思想相通 模型的“整体性”和“优雅性”不足

结论

分段线性判别是一个有效的“启发式”方法,但在实践中,我们通常寻求更系统、更优雅的解决方案。

第二部分:二次判别分析 (QDA)

QDA:不再满足于逼近,直接拟合曲线

二次判别分析 (Quadratic Discriminant Analysis, QDA) 不再用多条直线拼接,而是直接构建一个二次型的决策边界。

对于我们的月亮型数据,一条优美的抛物线就可以很好地完成分类任务。

QDA的二次边界 一条红色的抛物线优雅地分割了紫色和蓝色的数据点。 二次决策边界

QDA判别函数的形式

QDA 的判别函数 \(f(\mathbf{x}_n)\) 是一个关于输入向量 \(\mathbf{x}_n\) 的二次函数:

\[ \large{ f(\mathbf{x}_n, \mathbf{W}, \mathbf{w}, b) = \mathbf{x}_n^T \mathbf{W} \mathbf{x}_n + \mathbf{w}^T \mathbf{x}_n + b } \]

  • \(\mathbf{x}_n \in \mathbb{R}^d\): d维的特征向量。
  • \(\mathbf{W} \in \mathbb{R}^{d \times d}\): 二次项系数矩阵,它“掰弯”了决策边界。
  • \(\mathbf{w} \in \mathbb{R}^d\): 线性项系数向量,它“平移”决策边界。
  • \(b \in \mathbb{R}\): 偏置项。

QDA的核心:二次项矩阵 \(\mathbf{W}\)

在判别函数中,真正让 QDA 具有非线性能力的是二次项 \(\mathbf{x}_n^T \mathbf{W} \mathbf{x}_n\)

  • 如果 \(\mathbf{W} = \mathbf{0}\),那么 QDA 就退化为了我们熟悉的线性判别分析 (LDA)。决策边界是线性的。
  • 如果 \(\mathbf{W} \neq \mathbf{0}\),决策边界 \(f(\mathbf{x}_n) = 0\) 就是一个二次曲面 (在二维空间中是圆锥曲线,如椭圆、抛物线、双曲线)。

\(\mathbf{W}\) 的几何意义:决定边界形状

不同的 \(\mathbf{W}\) 矩阵可以生成各种形状的二次曲面边界。

W矩阵决定边界形状 三个子图分别展示了椭圆、抛物线和双曲线形状的决策边界。 椭圆 抛物线 双曲线

QDA的“代价”:参数数量的爆炸

这种灵活性是有代价的。我们来数一下模型的参数个数:

  • 矩阵 \(\mathbf{W}\): 由于 \(\mathbf{W}\) 可以被假定为对称矩阵,它有 \(d(d+1)/2\) 个独立参数。
  • 向量 \(\mathbf{w}\): 有 \(d\) 个参数。
  • 标量 \(b\): 有 \(1\) 个参数。

总参数数量为 \(\frac{d(d+1)}{2} + d + 1\),大约为 \(O(d^2)\)

参数数量爆炸的后果

特征维度 (d) QDA 参数数量 (约 d²/2)
2 6
10 66
50 1,326
100 5,151
1000 ~500,000

这会带来两个严峻的实际问题:

  1. 计算量巨大: 求解一个包含 \(d^2\) 级别参数的模型非常耗时。
  2. 样本需求量大: 要稳健地估计这么多参数,需要非常大的样本量,否则极易过拟合。

从概率视角理解QDA:更实用的路径

实践中,我们不直接去拟合那个庞大的 \(\mathbf{W}\) 矩阵,而是通过概率生成模型的思路来推导 QDA。

核心假设: 我们假设每个类别 \(k\) 的数据都服从一个多元高斯分布 (Multivariate Gaussian Distribution)。

\[ \large{ p(\mathbf{x} | y=k) = \mathcal{N}(\mathbf{x} | \boldsymbol{\mu}_k, \boldsymbol{\Sigma}_k) } \]

  • \(\boldsymbol{\mu}_k\): 第 \(k\) 类的数据均值向量(分布的中心)。
  • \(\boldsymbol{\Sigma}_k\): 第 \(k\) 类的数据协方差矩阵(分布的形状和方向)。

QDA与LDA的关键区别:协方差矩阵

QDA 和 LDA 都假设数据服从高斯分布,但它们对协方差矩阵的假设不同。

  • LDA (线性判别分析): 假设所有类别的协方差矩阵是相同的。 \(\boldsymbol{\Sigma}_1 = \boldsymbol{\Sigma}_2 = \dots = \boldsymbol{\Sigma}_K = \boldsymbol{\Sigma}\) 这个强假设导致了线性的决策边界。

  • QDA (二次判别分析): 假设每个类别的协方差矩阵可以是不同的。 \(\boldsymbol{\Sigma}_i \neq \boldsymbol{\Sigma}_j\) for \(i \neq j\) 这个更宽松的假设,恰恰是产生二次决策边界的根源。

可视化对比:LDA vs. QDA 的假设

可视化对比:LDA vs. QDA 的假设 图中以“线性判别分析 (LDA)、假设: 共同协方差 (Σ₁ = Σ₂)、形状相同的等高线、交点决定了线性边界、二次判别分析 (QDA)”呈现“可视化对比:LDA vs. QDA 的假设”涉及的对象、方向或比较关系。 线性判别分析 (LDA) 假设: 共同协方差 (Σ₁ = Σ₂) 同形等高线 → 线性边界 二次判别分析 (QDA) 假设: 各自协方差 (Σ₁ ≠ Σ₂) 异形等高线 → 二次边界

QDA判别函数的推导

  • 根据贝叶斯定理,后验概率 \(P(y=k|\mathbf{x}) \propto p(\mathbf{x}|y=k) P(y=k)\)

  • 取对数并展开高斯分布的概率密度函数,我们得到的判别函数(忽略常数项)为:

\[ \large{ \delta_k(\mathbf{x}) = -\frac{1}{2} \log |\boldsymbol{\Sigma}_k| - \frac{1}{2} (\mathbf{x} - \boldsymbol{\mu}_k)^T \boldsymbol{\Sigma}_k^{-1} (\mathbf{x} - \boldsymbol{\mu}_k) + \log \pi_k } \]

这是一个关于 \(\mathbf{x}\) 的二次函数!其中二次项来自于 \(\mathbf{x}^T \boldsymbol{\Sigma}_k^{-1} \mathbf{x}\)

什么是马氏距离 (Mahalanobis Distance)?

QDA 判别函数的核心是马氏距离的平方:

\[ \large{ D_M^2(\mathbf{x}, \boldsymbol{\mu}_k) = (\mathbf{x} - \boldsymbol{\mu}_k)^T \boldsymbol{\Sigma}_k^{-1} (\mathbf{x} - \boldsymbol{\mu}_k) } \]

  • 直观理解: 它衡量了一个点 \(\mathbf{x}\) 到一个分布中心 \(\boldsymbol{\mu}_k\) 的“统计距离”。
  • 它考虑了数据本身的协方差结构 \(\boldsymbol{\Sigma}_k\)。如果数据在某个方向上变化很大(方差大),那么在这个方向上的距离就会被“缩小”。
  • QDA 不能只比较马氏距离;还必须比较每类的 \(-\tfrac12\log|\Sigma_k|\) 体积惩罚与 \(\log\pi_k\) 先验项。

可视化:欧氏距离 vs. 马氏距离

可视化:欧氏距离 vs. 马氏距离 图中以“直观与形式:全面理解马氏距离、欧氏距离: d(A,μ) ≈ d(B,μ)、1σ、2σ、3σ”呈现“可视化:欧氏距离 vs. 马氏距离”涉及的对象、方向或比较关系。 欧氏距离与马氏距离 欧氏距离:A 与 B 相等 μ A B Δd Δd 欧氏:原坐标尺度 马氏:协方差重标度

结论: 点A在数据分布的“长轴”方向上,虽然欧氏距离远,但统计上更“近”。

QDA决策规则

对于一个二分类问题 (类别 \(\omega_1, \omega_2\)),我们可以定义一个判别函数 \(f_i(\mathbf{x})\):

\[ \large{ f_i(\mathbf{x}) = \log\pi_i - \frac{1}{2}\log|\boldsymbol{\Sigma}_i| - \frac{1}{2}(\mathbf{x} - \boldsymbol{\mu}_i)^T \boldsymbol{\Sigma}_i^{-1} (\mathbf{x} - \boldsymbol{\mu}_i) } \]

决策规则:

  • 如果 \(f_1(\mathbf{x}) \geq f_2(\mathbf{x})\),则预测为类别 \(\omega_1\)
  • 否则,预测为类别 \(\omega_2\)

由于每个类的 \(f_i(\mathbf{x})\) 都有自己的协方差矩阵 \(\boldsymbol{\Sigma}_i\),决策边界 \(f_1(\mathbf{x}) = f_2(\mathbf{x})\) 是一个二次函数。

QDA总结:何时应该使用它?

  • 适用场景:
    • 当你相信不同类别的数据具有不同的协方差结构时,QDA是一个很好的选择。

    • 它在LDA和更复杂的非参数方法(如K-近邻)之间提供了一个很好的平衡。

  • 优点: 模型形式明确,比许多非线性方法(如核SVM)的计算成本更低。
  • 缺点: 对高斯分布的假设较强。当特征维度 \(d\) 很高时,参数数量会变得非常大,需要大量数据来避免过拟合,且计算成本高。

第三部分:核方法 (The Kernel Trick)

核方法:一个“改变游戏规则”的思想

QDA虽然有效,但它只局限于二次函数。如果我们想拟合更复杂的边界怎么办?

核方法 (Kernel Method) 提供了一个极其优雅和强大的思路:

我们不直接在原始的低维空间中学习一个复杂的非线性模型,而是将数据通过一个非线性映射 \(\phi(\mathbf{x})\) 投射到一个更高维度的“特征空间”,然后在这个高维空间中学习一个简单的线性模型。

这个思想,通常被称为“核技巧 (Kernel Trick)”,是现代机器学习的基石之一。

核方法的核心直观:升维打击 (1/3)

想象一下一维空间中的一些数据点,它们无法被一个“点”(0维超平面)分开。

一维线性不可分数据 一条线上分布着两种颜色的点,无法用一个分割点分开。 x 问题:无法用一个点把蓝色和紫色分开

核方法的核心直观:升维打击 (2/3)

我们定义一个简单的非线性映射 \(\phi(x) = (x, x^2)\),将一维数据点 \(x\) 映射到二维空间。

从一维到二维的映射 展示了x到(x, x^2)的映射过程,点被提升到抛物线上。 x 映射: φ(x) = (x, x²)

核方法的核心直观:升维打击 (3/3)

奇迹发生了! 在这个新的二维空间里,数据点变得可以用一条直线分开了。

二维空间中的线性可分性 之前不可分的点在映射到二维后,可以被一条红线分开。 x 现在,数据是线性可分的!

核方法的完整流程图

核方法的完整流程图 图中以“核方法 (The Kernel Trick)、1. 输入空间 (Input Space)、非线性可分 (Non-linearly Separable)、φ(x)、2. 特征空间 (Feature Space)”呈现“核方法的完整流程图”涉及的对象、方向或比较关系。 核方法 (The Kernel Trick) 1. 输入空间 非线性可分 φ(x) 2. 特征空间 线性可分

映射后的新家:希尔伯特空间

  • 这个映射 \(\phi(\mathbf{x})\) 去往的高维空间,在数学上被称为特征空间

  • 为了让我们的数学工具(如距离、角度)能够正常工作,我们要求这个空间是一个希尔伯特空间 (Hilbert Space)

对于我们经济系的学生,你不需要深入了解它的严格数学定义。可以这样直观理解:

一个希尔伯特空间,就是一个行为表现良好的、可能无穷维的广义欧几里得空间。

在这里,我们可以像在普通空间一样,放心地计算长度、距离和角度。

希尔伯特空间的关键性质:内积

希尔伯特空间最重要的性质是它定义了内积 (Inner Product),我们记为 \(\langle \cdot, \cdot \rangle_{\mathcal{H}}\)

内积是我们熟悉的点积 (dot product) 的推广:

\[ \begin{aligned} \langle \mathbf{x}_1, \mathbf{x}_2 \rangle &= \mathbf{x}_1^T \mathbf{x}_2 = \sum_{i=1}^d x_{1,i}x_{2,i}, \\ \langle \mathbf{x}_1, \mathbf{x}_2 \rangle &= \lVert\mathbf{x}_1\rVert\,\lVert\mathbf{x}_2\rVert\cos\theta. \end{aligned} \]

有了内积,我们就可以定义范数 (Norm, 即长度)距离 (Distance),就像在欧氏空间中一样。内积还包含了向量间夹角的信息,因此可以衡量相似度

核技巧的“魔法”所在

我们回顾一下,很多线性算法(如SVM, PCA, 线性回归)的最终计算都可以只用样本点的内积 \(\langle \mathbf{x}_i, \mathbf{x}_j \rangle\) 来表示。

那么,如果我们将数据映射到高维空间 \(\phi(\mathbf{x})\),算法就需要计算映射后的内积 \(\langle \phi(\mathbf{x}_i), \phi(\mathbf{x}_j) \rangle_{\mathcal{H}}\)

问题:

  1. 映射函数 \(\phi(\mathbf{x})\) 可能非常复杂,甚至我们都不知道它的显式形式。
  2. 高维空间的维度可能非常高,甚至是无穷维,直接计算内积是不可能的。

核函数:通往高维空间的捷径

核函数 (Kernel Function) \(K(\mathbf{x}_i, \mathbf{x}_j)\) 的定义就是为了解决这个问题:

一个函数 \(K(\mathbf{x}_i, \mathbf{x}_j)\) 如果能被写成某个映射 \(\phi\) 在高维空间中的内积形式,即 \(K(\mathbf{x}_i, \mathbf{x}_j) = \langle \phi(\mathbf{x}_i), \phi(\mathbf{x}_j) \rangle_{\mathcal{H}}\),那么这个函数 \(K\) 就是一个核函数。

核技巧的精髓

  • 我们可以直接计算 \(K(\mathbf{x}_i, \mathbf{x}_j)\),而不显式构造 \(\phi(\mathbf{x})\) 的高维坐标。

  • 这节省的是特征展开的计算与存储;它并不消除高维模型的统计困难、样本复杂度或过拟合风险。

例子:一个简单的二次核函数

假设我们的原始数据是二维的 \(\mathbf{x} = (x_1, x_2)\)。 考虑一个简单的核函数: \(K(\mathbf{x}_i, \mathbf{x}_j) = (\mathbf{x}_i^T \mathbf{x}_j)^2\)

让我们展开它:

\[ \begin{aligned} \large{ K(\mathbf{x}_i, \mathbf{x}_j) } &= \large{ (x_{i1}x_{j1} + x_{i2}x_{j2})^2 } \\ &= \large{ x_{i1}^2x_{j1}^2 + x_{i2}^2x_{j2}^2 + 2x_{i1}x_{j1}x_{i2}x_{j2} } \\ &= \large{ \langle (x_{i1}^2, x_{i2}^2, \sqrt{2}x_{i1}x_{i2}), (x_{j1}^2, x_{j2}^2, \sqrt{2}x_{j1}x_{j2}) \rangle } \end{aligned} \]

这说明,这个简单的核函数背后隐含了一个从二维到三维的映射: \(\phi(\mathbf{x}) = (x_1^2, x_2^2, \sqrt{2}x_1x_2)\)

  • 直接计算该二次核需要两次分量乘法、一次加法和一次平方。

  • 核技巧节省的是显式构造三维特征并再做内积的存储与中间计算,而不是把二维核值化简成“一次乘法”。

如何判断一个函数是合法的核函数?

一个函数 \(K(\mathbf{x}_i, \mathbf{x}_j)\) 必须满足什么条件,才能保证它背后一定存在一个希尔伯特空间和一个映射 \(\phi\) 呢?

Mercer 定理给出了答案:

对于任意有限的数据点集合 \(\{\mathbf{x}_1, \dots, \mathbf{x}_N\}\),如果由核函数计算出的 Gram 矩阵 \(\mathbf{K}\) 都是半正定的,那么 \(K\) 就是一个合法的核函数。

什么是Gram矩阵?

Gram 矩阵 \(\mathbf{K}\) 是一个 \(N \times N\) 的对称矩阵,其中每个元素 \(K_{ij}\) 都是由第 \(i\) 个和第 \(j\) 个数据点通过核函数计算得到的值:

\[ \large{ \mathbf{K} = \begin{pmatrix} K(\mathbf{x}_1, \mathbf{x}_1) & K(\mathbf{x}_1, \mathbf{x}_2) & \dots & K(\mathbf{x}_1, \mathbf{x}_N) \\ K(\mathbf{x}_2, \mathbf{x}_1) & K(\mathbf{x}_2, \mathbf{x}_2) & \dots & K(\mathbf{x}_2, \mathbf{x}_N) \\ \vdots & \vdots & \ddots & \vdots \\ K(\mathbf{x}_N, \mathbf{x}_1) & K(\mathbf{x}_N, \mathbf{x}_2) & \dots & K(\mathbf{x}_N, \mathbf{x}_N) \end{pmatrix} } \]

直观理解

Gram 矩阵是一个成对相似度矩阵,描述了数据集中所有样本点之间的关系。半正定性保证了这种“相似度”是几何上一致的(没有自相矛盾)。

常用核函数:你的“弹药库”

幸运的是,我们不需要每次都自己去验证 Mercer 定理。有很多现成的、被证明是合法的核函数供我们使用。

选择核函数的基本原则

  • 先保证对称 Gram 矩阵半正定,再依据任务含义、缩放方式和无泄漏验证选择核与超参数。

  • 只有在特定核和已定义的相似度下,核值才可作单调相似度解释;

  • 例如 RBF 核随标准化后的欧氏距离单调下降,而未归一化线性核并不满足这一普遍规则。

接下来我们介绍几种最常用的核函数。

常用核函数1:线性核 (Linear Kernel)

\[ \large{ K(\mathbf{x}_i, \mathbf{x}_j) = \mathbf{x}_i^T \mathbf{x}_j } \]

  • 本质: 就是原始空间中的点积。
  • 对应映射: \(\phi(\mathbf{x}) = \mathbf{x}\),即没有进行映射。
  • 应用: 当数据本身就是线性可分时,使用线性核的SVM就是标准的线性SVM。这是最简单、最快的基准。

常用核函数2:多项式核

\[ \large{ K(\mathbf{x}_i, \mathbf{x}_j) = (\gamma \mathbf{x}_i^T \mathbf{x}_j + r)^d } \]

  • 参数:
    • \(d\): 多项式的次数 (degree)。
    • \(\gamma\): 缩放系数。
  • \(r\): 非负常数项;通常取 \(d\in\mathbb N\)\(\gamma>0\)\(r\ge0\) 以得到标准合法核。
  • 本质: \(r=0\) 时是只含总次数 \(d\) 的齐次多项式核;\(r>0\) 时才通过展开包含 0 到 \(d\) 次项。
  • 应用:
    • 对于需要考虑特征之间交互作用的问题非常有效。

    • 例如,在金融风控中,\(x_1 \times x_2\) (收入与负债率的乘积) 可能是一个比 \(x_1\)\(x_2\) 单独更强的预测因子。

常用核函数3:高斯核 (RBF Kernel)

径向基函数核 (Radial Basis Function Kernel),通常也叫高斯核,是常用且具有通用逼近能力的候选核,但不是脱离任务与验证方法的“最强”选择。

\[ \large{ K(\mathbf{x}_i, \mathbf{x}_j) = \exp \left( -\frac{||\mathbf{x}_i - \mathbf{x}_j||^2}{2\sigma^2} \right) = \exp(-\gamma ||\mathbf{x}_i - \mathbf{x}_j||^2) } \]

  • 参数:
    • \(\sigma\) (或 \(\gamma = 1/(2\sigma^2)\)): 控制核的“宽度”。
  • 本质: 相似度完全由两点间的欧氏距离决定。两点距离越近,核函数值越接近1;距离越远,核函数值越接近0。
  • 对应映射: 这是一个非常强大的核,因为它对应于一个无穷维的特征空间。

RBF核的直观理解

你可以将每个数据点想象成在空间中放置一个高斯“小山丘”。RBF核的决策边界是由这些“小山丘”的等高线组合而成的。

RBF核的直观理解 图中以“RBF核: γ 参数如何决定“影响范围”、核函数 K(x, x') = exp(-γ · d²),γ 越大,影响随距离(d)衰减越快、大 γ → 影响范围窄 (Narrow Influence)、“尖瘦”曲线: 影响衰减快、小 γ → 影响范围宽 (Wide Influence)”呈现“RBF核的直观理解”涉及的对象、方向或比较关系。 RBF 影响范围 K(x, x′)=exp(−γd²);γ 越大,衰减越快 大 γ · 影响范围窄 尖峰 · 快衰减 小 γ · 影响范围宽 宽峰 · 慢衰减

如何阅读 RBF 的 γ 图示

  • \(\gamma\) (大 \(\sigma\)): 核的半径很大,影响力范围广,决策边界非常平滑
  • \(\gamma\) (小 \(\sigma\)): 核的半径很小,每个数据点的影响范围有限,决策边界会变得非常曲折,容易过拟合。

结论

RBF 是候选而非默认赢家;以无泄漏验证和简单基准决定是否采用。

常用核函数4:Sigmoid核 (Sigmoid Kernel)

\[ \large{ K(\mathbf{x}_i, \mathbf{x}_j) = \tanh(\alpha \mathbf{x}_i^T \mathbf{x}_j + \beta) } \]

  • 参数: \(\alpha\)\(\beta\)
  • 来源: 它的形式来源于神经网络中的激活函数。
  • 注意: Sigmoid核只有在特定参数下才满足Mercer条件,因此在实践中不如RBF核和多项式核常用。

核心内容提示:KPCA/KSVM 应用为拓展内容;核心内容在核技巧与 Gram 检查后直接进入福耀玻璃主要案例

应用:核化学习算法

核方法的应用:算法的“核化” (Kernelization)

  • 核技巧的优美之处在于它的普适性。

  • 可核化条件: 算法的计算能完全写成数据点之间的内积。

  • 替换规则: 用核函数 \(K(\mathbf{x}_i, \mathbf{x}_j)\) 取代这些内积。

\[ \large{ \langle \mathbf{x}_i, \mathbf{x}_j \rangle \quad \xrightarrow{\text{Kernelize}} \quad K(\mathbf{x}_i, \mathbf{x}_j) = \langle \phi(\mathbf{x}_i), \phi(\mathbf{x}_j) \rangle_{\mathcal{H}} } \]

这使得我们能够将线性算法无缝升级,赋予其强大的非线性处理能力。

经典应用

我们将介绍两个经典应用:

  1. 核主成分分析 (Kernel PCA)
  2. 核支持向量机 (Kernel SVM)

应用1:核主成分分析 (KPCA)

拓展内容提示:核心内容在核技巧与 Gram 矩阵检查后直接进入福耀玻璃主要案例;KPCA 与 KSVM 推导在完成核心内容后选讲。

PCA 的局限性

回顾PCA:

  1. 计算数据的协方差矩阵 \(\mathbf{\Sigma} = \frac{1}{N} \sum_{n=1}^N \mathbf{x}_n \mathbf{x}_n^T\) (假设数据已中心化)。
  2. \(\mathbf{\Sigma}\) 进行特征值分解,找到主要的特征向量(主成分)。

问题

PCA只能发现数据中的线性结构。对于非线性结构,PCA会失效。

KPCA 的思路

KPCA的思路:

  1. 将数据映射后中心化:\(\tilde\phi(\mathbf{x}_n)=\phi(\mathbf{x}_n)-N^{-1}\sum_m\phi(\mathbf{x}_m)\)
  2. 在特征空间计算协方差:\(\mathbf{\Sigma}_\phi = N^{-1} \sum_n \tilde\phi(\mathbf{x}_n)\tilde\phi(\mathbf{x}_n)^T\)
  3. \(\mathbf{\Sigma}_\phi\) 进行特征值分解。

KPCA的计算技巧

  • 障碍: \(\mathbf{\Sigma}_\phi\) 可能是无穷维矩阵,无法直接计算。

  • 关键表示: 特征向量可写成映射后样本的线性组合:

\[ \mathbf{v} = \sum_{n=1}^N \alpha_n \phi(\mathbf{x}_n) \]

\(H=I-N^{-1}\mathbf 1\mathbf 1^T\),先把原始 Gram 矩阵双中心化为 \(K_c=HKH\)。特征值问题为:

\[ \large{ K_c\boldsymbol{\alpha}=N\lambda\boldsymbol{\alpha},\qquad \boldsymbol{\alpha}^{T}K_c\boldsymbol{\alpha}=1 } \]

这里 \(K_{ij}=K(\mathbf{x}_i,\mathbf{x}_j)\)\(K_c\) 对应中心化后的特征。整个计算避免显式构造 \(\phi\),但不能省略中心化。

应用2:核支持向量机 (KSVM)

回顾线性SVM

  • 目标: 找到一个能将两类数据分开,并且间隔 (margin) 最大的超平面。
  • 数学上, 这等价于求解一个带约束的二次优化问题。

对偶问题 (Dual Problem)

  • 通过拉格朗日对偶,可以把SVM的优化问题转化为“对偶形式”。
  • 神奇的是,在对偶形式中,优化目标和决策函数都只依赖于数据点的内积 \(\mathbf{x}_i^T \mathbf{x}_j\)

软间隔 SVM 对偶:目标与可行域

对带惩罚参数 \(C\) 的软间隔线性 SVM,对偶问题必须同时写出目标与可行域:

\[ \begin{aligned} \max_{\boldsymbol{\lambda}}\quad &\sum_{n=1}^{N}\lambda_n- \frac12\sum_{n=1}^{N}\sum_{m=1}^{N} \lambda_n\lambda_m y_ny_m\,\mathbf{x}_n^{\mathsf T}\mathbf{x}_m,\\ \text{s.t.}\quad &0\le \lambda_n\le C\quad(n=1,\ldots,N),\\ &\sum_{n=1}^{N}\lambda_n y_n=0. \end{aligned} \]

其中 \(\lambda_n\) 是拉格朗日乘子,\(y_n\in\{-1,+1\}\)。硬间隔情形移除上界 \(C\),保留 \(\lambda_n\ge0\) 与等式约束。

从 SVM 到 KSVM:只替换内积

核化只替换目标函数与决策函数中的内积,不改变可行域:

\[ \large{ \mathbf{x}_m^T \mathbf{x}_n \quad \longrightarrow \quad K(\mathbf{x}_m, \mathbf{x}_n) } \]

核 SVM 的完整对偶为:

\[ \begin{aligned} \max_{\boldsymbol{\lambda}}\quad &\sum_{n=1}^{N}\lambda_n- \frac12\sum_{n=1}^{N}\sum_{m=1}^{N} \lambda_n\lambda_m y_ny_m K(\mathbf{x}_n,\mathbf{x}_m),\\ \text{s.t.}\quad &0\le \lambda_n\le C,\qquad \sum_{n=1}^{N}\lambda_n y_n=0. \end{aligned} \]

  • \(K\) 是有效的正半定核时,这等价于在其特征空间寻找最大间隔超平面,并在原空间形成可能非线性的决策边界;

  • 随后进入最终总结

进入主要案例前的学习目标回顾

  • 回顾开场目标:①解释分段线性边界;

  • ②计算含先验与行列式项的 QDA 判别值;

  • ③检验核函数的 Gram 矩阵;

  • ④说明测试数据只用于最后评价,不能据此反复更换模型。

  • 回顾题: 若两个类均值相同但协方差不同,LDA 与 QDA 哪个能利用这个差异?

  • 答案: QDA。LDA 强制共享协方差,QDA 为每类估计 \(\Sigma_k\),因而边界含二次项;代价是参数更多、估计更不稳定。

形成性检查 1:完整 QDA 判别值

两类到样本的马氏距离相同,但 \(|\Sigma_1|=1\)\(|\Sigma_2|=4\) 且先验相同。哪类判别值更大?

答案

类 1。距离项相消后,\(-\tfrac12\log|\Sigma_1|=0\),类 2 为 \(-\tfrac12\log4<0\)。所以“选最近马氏距离”不是完整 QDA。

主要案例:福耀玻璃 QDA 下跌分类

  • 本例数据: data/stock/stock_price_pre_adjusted.h5;key=data;福耀玻璃 600660.XSHG;2018–2024;用当日收益、5 日收益、5/20 日波动率预测下一日是否下跌;前 80%/后 20% 时间切分。

  • 评价方法:

    • 在查看测试标签前,先确定 LDA 与 reg_param=0.1 的 QDA 为两个比较对象。

    • 测试期只用于描述它们的最终表现,不能看完结果再更换模型或增加复杂度。

    • 方法来源:scikit-learn LDA/QDA 指南

Code
from pathlib import Path  # 使用统一路径对象定位数据文件

import pandas as pd  # 导入表格工具以读取本地行情
from sklearn.pipeline import make_pipeline  # 在每个训练期内同时完成缩放和 QDA 拟合
from sklearn.preprocessing import StandardScaler  # 统一收益与波动率的数值尺度
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis, QuadraticDiscriminantAnalysis  # 在见到测试标签前同时确定线性与二次对照
from sklearn.metrics import balanced_accuracy_score, roc_auc_score  # 评价类别判断与概率排序
# 公网下载:https://assets.qiufei.site/data/stock/stock_price_pre_adjusted.h5
# 下载后把下一行改为本机文件位置;按课程结构存放时可用 Path("data/stock/stock_price_pre_adjusted.h5")。
# Windows:Path(r"C:\qiufei\data\stock\stock_price_pre_adjusted.h5")
# macOS:Path("/Users/你的用户名/data/stock/stock_price_pre_adjusted.h5")
# Linux:Path("/home/你的用户名/data/stock/stock_price_pre_adjusted.h5")
price_path = Path("/home/ubuntu/r2_data_mount/data/stock/stock_price_pre_adjusted.h5")
price_rows = pd.read_hdf(price_path, key='data', where=['order_book_id=="600660.XSHG"', 'date>=Timestamp("2018-01-01")', 'date<=Timestamp("2024-12-31")'], columns=['close'])  # 仅载入目标公司与时期
qda_frame = price_rows.reset_index().sort_values('date')  # 按交易日建立预测顺序
qda_frame['return_t'] = qda_frame['close'].pct_change()  # 构造单日收益率
qda_frame['return_5d_t'] = qda_frame['close'].pct_change(5)  # 构造五日累计收益
qda_frame['volatility_5d_t'] = qda_frame['return_t'].rolling(5).std()  # 构造短期历史波动率
qda_frame['volatility_20d_t'] = qda_frame['return_t'].rolling(20).std()  # 构造月度历史波动率
qda_frame['future_return_t1'] = qda_frame['return_t'].shift(-1)  # 先保留连续未来收益以识别末端未知标签
qda_frame['target_date_t1'] = qda_frame['date'].shift(-1)  # 保存标签实现日以清除跨窗口样本
qda_frame = qda_frame.dropna()  # 在整数化之前删除滚动窗口与未来收益缺失行
Code
qda_frame['down_t1'] = (qda_frame['future_return_t1'] < 0).astype(int)  # 仅把真实可观测的未来收益转换为类别
assert qda_frame['future_return_t1'].notna().all() and qda_frame['date'].max() < price_rows.reset_index()['date'].max()  # 确认最后特征日早于最后标签实现日
split_row = int(len(qda_frame) * 0.8)  # 固定前百分之八十为训练期
test_start_date = qda_frame.iloc[split_row]['date']  # 从完整序列确定测试起点
train_rows = qda_frame[(qda_frame['date'] < test_start_date) & (qda_frame['target_date_t1'] < test_start_date)]  # 清除到测试期才实现的训练标签
test_rows = qda_frame[qda_frame['date'] >= test_start_date]  # 确定测试特征窗口
assert train_rows['target_date_t1'].max() < test_rows['date'].min()  # 确认标签实现边界
feature_names = ['return_t', 'return_5d_t', 'volatility_5d_t', 'volatility_20d_t']  # 声明模型实际字段
lda_model = make_pipeline(StandardScaler(), LinearDiscriminantAnalysis()).fit(train_rows[feature_names], train_rows['down_t1'])  # 拟合事先说明的线性对照
qda_model = make_pipeline(StandardScaler(), QuadraticDiscriminantAnalysis(reg_param=0.1)).fit(train_rows[feature_names], train_rows['down_t1'])  # 拟合事先说明的轻度协方差收缩 QDA
lda_probability = lda_model.predict_proba(test_rows[feature_names])[:, 1]  # 在同一测试期计算 LDA 概率
down_probability = qda_model.predict_proba(test_rows[feature_names])[:, 1]  # 在同一测试期计算 QDA 概率
descriptive_comparison = pd.DataFrame([{'model': 'LDA', 'roc_auc': roc_auc_score(test_rows['down_t1'], lda_probability), 'balanced_accuracy': balanced_accuracy_score(test_rows['down_t1'], lda_probability >= 0.5)}, {'model': 'QDA', 'roc_auc': roc_auc_score(test_rows['down_t1'], down_probability), 'balanced_accuracy': balanced_accuracy_score(test_rows['down_t1'], down_probability >= 0.5)}])  # 一次性保存事先确定的描述性对照
display(descriptive_comparison)  # 展示共同测试检查,不用结果选模型
model roc_auc balanced_accuracy
0 LDA 0.539681 0.513192
1 QDA 0.458896 0.495022

形成性检查 2:核函数是否合法?

对任意样本,候选核产生的 Gram 矩阵若有明显负特征值,它能直接用于标准核 SVM 吗?

答案

通常不能。Mercer 条件要求 Gram 矩阵半正定;明显负特征值说明它未对应有效内积,优化问题可能失去标准凸性保证。

分步练习:解读 LDA/QDA 比较结果

  • 任务: 解读同一次测试期中的 LDA/QDA AUC、平衡准确率与校准;明确这些事后描述不能选胜者或据此增加模型复杂度。
  • 完整解答:
    • 并排报告两个事先确定模型的指标和 5 组概率分箱。

    • 若 QDA 未胜出,可将结果解读为额外协方差参数的方差风险,但不得用已打开的测试集回选模型;

    • 真正的复杂度选择必须在训练期时间验证中完成。

Code
comparison_rows = descriptive_comparison.copy()  # 复用已完成的一次测试结果,不再次使用测试集选模型
display(comparison_rows)  # 展示描述性对照并保留不选模型的边界
Table 1
model roc_auc balanced_accuracy
0 LDA 0.539681 0.513192
1 QDA 0.458896 0.495022

分步提示完整解答:五组校准表

Code
calibration_parts = []  # 收集 LDA 与 QDA 的五组校准结果
for model_name, model_probability in [('LDA', lda_probability), ('QDA', down_probability)]:  # 对同一测试标签评价两组概率
    model_calibration = pd.DataFrame({'observed': test_rows['down_t1'].to_numpy(), 'probability': model_probability})  # 对齐预测概率与真实类别
    model_calibration['probability_bin'] = pd.cut(model_calibration['probability'], bins=[0, .2, .4, .6, .8, 1], include_lowest=True)  # 使用预先声明的五个概率区间
    model_table = model_calibration.groupby('probability_bin', observed=False).agg(n=('observed', 'size'), mean_probability=('probability', 'mean'), observed_rate=('observed', 'mean')).reset_index()  # 计算每组预测均值与真实频率
    model_table.insert(0, 'model', model_name)  # 标记校准表所属模型
    calibration_parts.append(model_table)  # 记录当前模型的五组结果
pd.concat(calibration_parts, ignore_index=True).query("model == 'LDA'")  # 先输出 LDA 的五组校准证据
Table 2
model probability_bin n mean_probability observed_rate
0 LDA (-0.001, 0.2] 0 NaN NaN
1 LDA (0.2, 0.4] 0 NaN NaN
2 LDA (0.4, 0.6] 336 0.507943 0.470238
3 LDA (0.6, 0.8] 0 NaN NaN
4 LDA (0.8, 1.0] 0 NaN NaN

分步提示完整答案:QDA 校准

Code
pd.concat(calibration_parts, ignore_index=True).query("model == 'QDA'")  # 再输出 QDA 的五组校准证据
Table 3
model probability_bin n mean_probability observed_rate
5 QDA (-0.001, 0.2] 0 NaN NaN
6 QDA (0.2, 0.4] 5 0.329425 0.400000
7 QDA (0.4, 0.6] 331 0.526541 0.471299
8 QDA (0.6, 0.8] 0 NaN NaN
9 QDA (0.8, 1.0] 0 NaN NaN

空组或极小组本身就是不稳定证据;比较预测均值与真实频率时必须同时报告 n

综合练习

换用恒瑞医药 600276.XSHG,比较 QDA 概率、RBF-SVM 决策分数和训练期先验概率基准;仅在训练期扩展窗口选择 reg_param\(C\)\(\gamma\)

完整答案提醒

  • 按时间顺序验证,只用训练数据估计缩放参数,在同一测试期比较模型与基准;

  • 报告 AUC,并为概率模型报告平衡准确率和校准;

  • 说明增加复杂度的代价。

  • 未经有效校准的 SVM 分数不得解释为概率。

综合练习完整答案:数据与时间边界

Table 4
Code
from sklearn.model_selection import GridSearchCV, TimeSeriesSplit  # 只在训练期扩展窗口选参
from sklearn.svm import SVC  # 建立输出决策分数的 RBF 核分类器
from pathlib import Path  # 使用统一路径对象定位数据文件
# 公网下载:https://assets.qiufei.site/data/stock/stock_price_pre_adjusted.h5
# 下载后把下一行改为本机文件位置;按课程结构存放时可用 Path("data/stock/stock_price_pre_adjusted.h5")。
# Windows:Path(r"C:\qiufei\data\stock\stock_price_pre_adjusted.h5")
# macOS:Path("/Users/你的用户名/data/stock/stock_price_pre_adjusted.h5")
# Linux:Path("/home/你的用户名/data/stock/stock_price_pre_adjusted.h5")
price_path = Path("/home/ubuntu/r2_data_mount/data/stock/stock_price_pre_adjusted.h5")
transfer_rows = pd.read_hdf(price_path, key='data', where=['order_book_id=="600276.XSHG"', 'date>=Timestamp("2018-01-01")', 'date<=Timestamp("2024-12-31")'], columns=['close'])  # 选择恒瑞医药收盘价
transfer_frame = transfer_rows.reset_index().sort_values('date')  # 按预测顺序排列交易日
transfer_frame['return_t'] = transfer_frame['close'].pct_change()  # 构造当日收益率
transfer_frame['return_5d_t'] = transfer_frame['close'].pct_change(5)  # 构造五日收益率
transfer_frame['volatility_5d_t'] = transfer_frame['return_t'].rolling(5).std()  # 构造历史五日波动率
transfer_frame['volatility_20d_t'] = transfer_frame['return_t'].rolling(20).std()  # 构造历史二十日波动率
transfer_frame['future_return_t1'] = transfer_frame['return_t'].shift(-1)  # 先保留连续未来收益
transfer_frame['target_date_t1'] = transfer_frame['date'].shift(-1)  # 保存标签实现日
transfer_frame = transfer_frame.dropna()  # 在整数化前删除未知未来与滚动缺失
transfer_frame['down_t1'] = (transfer_frame['future_return_t1'] < 0).astype(int)  # 仅对已观测未来收益构造标签
transfer_train = transfer_frame[(transfer_frame['date'] <= '2022-12-31') & (transfer_frame['target_date_t1'] < '2023-01-01')]  # 清除到测试期才实现的训练标签
transfer_test = transfer_frame[transfer_frame['date'] >= '2023-01-01']  # 测试期
assert transfer_train['target_date_t1'].max() < transfer_test['date'].min()  # 确认标签实现边界
transfer_features = ['return_t', 'return_5d_t', 'volatility_5d_t', 'volatility_20d_t']  # 固定四个 t 时点特征

综合练习完整答案:选参与确定测试

Code
transfer_cv = TimeSeriesSplit(5, gap=1)  # 一日预测 horizon 在每折训练与验证之间清除一行
assert all(transfer_train.iloc[fit_idx]['target_date_t1'].max() < transfer_train.iloc[val_idx]['date'].min() for fit_idx, val_idx in transfer_cv.split(transfer_train))  # 确认全部训练折标签先实现
qda_search = GridSearchCV(make_pipeline(StandardScaler(), QuadraticDiscriminantAnalysis()), {'quadraticdiscriminantanalysis__reg_param': [0, .1, .5]}, cv=transfer_cv, scoring='roc_auc').fit(transfer_train[transfer_features], transfer_train['down_t1'])  # 仅在训练期选择 QDA 收缩
svm_search = GridSearchCV(make_pipeline(StandardScaler(), SVC(kernel='rbf')), {'svc__C': [.1, 1, 10], 'svc__gamma': ['scale', .1, 1]}, cv=transfer_cv, scoring='roc_auc').fit(transfer_train[transfer_features], transfer_train['down_t1'])  # 仅在训练期选核参数且不触发随机内部概率拟合
transfer_probabilities = {'QDA': qda_search.predict_proba(transfer_test[transfer_features])[:, 1], 'prior baseline': pd.Series(transfer_train['down_t1'].mean(), index=transfer_test.index).to_numpy()}  # 只保留具有明确概率语义的输出
svm_decision_score = svm_search.decision_function(transfer_test[transfer_features])  # 为 SVM 生成未校准的排序分数
probability_metrics = [{'model': model_name, 'roc_auc': roc_auc_score(transfer_test['down_t1'], probability), 'balanced_accuracy': balanced_accuracy_score(transfer_test['down_t1'], probability >= .5)} for model_name, probability in transfer_probabilities.items()]  # 只对概率输出应用 0.5 阈值
transfer_metrics = pd.DataFrame(probability_metrics + [{'model': 'RBF-SVM score', 'roc_auc': roc_auc_score(transfer_test['down_t1'], svm_decision_score), 'balanced_accuracy': float('nan')}])  # SVM 只报告阈值无关排序证据
transfer_calibration = []  # 收集两个概率模型的五组校准表
for model_name, probability in transfer_probabilities.items():  # 对每组概率使用同一分箱规则
    calibration_frame = pd.DataFrame({'observed': transfer_test['down_t1'].to_numpy(), 'probability': probability})  # 对齐概率与真实标签
    calibration_frame['bin'] = pd.cut(calibration_frame['probability'], [0, .2, .4, .6, .8, 1], include_lowest=True)  # 划分五个固定概率组
    model_calibration = calibration_frame.groupby('bin', observed=False).agg(n=('observed', 'size'), mean_probability=('probability', 'mean'), observed_rate=('observed', 'mean')).reset_index()  # 计算校准证据
    model_calibration.insert(0, 'model', model_name)  # 标明每组来源模型
    transfer_calibration.append(model_calibration)  # 记录当前模型结果
display(pd.Series({'QDA_best': qda_search.best_params_, 'SVM_best': svm_search.best_params_}))  # 输出训练期确定的超参数
display(transfer_metrics)  # 输出共同测试 AUC 与平衡准确率
Table 5
QDA_best    {'quadraticdiscriminantanalysis__reg_param': 0.5}
SVM_best                     {'svc__C': 1, 'svc__gamma': 0.1}
dtype: object
model roc_auc balanced_accuracy
0 QDA 0.508321 0.503456
1 prior baseline 0.500000 0.500000
2 RBF-SVM score 0.498711 NaN
  • 真实结果:QDA 选择 reg_param=0.5,AUC/平衡准确率为 0.508321/0.503456;RBF-SVM 选择 \(C=1,\gamma=0.1\),只检查未校准决策分数的测试 AUC;先验概率基准为 0.500000/0.500000。

  • SVM 不使用 probability=True,因为其内部随机五折概率拟合不满足本题的时间边界;

  • 没有单独的时间有效校准集,就不报告 SVM 的 0.5 概率阈值或校准表。

综合练习完整答案:确定测试校准

Code
pd.concat(transfer_calibration, ignore_index=True).query("model == 'QDA'")  # 输出 QDA 的五组校准表
Table 6
model bin n mean_probability observed_rate
0 QDA (-0.001, 0.2] 0 NaN NaN
1 QDA (0.2, 0.4] 9 0.314139 0.777778
2 QDA (0.4, 0.6] 470 0.498199 0.523404
3 QDA (0.6, 0.8] 4 0.650944 0.250000
4 QDA (0.8, 1.0] 0 NaN NaN

RBF-SVM:只检查未校准决策分数

Code
pd.Series({'score_min': svm_decision_score.min(), 'score_median': pd.Series(svm_decision_score).median(), 'score_max': svm_decision_score.max(), 'test_roc_auc': roc_auc_score(transfer_test['down_t1'], svm_decision_score)})  # 输出分数范围与阈值无关 AUC
Table 7
score_min      -1.209231
score_median   -0.295047
score_max       1.313768
test_roc_auc    0.498711
dtype: float64

确定测试校准:先验概率基准

Code
pd.concat(transfer_calibration, ignore_index=True).query("model == 'prior baseline'")  # 输出先验概率基准的五组校准表
Table 8
model bin n mean_probability observed_rate
5 prior baseline (-0.001, 0.2] 0 NaN NaN
6 prior baseline (0.2, 0.4] 0 NaN NaN
7 prior baseline (0.4, 0.6] 483 0.48995 0.52588
8 prior baseline (0.6, 0.8] 0 NaN NaN
9 prior baseline (0.8, 1.0] 0 NaN NaN

形成性检查 3:何时不用非线性?

非线性模型训练分数更高,但所有时间验证窗口均未优于线性基准。应选哪个?

答案

优先线性基准。训练拟合不是泛化证据;只有稳定、样本外且足以补偿复杂度成本的提升才支持升级模型。

来源与延伸阅读

  • Hastie, Tibshirani & Friedman, The Elements of Statistical Learning, discriminant analysis and kernels。
  • Schölkopf & Smola, Learning with Kernels
  • Ledoit & Wolf (2004), covariance shrinkage。
  • 数据:本地 A 股前复权行情数据;文件、key、字段、时期和切分见 前面的案例。

本章总结

课后选学

完成核心内容后,可以继续学习KPCA 与 KSVM 推导,随后进入最终总结

三种非线性建模思想对比

特性 / 方法 分段线性判别 二次判别分析 (QDA) 核方法 (Kernel Trick)
核心思想 用多段直线逼近 直接拟合二次曲线 升维打击,化曲为直
灵活性 高(依赖分段设计) 中等(仅限二次型) 高(取决于核、超参数与表示维数)
计算成本 取决于分段数量 中等 (\(O(d^2)\)) 高 (\(O(N^2)\)\(O(N^3)\))
可解释性 中等(类似决策树) 较高(二次函数) 低(高维空间无法直观理解)
主要假设 无特定分布假设 数据服从高斯分布 无特定分布假设
关键参数 子类/分段的数量 类别先验、协方差估计与正则化强度 核函数类型及其参数 (如 gamma, d)
适用场景 直观建模,类似决策树的场景 类别协方差不同,特征维度不高 经样本外结果验证后确有增益的非线性问题

关键要点回顾

  1. 直面非线性: 现实世界是复杂的,线性模型有其局限性,学习非线性模型是必要的。
  2. QDA: 通过为每个类假定不同的协方差矩阵来生成二次边界,是LDA的自然推广,在LDA和更复杂模型间取得良好平衡。
  3. 核方法 (Kernel Trick):
    • 核心思想: 升维 + 线性模型。
    • 通过核函数 \(K(\mathbf{x}_i, \mathbf{x}_j) = \langle \phi(\mathbf{x}_i), \phi(\mathbf{x}_j) \rangle\) 避免显式构造高维坐标,但仍须面对样本复杂度、正则化和过拟合。
    • 可“核化”任何依赖于内积的算法 (如PCA, SVM),赋予其强大的非线性能力。
    • RBF 核是常用候选,但表现依赖核宽度、保留维数、下游模型与样本外评价结果;本讲的一维 KPCA 反例说明它不保证可分。

谢谢!

Q & A