Skip to content

监督学习

本页介绍传统机器学习中按监督信号划分的第一大类——监督学习(Supervised Learning):从有标注数据学习输入到输出的映射。它是传统 ML 分类树中最主干的一支,集成学习(见集成学习与随机森林)大多以监督学习器为基学习器。监督学习是最经典的机器学习范式:每个训练样本都有一个”正确答案”(标签),模型的目标是学会从输入特征到标签的映射函数。

监督学习的本质很简单:给你一堆”题目—答案”对,让模型学会做题的规律。四大经典算法各自的直觉:

  • 决策树 = 自动玩”20 问”游戏:每个节点问一个最有信息量的问题(“花瓣长度 > 2.45cm 吗?”),不断二分,直到能确定答案。简单、可解释、能处理混合类型特征。详见决策树。
  • SVM(支持向量机)= 找最宽的路:想象两类数据是马路两边的人群,SVM 要找一条分界线,让马路(间隔)最宽——路越宽,新数据点越不容易被分错。深入解析见 SVM 支持向量机。
  • k-NN = 近朱者赤:看你周围最近的 k 个邻居属于哪类,就投票决定你属于哪类。懒惰学习(Lazy Learning,不训练模型,预测时才计算),简单到只需一句代码。
  • 朴素贝叶斯 = 带独立假设的贝叶斯推断:假设所有特征互相独立,然后用贝叶斯公式算概率——虽然假设”太天真”,但文本分类效果出奇地好。

监督学习按输出类型分为两大子任务:

  • 分类(Classification):输出是离散的类别标签。如垃圾邮件检测(垃圾/正常)、图像识别(猫/狗/鸟)、信用评级(A/B/C/D)。
  • 回归(Regression):输出是连续的数值。如房价预测(多少万元)、温度预测(多少度)、销量预测(多少件)。

关键区别:分类预测”是什么”,回归预测”是多少”。逻辑回归(Logistic Regression)虽然名字里有”回归”,但它实际是分类算法——用 sigmoid 函数把线性回归的输出压缩到 [0,1] 区间表示概率。

偏差-方差权衡(Bias-Variance Tradeoff)

Section titled “偏差-方差权衡(Bias-Variance Tradeoff)”

监督学习的核心理论框架——模型的总泛化误差可以分解为三部分:

Error=Bias2+Variance+Noise\text{Error} = \text{Bias}^2 + \text{Variance} + \text{Noise}
  • 偏差(Bias):模型预测值的期望与真实值之间的差异。偏差高意味着模型太简单,“学不到位”(欠拟合)。例如用一条直线拟合弯曲的数据。
  • 方差(Variance):不同训练集训练出的模型预测值的变化幅度。方差高意味着模型太敏感,“换一组数据就变”(过拟合)。例如一棵极深的决策树。
  • 噪声(Noise):数据本身的不可约误差,无法通过模型改进消除。

实践意义:降低偏差的方法——用更复杂的模型(如从线性回归换到随机森林);降低方差的方法——用正则化、更多数据、或集成方法(如 Bagging)。深度学习的成功很大程度上归功于”大模型 + 大数据”同时降低了偏差和方差。

虽然监督学习页不展开逻辑回归的完整推导(这是 NLP/统计学习的基础),但其核心思想值得理解。逻辑回归用 sigmoid 函数 σ(z)=1/(1+e−z)\sigma(z) = 1/(1+e^{-z}) 把线性模型 z=wTx+bz = w^T x + b 的输出映射为概率:

P(y=1∣x)=σ(wTx+b)=11+e−(wTx+b)P(y=1 \mid x) = \sigma(w^T x + b) = \frac{1}{1 + e^{-(w^T x + b)}}

训练目标是最小化交叉熵损失(Cross-Entropy Loss):

L=−∑i[yilog⁡pi+(1−yi)log⁡(1−pi)]\mathcal{L} = -\sum_i \left[ y_i \log p_i + (1-y_i) \log(1-p_i) \right]

直觉:sigmoid 把线性输出”S 形”地压到 [0,1]。wTx+bw^T x + b 很大时概率接近 1(确信是正类),很小时接近 0(确信是负类),在 0 附近为 0.5(不确定)。交叉熵损失在模型”确信但猜错”时惩罚极大——这正是我们想要的。

k-NN 看似简单,背后有深刻的统计学习理论保证。Cover 定理指出:在高维空间中,最近邻分类器的期望误差率不超过贝叶斯最优误差(Bayes Optimal Error,即理论上最好的分类器)的两倍。当 k→∞k \to \infty 且 k/N→0k/N \to 0(NN 是样本量)时,k-NN 的误差趋近于贝叶斯误差。

距离度量选择:

  • 欧氏距离(Euclidean):∥x−z∥2=∑i(xi−zi)2\|x - z\|_2 = \sqrt{\sum_i (x_i - z_i)^2},最常用
  • 曼哈顿距离(Manhattan):∥x−z∥1=∑i∣xi−zi∣\|x - z\|_1 = \sum_i |x_i - z_i|
  • 余弦相似度(Cosine):x⋅z∥x∥∥z∥\frac{x \cdot z}{\|x\| \|z\|},适合文本等高维稀疏向量
  • 马氏距离(Mahalanobis):考虑特征间相关性,消除量纲影响

维度灾难对 k-NN 的影响:在高维空间中,所有点对之间的距离趋于相同——“最近的邻居”不再比其他点近多少,k-NN 的区分力急剧下降。这就是为什么 k-NN 在图像(数万维像素)上效果差,但在低维特征空间中效果好的原因。

朴素贝叶斯基于贝叶斯定理和条件独立假设。给定特征 x=(x1,…,xd)x = (x_1, \ldots, x_d) 和类别 cc:

P(c∣x)=P(x∣c) P(c)P(x)∝P(c)∏i=1dP(xi∣c)P(c \mid x) = \frac{P(x \mid c) \, P(c)}{P(x)} \propto P(c) \prod_{i=1}^d P(x_i \mid c)

“朴素”(Naive)体现在假设所有特征在给定类别后条件独立:P(x1,…,xd∣c)=∏iP(xi∣c)P(x_1, \ldots, x_d \mid c) = \prod_i P(x_i \mid c)。这个假设几乎总是不成立的,但实践中效果出奇地好——因为即使假设错误,后验概率的排序(argmax)往往仍然正确。

为什么朴素贝叶斯适合文本分类:文本经过词袋模型(Bag of Words)处理后,每个词的出现频率是一个特征。“给定这是一封垃圾邮件,‘免费’这个词出现的概率”与”给定这是一封垃圾邮件,‘点击’这个词出现的概率”——虽然这两个词的出现不完全独立,但独立性假设给出了一个可计算且效果不错的近似。

决策树选择分裂特征的核心是信息增益(Information Gain)。信息熵(Entropy)衡量不确定性:

H(S)=−∑k=1Kpklog⁡2pkH(S) = -\sum_{k=1}^{K} p_k \log_2 p_k

其中 pkp_k 是节点 SS 中第 kk 类样本的比例。熵越大越混乱(越不纯)。

用特征 AA 分裂后的信息增益:

Gain(S,A)=H(S)−∑v∈Values(A)∣Sv∣∣S∣H(Sv)\text{Gain}(S, A) = H(S) - \sum_{v \in \text{Values}(A)} \frac{|S_v|}{|S|} H(S_v)

直觉:分裂前节点的不确定性减去分裂后的平均不确定性——差值越大说明这个分裂越”有用”(减少了更多不确定性)。这与信息论基础中的互信息概念一致。决策树的完整原理见决策树。

过拟合(Overfitting)是监督学习的头号敌人:模型把训练数据”背下来”了(包括噪声),但对新数据泛化能力差。控制过拟合的方法统称正则化(Regularization):

方法适用模型核心思想
L1 正则(Lasso)线性模型惩罚权重绝对值之和,使部分权重归零(特征选择)
L2 正则(Ridge)线性模型、神经网络惩罚权重平方和,使权重整体变小但非零
Dropout神经网络训练时随机丢弃部分神经元,强迫网络学习冗余表示
剪枝决策树限制树深度或合并叶子节点
早停(Early Stopping)迭代训练的模型验证集性能不再提升时停止训练
数据增强深度学习通过变换(翻转、裁剪等)增加训练数据多样性

决策树通过不断”提问”来分割数据,每个问题选择信息增益最大的特征:

SVM 不只是”分开”两类,而是要找间隔最大的分界超平面:

支持向量(Support Vector)就是离分界线最近的那些点——它们”撑住”了间隔,移除其他点不影响结果,这也是 SVM 名字的由来。

面对一个具体的分类/回归任务,按下面的流程快速锁定候选算法:

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 加载鸢尾花数据集
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
# 训练决策树(限制深度防止过拟合)
clf = DecisionTreeClassifier(max_depth=3, random_state=42)
clf.fit(X_train, y_train)
# 评估
pred = clf.predict(X_test)
print(f"准确率: {accuracy_score(y_test, pred):.2%}")
# 输出: 准确率: 100.00%

SVM 分类(make_classification 数据)

Section titled “SVM 分类(make_classification 数据)”
from sklearn.datasets import make_classification
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
# 生成二分类数据
X, y = make_classification(n_samples=500, n_features=10, random_state=42)
# SVM 对量纲敏感,必须标准化
X = StandardScaler().fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
# 用 RBF 核的 SVM
svm = SVC(kernel="rbf", C=1.0)
svm.fit(X_train, y_train)
print(f"准确率: {accuracy_score(y_test, svm.predict(X_test)):.2%}")
# 输出示例: 准确率: 92.80%
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_wine
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
import numpy as np
X, y = load_wine(return_X_y=True)
X = StandardScaler().fit_transform(X) # k-NN 也必须标准化
# 对比不同 k 值
for k in [1, 3, 5, 7, 11]:
knn = KNeighborsClassifier(n_neighbors=k)
scores = cross_val_score(knn, X, y, cv=5, scoring='accuracy')
print(f"k={k:2d}: 准确率 {scores.mean():.3f} ± {scores.std():.3f}")
# k 太小(k=1)方差大(过拟合),k 太大偏差大(欠拟合),选中间值最稳定
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 模拟邮件数据
emails = [
"免费优惠 立即点击领取", "会议纪要请查收", "恭喜中奖 点击领取奖品",
"项目进度报告", "限时折扣 不要错过", "关于代码审查的通知",
"免费试用 信用卡办理", "下周会议议程安排",
]
labels = [1, 0, 1, 0, 1, 0, 1, 0] # 1=垃圾邮件, 0=正常邮件
X_tr, X_te, y_tr, y_te = train_test_split(emails, labels, test_size=0.25, random_state=42)
# TF-IDF + 朴素贝叶斯 pipeline
model = make_pipeline(TfidfVectorizer(), MultinomialNB())
model.fit(X_tr, y_tr)
print(classification_report(y_te, model.predict(X_te), target_names=["正常", "垃圾"]))

完整流水线:从数据到预测新样本

Section titled “完整流水线:从数据到预测新样本”

真实业务中,模型训练完不是终点——你还需要用它对没见过的新样本做预测。完整流程如下:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 第 1 步:加载数据(特征 + 标签)
X, y = load_iris(return_X_y=True)
# 第 2 步:划分训练集 / 测试集(stratify 保证类别比例一致)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y)
# 第 3 步:标准化——只对训练集 fit,测试集只 transform(防止数据泄露)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# 第 4 步:训练模型
clf = LogisticRegression(max_iter=200, random_state=42)
clf.fit(X_train, y_train)
# 第 5 步:评估
pred = clf.predict(X_test)
print(f"测试集准确率: {accuracy_score(y_test, pred):.2%}")
# 输出示例: 测试集准确率: 97.37%
# 第 6 步:预测新样本——用同一套 scaler 变换后再预测
new_sample = [[5.1, 3.5, 1.4, 0.2]] # 一朵新花的 4 个测量值
new_sample_scaled = scaler.transform(new_sample)
pred_label = clf.predict(new_sample_scaled)[0]
print(f"新样本预测类别: {load_iris().target_names[pred_label]}")
# 输出示例: 新样本预测类别: setosa

关键点:测试集标准化必须用训练集 fit 出的统计量(scaler.transform 而非重新 fit_transform),否则测试集信息被”偷看”了,评估会虚高。

决策树不限制深度时会把训练集”背下来”——训练集 100% 正确,但测试集反而变差:

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
# 构造"样本少、噪声大"的数据:最容易过拟合的场景
X, y = make_classification(n_samples=300, n_features=20, n_informative=10,
n_redundant=5, class_sep=0.8, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
for max_depth in [None, 3]:
clf = DecisionTreeClassifier(max_depth=max_depth, random_state=42)
clf.fit(X_train, y_train)
train_acc = accuracy_score(y_train, clf.predict(X_train))
test_acc = accuracy_score(y_test, clf.predict(X_test))
label = "不限制深度(过拟合)" if max_depth is None else "max_depth=3(剪枝)"
print(f"{label:>16}: 训练集 {train_acc:.2%} / 测试集 {test_acc:.2%}")

运行结果示例——不限制深度的树训练集 100% 但测试集只有 74.67%(背答案);而 max_depth=3 的树训练集略低、测试集反而更高(77.33%)——这就是”学规律”与”背答案”的区别:

不限制深度(过拟合): 训练集 100.00% / 测试集 74.67%
max_depth=3(剪枝): 训练集 81.33% / 测试集 77.33%
  • 决策树容易过拟合:不限制深度时,树会一直长到每个叶子只有 1 个样本。务必设置 max_depth、min_samples_leaf 等参数剪枝。
  • SVM 核函数选择经验:特征少(< 1000)、样本中等(< 10 万)→ 优先试 RBF 核;特征非常多(如文本 TF-IDF)→ 线性核更快更好;样本量 > 10 万 → SVM 训练太慢,考虑树模型或线性方法。详见 SVM。
  • SVM 对数据量纲敏感:使用前务必 StandardScaler 或 MinMaxScaler,否则大范围特征会”淹没”小范围特征。
  • k-NN 也要标准化,且数据量大时预测慢(每次要算到所有点的距离)。可用 KD-Tree 或 Ball-Tree 加速。
  • 逻辑回归虽然名字带”回归”,但实际是分类算法,适合作为 baseline 快速跑。它训练快、输出有概率解释、且在高维稀疏数据上表现优异。
  • 朴素贝叶斯是最快的分类器之一:训练和预测都是线性时间,适合做 baseline 和实时系统。
  • 评估要用交叉验证:单一训练/测试划分的结果不够可靠,用 5 折或 10 折交叉验证取平均更稳健。详见交叉验证。
  • 2025 年表格数据实践建议:对于中等规模表格数据(< 100 万样本),XGBoost/LightGBM(见梯度提升树详解)仍是首选——研究表明它们在表格数据上至今优于深度学习。只有在大规模、高维非结构化数据(图像、文本)上深度学习才有明显优势。
  • 决策树 → 信用评分卡:银行用决策树将客户收入、负债、历史记录等特征转化为可解释的评分规则,审批贷款时一目了然——这是传统金融风控的核心工具。
  • SVM → 人脸检测:线性 SVM 对 Haar 特征分类,经典 Viola-Jones 检测框架的底层分类器,早期数码相机和手机的人脸对焦就靠它。
  • SVM → 文本分类:线性 SVM 在高维稀疏的 TF-IDF 特征上表现优异,曾是新闻分类、垃圾邮件过滤的主流方法。
  • 朴素贝叶斯 → 垃圾邮件过滤:根据邮件中关键词频率算后验概率,Gmail 早期反垃圾系统即基于此。
  • 朴素贝叶斯 → 情感分析:分析电商评论、微博评论的正负面情绪,用于品牌口碑监控——Naive Bayes 因速度快、效果好,是情感分析的入门标配。
  • k-NN → 推荐系统:“喜欢这件商品的人还买了…”本质就是找相似用户/物品(k 近邻),Spotify 早期音乐推荐、Amazon 的”购买此商品的顾客也购买了”都基于此思路。详见推荐系统。
  • k-NN → 图像检索:以图搜图,用特征向量找视觉最相似的 k 张图片——Google Images 早期的相似图片搜索就用过 k-NN。
  • 逻辑回归 → 点击率预估(CTR):Google、Facebook 等广告系统用逻辑回归预估用户点击广告的概率,决定展示排序和出价——这是百亿美元级业务的核心模型。
类库语言说明
scikit-learnPython提供决策树、SVM、k-NN、朴素贝叶斯、逻辑回归等全套监督学习算法
LIBSVMC++/Python台湾大学开发的高效 SVM 核心库,scikit-learn 的 SVM 底层后端
XGBoostC++/Python高性能梯度提升树库,监督学习中表格数据的强力方法
statsmodelsPython侧重逻辑回归等统计模型的参数推断与显著性检验
NLTKPython自然语言工具包,内置朴素贝叶斯等文本分类工具
术语英文解释
监督学习Supervised Learning从有标注数据学习输入到输出映射的机器学习范式
分类Classification输出为离散类别标签的监督学习任务
回归Regression输出为连续数值的监督学习任务
信息增益Information Gain决策树 ID3 选择分裂特征的依据,衡量划分后不确定性的减少量
基尼不纯度Gini Impurity决策树 CART 选择分裂特征的指标,衡量集合中类别混乱程度
支持向量Support Vector离 SVM 决策边界最近的样本点,它们”撑住”了间隔
核技巧Kernel TrickSVM 在不显式映射的情况下计算高维特征空间内积的方法
逻辑回归Logistic Regression用 sigmoid 函数将线性输出映射为概率的二分类线性模型
交叉熵Cross-Entropy衡量两个概率分布差异的损失函数,分类任务的标配
k 近邻k-Nearest Neighbors根据最近 k 个邻居的类别投票分类的懒惰学习方法
偏差-方差权衡Bias-Variance Tradeoff模型总误差来自偏差(欠拟合)和方差(过拟合)的此消彼长
正则化Regularization在损失函数中加入模型复杂度惩罚项以防止过拟合的技术
过拟合Overfitting模型过度拟合训练数据(含噪声),导致泛化能力差
欠拟合Underfitting模型太简单无法捕捉数据中的规律,训练集和测试集表现都差
朴素贝叶斯Naive Bayes基于贝叶斯定理和特征条件独立假设的概率分类器
贝叶斯最优误差Bayes Optimal Error理论上的最低可能误差,由数据中的不可约噪声决定
  • 决策树谱系:1960s Hunt 的 CLS 开端 → Quinlan 的 ID3(1986,信息增益)→ C4.5(1993,增益率);统计学界 Breiman 等的 CART(1984,Gini 不纯度 + 剪枝)。决策树是”可解释/玻璃盒”模型,也是随机森林与 GBDT 的基学习器。详见决策树。
  • SVM 谱系:理论源头是 Vapnik 1960s 的统计学习理论(VC 维、结构风险最小化);1992 年引入 kernel trick,1995 年 Cortes & Vapnik 提出 soft margin 定型。1990s–2012 年间是传统 ML 的”顶峰”方法。深入解析见SVM 支持向量机。
  • 朴素贝叶斯:贝叶斯网络的特例(星型结构 + 条件独立假设),文本分类经典方法。贝叶斯网络作为概率图模型见概率图模型与半监督学习。
  • k-NN / 逻辑回归:均源自 1950s 的统计方法,说明传统 ML 与统计学高度重叠(Hastie 等的经典教材书名就叫《统计学习基础》The Elements of Statistical Learning)。
  • 偏差-方差权衡:Geman et al. 1992 “Neural Networks and the Bias/Variance Dilemma”——经典的理论分析,至今是理解模型泛化的核心框架。
  • 推荐教材:Hastie, Tibshirani & Friedman,《The Elements of Statistical Learning》(2nd ed., 2009,免费在线)——监督学习的统计理论圣经;周志华《机器学习》(2016,“西瓜书”)——中文入门首选。