跳转至

导师:“你用 Codex 把高斯核跑通了?”我:“对啊,很顺利!”导师:“那你说说,为什么能把圆环数据一刀切开?”

来源:https://mp.weixin.qq.com/s/sQNMLqaBPY_fy0inVvBBVg

今儿和大家聊一个非常重要的模型,高斯核~ 你可能听过核方法。高斯核,但总感觉它像个黑箱:一加上核函数,原本分不开的数据就突然分开了。 为什么?今天就把它层层剥开,和大家聊清楚~

01高斯核在干什么?

一句话总结的话,高斯核的本质,是用相似度(距离越近越相似)来重新衡量数据,并把相似度变成特征,这样原本扭曲纠缠的数据,在相似度空间里就能被一条分界线(比如超平面)整齐切开了。 再细一点,在二维平面里,你用一条直线分不开圆环月牙这类花哨形状的数据。 核方法,你别在原地硬分;把每个点与所有训练点的相似度当作它的新坐标(特征)!在这个相似度新世界里,看似弯曲的边界,常常就能被直线切开。 什么是相似度?以高斯核举例:两个点越近就越相似,远了就不相似。相似度用高斯函数来刻画,形状是一个鼓包,离中心越远值越小。 高斯核的数学式子:

其中 。 大家把它理解成给每个训练样本点点亮一盏小手电,离手电越近越亮(相似度高),越远越暗(相似度低)。 学习的过程,就是学会如何给这些手电设定亮度权重,让所有光影叠加后,某些区域呈现正类为主的亮度,另一些区域呈现反类为主的亮度,分界线自然出现。 核技巧(Kernel Trick)最重要的一句话,你不必真的把数据映射到高维(甚至无限维)空间,只需要计算相似度(内积)就够了。也就是说,用直接替代特征内积。 理论上,高斯核对应的特征映射是无限维的(它可以被展开成无穷多项的多项式组合),这就是它强大的原因。但我们从来不显式构造这些特征,只算就够了。

02一个通俗例子

你可以想象一个操场,有很多颗小灯泡(训练数据点),红色组和蓝色组各有一堆。每个灯泡都会发出光,光的亮度离灯越近越亮,远了就暗了(这就是高斯核)。现在,有一只小球(新数据点)放到操场的某个位置,它会收到周围红色灯和蓝色灯的光。哪种颜色的光更亮,就把小球判成哪种颜色。光多的地方,就像地形图的山峰;两种颜色的山峰相互挤压、交界的地方,就是分类的边界。 - 灯泡越密集的地方(某类样本多),那个区域的光强越高,容易被判成该类。

  • 灯泡离得越近,互相影响越大;离得远,影响就弱。

甚至可以把它想成软K近邻:不是数最近的K个邻居,而是离得越近权重大,所有邻居的贡献叠加起来做决定。

03数学表达

高斯核:

核技巧(以SVM为例)的决策函数形状:

只需训练出权重(支持向量对应的不为0)。这就像给每个训练点一盏手电,以为亮度、以高斯核为光照衰减规律,叠加出一张光强地图,然后看新点落在地图的哪一边。 为什么高斯核像无限维多项式? 因为:

它包含了从1次到无穷次的多项式内积项。配合上这样的常数因子,可以理解为在无限维空间里做线性分类,但我们并不真去算那些维度。 超重要的两个超参数: - (核宽度的倒数):越大,光斑越尖锐,模型越容易过拟合;越小,光斑越平滑,模型越容易欠拟合。

  • (SVM的正则化项系数):越大,越重视把训练样本分对,可能牺牲间隔、导致过拟合;越小,容错更大,间隔更宽,可能欠拟合。

04小小例子

想象数轴上有3个训练点: - 红点在和;

  • 蓝点在。

我们用高斯核来判断是红还是蓝。设,高斯核。 - 距离最近的是(蓝),距离为1,贡献约。

  • 红点到的距离也是1,贡献约。

  • 红点到的距离是3,贡献约(几乎没贡献)。

如果我们给红点和蓝点差不多的权重,那么处: - 蓝光强≈0.3679

  • 红光强≈0.3679 + 0.000123 ≈ 0.3680

几乎打平,略偏红。 要更明显地区分,需要更多点、或调整、或学习到合理的权重(这就是训练要做的事)。这个例子清楚地说明了离近的点影响大、离远的点影响小,同类样本越多越密,叠加的光越亮的直觉。

05完整案例

下面我们用一个数据集做一个完整的流程,从数据构造到建模、调参、可视化~ 首先,构造一个复杂多类、非线性的二维数据集:把两月亮(moons)放在左侧,同心圆(circles)放在右侧,合成4个类别。 标准化特征(对RBF核很关键)。 训练两个模型对比: - 线性SVM(kernel=linear)

  • RBF核SVM(kernel=rbf)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.datasets import make_moons, make_circles
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics.pairwise import rbf_kernel

np.random.seed(42)

# 1) 构造数据:左边两月亮(两类),右边同心圆(两类),合并成4类
X_moon, y_moon = make_moons(n_samples=3000, noise=0.10, random_state=0)
X_moon[:, 0] -= 2.5  # 左移
# 标记为0、1两类
y_moon = y_moon

X_circ, y_circ = make_circles(n_samples=3000, noise=0.06, factor=0.5, random_state=1)
X_circ[:, 0] += 2.5  # 右移
# 将圈的两类映射到2、3
y_circ = y_circ + 2

X = np.vstack([X_moon, X_circ])
y = np.hstack([y_moon, y_circ])

class_colors = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3']
markers = ['o', '^', 's', 'D']  # 圆、三角、方、菱形

# 2) 标准化特征(非常重要!RBF核对尺度敏感)
scaler = StandardScaler()
X_std = scaler.fit_transform(X)

# 网格辅助函数(可视化决策边界)
def make_meshgrid(X, h=0.04, pad=0.6):
    x_min, x_max = X[:, 0].min() - pad, X[:, 0].max() + pad
    y_min, y_max = X[:, 1].min() - pad, X[:, 1].max() + pad
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, int((x_max-x_min)/h)),
                         np.linspace(y_min, y_max, int((y_max-y_min)/h)))
    return xx, yy

xx, yy = make_meshgrid(X_std, h=0.04, pad=0.6)
grid = np.c_[xx.ravel(), yy.ravel()]

def plot_data(ax, X, y, title='Dataset', alpha=0.85, s=30):
    for cls in np.unique(y):
        ax.scatter(X[y==cls, 0], X[y==cls, 1],
                   c=class_colors[cls],
                   marker=markers[cls],
                   edgecolors='k', linewidths=0.5,
                   s=s, alpha=alpha, label=f'Class {cls}')
    ax.set_title(title, fontsize=12)
    ax.legend(loc='upper right', frameon=True, fontsize=8)
    ax.set_xlabel('x1 (std)')
    ax.set_ylabel('x2 (std)')
    ax.set_aspect('auto')
    ax.set_box_aspect(0.45)

def plot_decision(ax, clf, X, y, title='Decision boundary', alpha_bg=0.25):
    # 画背景的类别区域
    Z = clf.predict(grid).reshape(xx.shape)
    bg_cmap = ListedColormap(class_colors)
    ax.contourf(xx, yy, Z, cmap=bg_cmap, alpha=alpha_bg, levels=np.arange(-0.5, len(np.unique(y))+0.5, 1))
    # 再叠加一层等高线突出边界
    ax.contour(xx, yy, Z, levels=np.arange(-0.5, len(np.unique(y))+0.5, 1),
               colors='k', linewidths=0.5, alpha=0.7)
    # 叠加原始点
    plot_data(ax, X, y, title)

# 3) 训练两个模型:线性 vs RBF
clf_linear = SVC(kernel='linear', C=10.0, decision_function_shape='ovr', random_state=0)
clf_rbf = SVC(kernel='rbf', gamma=1.0, C=10.0, probability=True, decision_function_shape='ovr', random_state=0)

clf_linear.fit(X_std, y)
clf_rbf.fit(X_std, y)

# 图1:数据点分布
fig1, ax1 = plt.subplots(figsize=(10, 4.8), constrained_layout=True)
plot_data(ax1, X_std, y, title='Fig 1. Complex 4-class dataset (std-scaled)')

# 图2:对某个地标点的核相似度热力图(看手电筒光强地形)
gamma_for_heat = 1.0
landmark_idx = 50  # 任选一个样本做地标
landmark = X_std[landmark_idx].reshape(1, -1)
sim_heat = rbf_kernel(grid, landmark, gamma=gamma_for_heat).reshape(xx.shape)

fig2, ax2 = plt.subplots(figsize=(10, 4.8), constrained_layout=True)
im = ax2.imshow(sim_heat, extent=(xx.min(), xx.max(), yy.min(), yy.max()),
                origin='lower', cmap='plasma', alpha=0.85, aspect='auto')
fig2.colorbar(im, ax=ax2, fraction=0.046, pad=0.04, label='RBF similarity')
plot_data(ax2, X_std, y, title='Fig 2. RBF similarity to a landmark (plasma cmap)', alpha=0.85, s=20)
ax2.scatter(landmark[:, 0], landmark[:, 1], c='yellow', edgecolors='k',
            s=120, marker='*', label='Landmark')
ax2.legend(loc='upper right', fontsize=8, frameon=True)

# 图3:线性 vs RBF 决策边界对比
fig3, axes3 = plt.subplots(1, 2, figsize=(14, 4.8), constrained_layout=True)
plot_decision(axes3[0], clf_linear, X_std, y, title='Fig 3a. Linear SVM boundary')
plot_decision(axes3[1], clf_rbf, X_std, y, title='Fig 3b. RBF SVM boundary (gamma=1.0, C=10)')

# 图4:不同γ(核宽度)下的决策边界(横向4子图)
gamma_list = [0.05, 0.2, 1.0, 5.0]
fig4, axes4 = plt.subplots(1, 4, figsize=(18, 4.5), constrained_layout=True)
axes4 = axes4.ravel()
for i, g in enumerate(gamma_list):
    clf_g = SVC(kernel='rbf', gamma=g, C=10.0, decision_function_shape='ovr', random_state=0)
    clf_g.fit(X_std, y)
    plot_decision(axes4[i], clf_g, X_std, y, title=f'Fig 4.{i+1} RBF SVM (gamma={g}, C=10)')

# 图5:RBF模型的预测置信度热力图 + 支持向量标注
proba_grid = clf_rbf.predict_proba(grid)  # shape: (N, n_classes)
conf = proba_grid.max(axis=1).reshape(xx.shape)  # 每点最可能的类别概率
fig5, ax5 = plt.subplots(figsize=(10, 4.8), constrained_layout=True)
im5 = ax5.imshow(conf, extent=(xx.min(), xx.max(), yy.min(), yy.max()),
                 origin='lower', cmap='Spectral', alpha=0.8, aspect='auto', vmin=0.25, vmax=1.0)
fig5.colorbar(im5, ax=ax5, fraction=0.046, pad=0.04, label='Max class probability')
plot_data(ax5, X_std, y, title='Fig 5. Confidence heatmap + support vectors', alpha=0.85, s=18)
# 支持向量
SV = clf_rbf.support_vectors_
ax5.scatter(SV[:, 0], SV[:, 1], s=80, facecolors='none', edgecolors='black', linewidths=1.2, marker='*', label='Support Vectors')
ax5.legend(loc='lower right', fontsize=8, frameon=True)

plt.show()
图1:数据点分布

img

左边是两月亮(上下两个弯弯);右边是同心圆(内圈和外圈)。 这些形状在原始二维空间里,被一条直线根本分不开。 图2:核相似度热力图

img

我们随机挑了一个样本作为地标点(黄色五角星)。图中颜色越亮,代表和地标点越相似(越近)。 这张地形图展示了高斯核的鼓包效应:像一盏手电筒,离中心越远越暗。 核方法就是把每个训练样本都变成这样一盏手电筒,学习出合适的亮度权重。 图3:线性 vs RBF 决策边界

img

左图(线性SVM):你会看到它几乎画不出贴合数据形状的边界,在多类交错的区域显得力不从心。 右图(RBF SVM):边界随数据形状弯弯绕绕,明显能抱住圆环、分开月亮,效果直观更好。 图4:调参之γ会改变什么?

img

  • γ小(0.05):高斯光斑很宽,模型很平滑,可能欠拟合(边界太粗糙)。

  • γ适中(0.2、1.0):边界更贴合数据结构,既不过度摆动,也不太僵硬。

  • γ大(5.0):每盏手电光斑很尖,容易过拟合(边界在训练点附近弯来绕去,可能对噪音敏感)。

  • 这4张小图帮助你建立γ控制曲线弯曲程度的直觉。

图5:RBF模型预测置信度热力图 + 支持向量标注 背景的颜色表示模型对最可能类别的概率。

img

越亮(接近1)代表模型更有把握;颜色过渡带代表拿不准的区域(通常就是边界附近)。 星号(黑边空心)是支持向量:它们决定了边界的形状。你能看到,边界附近的样本更可能成为支持向量(符合SVM的几何直觉)。

小结

整体来说,高斯核的核心逻辑是用相似度作为新的特征表达,让非线性结构在相似度空间里可被线性边界分开。 其中,关键超参数 γ 控制光斑宽度(平滑 vs 复杂),C控制容错/间隔(泛化 vs 过拟合)。 在实验中,关键是标准化特征、网格搜索调参、可视化诊断。

超硬核:学习圈子

欢迎加入,这里再介绍一下我们的学习圈子~ 我们目前已经更新的内容有:

img

更加详细的介绍,可以看这里,会有更多超级干货带给大家~ 目前,200个核心算法模型也已经更新完毕~

往期精华

知识星球,硬核学习圈子 讲透200个机器学习模型 最强组合,随机森林和XGBoost 融合ARIMA+LSTM+Prophet融合的时序预测 融合SVR+XGBoost+LSTM,非平稳时序预测 融合XGBoost+LSTM+ARIMA+Prophet 时序预测 靠三四区论文,进大厂 开年发论文!登Nature正刊

有任何问题评论区留言~我是cos大壮,只写干货,最后感谢大家的点赞或者转发~

cos大壮的机器学习

cos大壮的机器学习实战

            预览时标签不可点




































<div class="