KNN、贝叶斯与 SVM 对比
三类模型分别依赖邻居、概率假设和最大间隔,应在同一验证协议下公平比较。
学习前需要掌握
背景与问题
KNN、贝叶斯和 SVM 的优势取决于数据表示与约束。拿不同划分或不同预处理的最高分比较,会把协议差异误当模型差异。
概念定义
模型家族比较在相同独立划分、指标和预算下,评估各家族的预测、波动、计算、概率语义及部署行为。预处理可不同,但必须各自在训练折学习。
直观理解
公平比较比赛成绩需要同一赛道,但选手仍可使用各自合规装备;不能为表面统一而故意省去某模型需要的缩放。
核心原理
KNN 依赖局部距离,把主要成本放在预测;高斯贝叶斯依赖类条件分布假设,参数少且推理快;SVM 依赖间隔与核,尺度和核参数尤其关键。它们不是同一目标的三种名称。
固定同一组交叉验证折,对每个模型分别用 Pipeline 处理拟合变换,再记录逐折指标。不要只保留最好一折;均值与波动说明不同方面,折间分数又并非完全独立,因此简单标准差不是严格置信区间。
若用交叉验证调很多超参数,最终性能估计可能还需要嵌套验证或独立测试。训练时间、延迟、内存与校准也应实际测量;不能从算法标签直接给出某项目的耗时结论。
相同三折上的受控小型对照
- 构造十二个一维样本,前六个为负类、后六个为正类
- 固定三折 StratifiedKFold
- KNN 与 SVM 在各自 Pipeline 中缩放,GNB 使用其高斯特征模型
代码实际产生三组逐折分数;只对应这个构造数据,不能作为真实任务排名。
本例类别沿一条轴分开,刻意保持简单以验证比较协议。即使三家分数相同,也不意味着真实数据中三者等价,而是这套小数据没有足够区分力。
真实选择还要给定时延或概率要求。例如预测量很大时 KNN 的查询成本可能成为约束;需要概率时不能把 SVM 分数直接与 GNB 概率同口径比较。
数学表达
核心表达
这是同一验证协议下逐折分数的算术平均;同时保留分数分布与实际资源测量,不能把多目标选择缩成无单位的随意加法。
变量含义
变量定义与本页概念定义一致,代码中的同名变量保持相同语义。
计算步骤
- 1预先固定划分、指标、候选和资源约束。
- 2为每个候选建立必要的训练内预处理 Pipeline。
- 3保留逐折结果与资源测量,锁定方案后再测试。
代码对应位置
示例 1相同三折上的受控小型对照的最小验证:使用完整构造输入核对相同三折上的受控小型对照,输出只表示本例计算。
计算与实现步骤
- 预先固定划分、指标、候选和资源约束。
- 为每个候选建立必要的训练内预处理 Pipeline。
- 保留逐折结果与资源测量,锁定方案后再测试。
代码实现
示例 1
相同三折上的受控小型对照的最小验证
example_01.py用途:使用完整构造输入核对相同三折上的受控小型对照,输出只表示本例计算。
import numpy as np
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
x = np.array([-6., -5., -4., -3., -2., -1., 1., 2., 3., 4., 5., 6.]).reshape(-1, 1)
y = np.array([0] * 6 + [1] * 6)
cv = StratifiedKFold(3, shuffle=True, random_state=7)
models = {
"KNN": make_pipeline(StandardScaler(), KNeighborsClassifier(3)),
"GNB": GaussianNB(),
"SVM": make_pipeline(StandardScaler(), SVC(kernel="linear", C=1)),
}
for name, model in models.items():
scores = cross_val_score(model, x, y, cv=cv, scoring="accuracy")
print(name, [round(v, 3) for v in scores.tolist()])代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
使用完整构造输入核对相同三折上的受控小型对照,输出只表示本例计算。
y- 目标标签或连续目标值。
model- 组合预处理和估计器的模型对象。
scores- 交叉验证各折的评价分数。
Step 1 · 1–18 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import numpy as np
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
x = np.array([-6., -5., -4., -3., -2., -1., 1., 2., 3., 4., 5., 6.]).reshape(-1, 1)
y = np.array([0] * 6 + [1] * 6)
cv = StratifiedKFold(3, shuffle=True, random_state=7)
models = {
"KNN": make_pipeline(StandardScaler(), KNeighborsClassifier(3)),
"GNB": GaussianNB(),
"SVM": make_pipeline(StandardScaler(), SVC(kernel="linear", C=1)),
}
for name, model in models.items():
scores = cross_val_score(model, x, y, cv=cv, scoring="accuracy")
print(name, [round(v, 3) for v in scores.tolist()])代码与数学原理
减去训练均值并除以训练标准差,对应代码中的 mean/std 或 StandardScaler。
预期输出或运行结果
KNN [1.0, 1.0, 1.0] GNB [1.0, 1.0, 1.0] SVM [1.0, 1.0, 1.0]
常见错误 · 5 条
- 不要在测试集上调用 fit 或 fit_transform;测试集只能复用训练参数。
- 不同折比较
- 测试分数选模型
- 忽略预处理成本
- 确认样本轴、特征轴以及 X 与 y 的第一维完全对应。
实际应用
- 建立分类模型基线表
- 按延迟、概率与数据结构选候选
常见错误
- 不同折比较
- 测试分数选模型
- 忽略预处理成本
推荐学习资料
scikit-learn/scikit-learn
经典机器学习算法、模型选择、预处理和评估工具的核心实现仓库。
scikit-learn Contributors · GitHub
仓库信息
研究 scikit-learn 实现和贡献流程
主要语言:Python / Cython包含数据集或实验需要额外环境