Chapter 07

分类算法

KNN、朴素贝叶斯、SVM 与分类评估指标体系

01

核心概念:分类算法的多样性

分类(Classification)是监督学习的核心任务之一:给定输入特征 x,预测其所属离散类别 y。不同算法对数据分布、特征关系和决策边界的假设截然不同,理解这些差异是选择合适模型的前提。

K-近邻(KNN):"物以类聚"的直觉

KNN 是一种惰性学习(Lazy Learning)算法,它没有显式的训练阶段,而是在预测时直接查询训练数据。核心思想:一个样本的类别,由其邻居的多数投票决定。

距离度量是 KNN 的灵魂。最常用的是欧氏距离:

d(x, x') = √Σⱼ (xⱼ − x'ⱼ)²

其他距离包括曼哈顿距离(坐标差绝对值之和,适合高维稀疏数据)和闵可夫斯基距离。K 值的选择至关重要:K 太小易受噪声干扰;K 太大则边界模糊,可能引入异类邻居。

朴素贝叶斯:概率视角的分类

朴素贝叶斯基于贝叶斯定理,假设各特征在给定类别下条件独立("朴素"的由来):

P(y|x) = P(x|y)·P(y) / P(x) ∝ P(y)·Πⱼ P(xⱼ|y)

预测时选择使后验概率 P(y|x) 最大的类别。对于连续特征,常用高斯分布建模 P(xⱼ|y);对于离散特征,用频率计数(多项式/伯努利朴素贝叶斯)。

核心洞察

朴素贝叶斯的"条件独立"假设在现实中几乎不成立,但它在文本分类等场景表现优异。原因在于:即使概率估计有偏,分类决策往往只需比较各类别的相对大小,而错误的独立性假设对排序的影响有限。

支持向量机(SVM):寻找最大间隔

SVM 的核心思想是找到一个最优超平面,使得不同类别的样本被分开,且超平面到最近样本的距离(间隔 Margin)最大化。

优化目标:min (1/2)||w||² ,约束 yᵢ(wTxᵢ + b) ≥ 1

位于间隔边界上的样本称为支持向量,它们决定了最终决策边界。对于线性不可分数据,SVM 引入核函数(Kernel)将特征映射到高维空间,使其在高维中线性可分:

评估指标:超越准确率

在不平衡数据集中,准确率(Accuracy)是误导性的。例如,99% 的样本为负类时,全部预测为负也能达到 99% 准确率。需要更精细的指标:

指标公式含义
精确率 (Precision)TP / (TP+FP)预测为正类中真正为正的比例
召回率 (Recall)TP / (TP+FN)真正为正类中被正确找出的比例
F1 分数2·P·R / (P+R)精确率与召回率的调和平均
特异度 (Specificity)TN / (TN+FP)真正为负类中被正确找出的比例

混淆矩阵与 ROC-AUC

混淆矩阵以表格形式展示 TP、FP、TN、FN 的数量,是诊断模型偏误的第一工具。

ROC 曲线通过不断调整分类阈值,绘制真正例率(TPR = Recall)与假正例率(FPR = FP/(FP+TN))的关系曲线。AUC(Area Under Curve)量化了 ROC 曲线下面积,取值 0.5(随机猜测)到 1.0(完美分类)。AUC 对类别不平衡不敏感,是模型排序能力的综合度量。

02

计算方法:算法步骤与核心公式

KNN 预测步骤

  1. 计算待预测样本 x 与训练集中所有样本的距离。
  2. 按距离升序排序,选取距离最近的 K 个邻居。
  3. 统计 K 个邻居的类别分布,以多数投票决定 x 的类别(回归任务则取平均)。
  4. (可选)对邻居按距离加权投票,近邻权重更高。

贝叶斯分类的决策规则

对于 C 个类别,预测规则为:

ŷ = argmaxc P(y=c)·Πⱼ P(xⱼ|y=c)

为避免概率连乘下的数值下溢,通常取对数:

ŷ = argmaxc [ log P(y=c) + Σⱼ log P(xⱼ|y=c) ]

SVM 超平面与核技巧

SVM 的决策函数为 f(x) = sign(wTφ(x) + b)。通过核技巧,无需显式计算高维映射 φ(x),直接用核函数代替内积:

f(x) = sign( Σᵢ αᵢyᵢK(xᵢ, x) + b )

其中 αᵢ 为拉格朗日乘子,仅支持向量对应的 αᵢ 非零。这就是 SVM 的稀疏性:决策仅依赖于少量支持向量。

03

工程应用

文本分类与情感分析

朴素贝叶斯是垃圾邮件过滤和新闻主题分类的经典选择。将文本转化为词袋(Bag-of-Words)特征后,每个词的出现与否/频次即构成特征。假设词与词之间独立显然不成立(如"纽约"和"时报"常一起出现),但朴素贝叶斯因其训练速度极快、对小样本友好、可解释性强,至今仍是文本分类的高效基线。

医疗诊断

在癌症筛查中,召回率(不漏诊)往往比精确率(不误诊)更重要——漏掉一个癌症患者的代价远高于让健康人多做一次检查。SVM 在高维基因表达数据上表现优异,RBF 核能够捕捉复杂的基因组合效应。评估时通常采用 ROC-AUC,因为它综合了所有阈值下的表现。

人脸识别

人脸图像通常是数千维的高维数据。SVM 配合 RBF 核在中小规模人脸识别中效果出色;KNN 配合合适的距离度量(如基于深度特征的余弦距离)也可用于人脸检索。现代系统多采用深度学习提取特征后,再用轻量级分类器(如 SVM、Softmax)做最终判别。

金融欺诈检测

信用卡欺诈交易中,欺诈样本占比可能低于 0.1%。此时准确率毫无意义,应关注精确率-召回率曲线(PR Curve)和 F1 分数。孤立森林(异常检测)和梯度提升树是主流方案,但 KNN 的局部密度思想也启发了许多异常检测算法:远离正常交易邻居的样本即为可疑交易。

04

Python 实践:分类与评估

1. KNN 分类

Python
from sklearn.neighbors import KNeighborsClassifier from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split iris = load_iris() X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.2, random_state=42, stratify=iris.target ) # K=3,欧氏距离 knn = KNeighborsClassifier(n_neighbors=3, metric="euclidean") knn.fit(X_train, y_train) print("KNN 准确率:", knn.score(X_test, y_test)) # 预测新样本 print("预测类别:", knn.predict([[5.1, 3.5, 1.4, 0.2]]))

2. 朴素贝叶斯分类

Python
from sklearn.naive_bayes import GaussianNB # 高斯朴素贝叶斯假设每个特征在各类别下服从正态分布 nb = GaussianNB() nb.fit(X_train, y_train) print("NB 准确率:", nb.score(X_test, y_test)) # 查看各类别的先验概率和均值方差参数 print("类别先验:", nb.class_prior_) print("各类别特征均值 shape:", nb.theta_.shape)

3. SVM 与核函数

Python
from sklearn.svm import SVC # 线性核 vs RBF 核 svm_linear = SVC(kernel="linear", C=1.0) svm_rbf = SVC(kernel="rbf", gamma="scale", C=1.0) for name, model in [("Linear", svm_linear), ("RBF", svm_rbf)]: model.fit(X_train, y_train) print(f"{name} SVM 准确率: {model.score(X_test, y_test):.3f}")

4. 混淆矩阵与 ROC 曲线

Python
from sklearn.metrics import confusion_matrix, classification_report, roc_curve, auc from sklearn.preprocessing import label_binarize import numpy as np # 二分类 ROC 示例(取 Iris 前两类) X_bin = iris.data[iris.target != 2] y_bin = iris.target[iris.target != 2] Xb_train, Xb_test, yb_train, yb_test = train_test_split( X_bin, y_bin, test_size=0.3, random_state=42 ) clf_bin = LogisticRegression() clf_bin.fit(Xb_train, yb_train) y_score = clf_bin.predict_proba(Xb_test)[:, 1] fpr, tpr, thresholds = roc_curve(yb_test, y_score) roc_auc = auc(fpr, tpr) print(f"AUC = {roc_auc:.3f}") # 混淆矩阵 y_pred = clf_bin.predict(Xb_test) print("混淆矩阵:\n", confusion_matrix(yb_test, y_pred)) print(classification_report(yb_test, y_pred, target_names=["Class 0", "Class 1"]))
ROC 曲线示意:AUC 越接近 1,模型区分正负类的能力越强
05

例题与解析

例题 1:KNN 分类决策

在二维平面上,某待分类样本位于 (3, 4)。训练集中最近的 5 个邻居及其类别为:(2,4) A, (4,4) A, (3,5) B, (3,3) B, (5,5) A。

问题

K=3 和 K=5 时,该样本分别被预测为哪一类?说明 K 值对决策边界的影响。

解析

计算欧氏距离:d(2,4)=1, d(4,4)=1, d(3,5)=1, d(3,3)=1, d(5,5)=√5≈2.24。最近3个为 (2,4)A, (4,4)A, (3,5)B → A 类占2/3,预测 A。K=5 时所有5个邻居参与,A 占3/5,仍预测 A。K 值小则决策边界复杂(对噪声敏感),K 值大则边界平滑(可能模糊局部结构)。

结果:K=3 预测 A;K=5 预测 A
例题 2:朴素贝叶斯计算

某邮件分类任务中,"垃圾邮件"先验概率 P(S)=0.3,"正常邮件" P(H)=0.7。词"免费"在垃圾邮件中出现概率 P(免费|S)=0.8,在正常邮件中 P(免费|H)=0.1。现收到一封包含"免费"的邮件,判断其类别。

问题

计算后验概率 P(S|免费) 和 P(H|免费),并给出预测。

解析

P(免费) = P(免费|S)P(S) + P(免费|H)P(H) = 0.8×0.3 + 0.1×0.7 = 0.31。
P(S|免费) = 0.8×0.3 / 0.31 ≈ 0.774。
P(H|免费) = 0.1×0.7 / 0.31 ≈ 0.226。
因 P(S|免费) > P(H|免费),预测为垃圾邮件。注意:即使"免费"在正常邮件中也有 10% 的出现率,但由于垃圾邮件的先验和似然都更高,后验概率仍显著偏向垃圾邮件。

结果:P(S|免费) ≈ 77.4%,预测垃圾邮件
例题 3:评估指标计算

某疾病筛查模型在 1000 人上测试,结果如下:真正例 TP=80,假正例 FP=20,真反例 TN=880,假反例 FN=20。

问题

计算准确率、精确率、召回率和 F1 分数。若全部预测为阴性,准确率是多少?

解析

准确率 = (80+880)/1000 = 96.0%。精确率 = 80/(80+20) = 80.0%。召回率 = 80/(80+20) = 80.0%。F1 = 2×0.8×0.8/(0.8+0.8) = 80.0%。若全部预测阴性,TN=900, FP=0, FN=100, TP=0,准确率 = 90%。这说明:即使模型什么都不做,准确率也可高达 90%(因疾病本身罕见),因此必须同时看召回率。

结果:准确率 96%,精确率 80%,召回率 80%,F1 = 80%
例题 4:ROC 与 AUC 理解

模型 A 的 AUC=0.95,模型 B 的 AUC=0.85。但在精确率-召回率曲线上,模型 B 在召回率 > 0.9 时的精确率反而高于模型 A。

问题

如何理解 AUC 高不等于在所有阈值/所有指标上都更优?在什么场景下应优先关注 PR 曲线而非 ROC 曲线?

解析

AUC 衡量的是模型将随机正例排在随机负例之前的概率,是对排序能力的整体度量。但 ROC 曲线的横轴 FPR 对负例数量敏感:在极度不平衡数据中(负例占 99.9%),大量负例使 FPR 变化很小,ROC 曲线容易被"拉平",显得模型表现很好。此时PR 曲线更可靠,因为它直接展示精确率与召回率的权衡。当正例稀少且漏检代价高(如罕见病筛查)时,优先使用 PR 曲线和 F1 分数。

← 上一章:回归分析 下一章:决策树与集成学习 →