机器学习的视角:从规则到数据驱动
第 1 章:机器学习的视角:从规则到数据驱动
1.1 从“写规则”到“让数据说话”
在传统的软件工程范式中,我们习惯于将问题描述为一组清晰、可执行的规则:输入是什么、输出是什么、规则如何把输入映射到输出。只要规则足够完整且无歧义,程序就能稳定运行。这种范式可以概括为:
> 显式编程(rule-based programming):人类总结规律 → 写成规则 → 计算机执行规则。
然而,许多现实问题并不适合用显式规则解决。原因并非计算机算力不足,而是规则本身难以被人类穷尽,或环境不断变化导致规则需要频繁维护。典型例子包括:
- 垃圾邮件识别:垃圾邮件的写法不断变化,手写规则很快失效。
- 语音识别与机器翻译:语言的变体、口音、语境极其复杂。
- 图像识别:用规则描述“猫长什么样”几乎不可行。
- 金融风控:欺诈行为会主动对抗规则,并随策略快速演化。
机器学习提供了另一种范式:
> 数据驱动(data-driven learning):收集数据 → 选定模型族 → 用优化方法从数据中自动拟合规律 → 在未见数据上泛化。
一句话概括机器学习的核心思想: 当规则难以被显式编写时,就把“总结规则”的工作交给算法,让它从数据中学习。
需要强调的是,“让数据说话”并不意味着否定人类知识。相反,机器学习系统几乎处处依赖人类的选择:问题定义、数据口径、特征构造、模型结构、损失函数、评估指标、上线策略与监控机制等。机器学习更像一种“以数据为证据的建模方法”,而不是“全自动的智能黑箱”。
---
1.2 机器学习、统计学、数据挖掘与人工智能:相似与边界
机器学习(Machine Learning, ML)常被放置在多个学科的交叉处。为了形成清晰的整体图景,本节给出一种实用的“分工视角”。这些领域之间没有硬边界,但其关注点确实存在差异。
1.2.1 统计学:以不确定性为核心的推断框架
统计学关注的问题通常是:在随机性与噪声存在的前提下,如何从样本推断总体规律,并量化不确定性。例如,给出估计值的置信区间、假设检验的显著性水平等。
- 统计学的语言强调:概率模型、似然、估计量性质(无偏性、一致性)、置信区间。
- 机器学习的语言强调:泛化误差、模型容量、经验风险最小化、交叉验证、正则化。
两者高度重叠:许多经典机器学习算法可被视为统计估计方法(例如线性回归、逻辑回归)。区别更多体现在目标与工程导向: 统计学常追求可解释的推断与不确定性量化;机器学习常追求预测性能与可扩展的训练流程(尤其在大数据与复杂模型中)。
1.2.2 数据挖掘:从数据中发现模式与知识
数据挖掘(Data Mining)强调在大量数据中发现结构、模式与可行动知识,例如关联规则、聚类结构、异常点、用户分群等。在应用上,它常与数据库系统、商业分析、可视化结合得更紧密。
机器学习可以被视为数据挖掘的重要方法库之一;而数据挖掘更偏“从数据到洞见”的任务组织方式,机器学习更偏“从数据到模型”的数学化训练范式。
1.2.3 人工智能:更广义的“智能系统”愿景
人工智能(AI)是更宏观的概念,目标是构建能执行智能任务的系统,包括规划、推理、搜索、知识表示、多智能体协作、人机交互等。机器学习是 AI 的关键支柱之一,但 AI 并不等同于机器学习;在不少系统中,规则、检索、规划仍然占据重要位置。
可以用一个简化关系图表达(仅为直观,不是严格学科划分):
```mermaid graph TD A[人工智能 AI] --> B[机器学习 ML] A --> C[推理/规划/搜索] B --> D[监督学习] B --> E[无监督学习] B --> F[强化学习] D --> G[统计学方法] B --> H[深度学习] I[数据挖掘] --> B I --> J[模式发现/关联/聚类] ```
---
1.3 学习任务的三要素:数据、模型与目标
机器学习的训练过程看似复杂,但从抽象层面可以压缩为三个要素:
1. 数据(Data):我们能观察到什么? 2. 模型(Model):我们用什么形式表达规律? 3. 目标(Objective):我们希望模型在何种意义上“好”?
这三者共同决定了“学习”到底在学什么,以及最终系统的行为边界。
1.3.1 数据:样本、特征与标签
在监督学习中,数据通常表示为一组样本对:
$$ \mathcal{D}=\{(x_i,y_i)\}_{i=1}^n $$
- $x_i$:第 $i$ 个样本的输入(特征向量),常记为 $x_i\in\mathbb{R}^d$。
- $y_i$:第 $i$ 个样本的输出(标签),可能是连续值(回归)、类别(分类)或更复杂结构(序列、图、文本)。
特征(feature)是机器学习的“观测语言”。如果观测语言不合适,模型即使再复杂也难以成功。特征可以来自:
- 直接测量(温度、点击次数、时长、交易金额)
- 统计汇总(过去 7 天均值、最大值、增长率)
- 表示学习(如文本的向量表示、图像的嵌入表示)
数据的关键挑战往往不在于“有没有数据”,而在于:
- 数据是否代表真实分布(是否存在抽样偏差)
- 标签是否可靠(标注噪声、延迟反馈)
- 特征是否泄露未来信息(data leakage)
- 数据口径是否一致(时间窗、去重、单位、缺失处理)
- 数据是否随时间漂移(distribution shift)
这些问题决定了机器学习不仅是“算法问题”,更是“数据与系统问题”。
1.3.2 模型:函数族与假设空间
模型本质上是一类可调函数。我们常写作:
$$ \hat{y}=f_\theta(x) $$
- $f$:模型形式(线性函数、树模型、神经网络等)
- $\theta$:模型参数(权重、阈值、树分裂规则等)
- $f_\theta$ 所能表达的所有函数集合称为**假设空间(hypothesis space)**,记为 $\mathcal{H}$
直觉上:
- 假设空间太小 → 模型表达能力不足 → 欠拟合(underfitting)
- 假设空间太大 → 容易记住训练数据噪声 → 过拟合(overfitting)
这引出机器学习的核心矛盾之一:拟合训练数据与在新数据上泛化之间的张力。
1.3.3 目标:损失函数、风险与优化
模型好不好,需要一个可计算的标准。监督学习常用损失函数(loss function)衡量单个样本预测误差:
$$ \ell(\hat{y},y) $$
例如:
- 回归常用平方损失:$\ell(\hat{y},y)=(\hat{y}-y)^2$
- 二分类常用对数损失(交叉熵的一种形式)
对整个数据集,常用经验风险(empirical risk):
$$ R_n(\theta)=\frac{1}{n}\sum_{i=1}^n \ell(f_\theta(x_i),y_i) $$
训练就是求解优化问题:
$$ \theta^\*=\arg\min_\theta \; R_n(\theta) + \lambda \Omega(\theta) $$
其中:
- $\Omega(\theta)$:正则项(regularization),用于限制模型复杂度
- $\lambda$:正则强度(超参数)
常见正则例子:
- $L_2$ 正则:$\Omega(\theta)=\|\theta\|_2^2$
- $L_1$ 正则:$\Omega(\theta)=\|\theta\|_1$
优化(optimization)是把目标函数最小化的计算过程。许多模型依赖梯度下降及其变种:
$$ \theta \leftarrow \theta - \eta \nabla_\theta \Big(R_n(\theta)+\lambda \Omega(\theta)\Big) $$
- $\eta$:学习率(learning rate)
到这里可以看到,机器学习训练并不神秘:它是“用数据定义损失,再用优化算法寻找最小损失参数”的过程。真正困难之处通常在于:数据是否可信、目标是否匹配业务、评估是否可靠、上线后是否稳定。
---
1.4 一眼看懂的端到端案例:用可解释模型预测房价
为了将抽象概念落到具体流程,本节用一个可解释、贴近生活的监督学习问题展示端到端路径。我们选择“房价预测”是因为它直观且便于解释模型系数。
1.4.1 问题定义:预测什么,服务什么决策?
假设我们希望给出某城市二手房的参考成交价,用于:
- 购房者:评估是否买贵
- 卖房者:制定挂牌价
- 中介平台:排序推荐与议价辅助
将问题形式化为回归任务:
- 输入 $x$:房屋特征(面积、房龄、楼层、地铁距离、学区、装修等)
- 输出 $y$:成交价(例如单位:万元)
关键点: 模型输出应服务决策,而不是追求数学上的“最小误差”本身。 例如,平台可能更关心“误差在 5% 以内的比例”,或对某些区域的公平性约束。
1.4.2 数据收集:样本从哪里来?
数据来源可能包括:
- 历史成交记录(成交价、成交时间)
- 房源结构化信息(面积、户型、楼层、朝向)
- 地理信息(经纬度、周边配套)
- 宏观信息(利率、政策、学区划片变动)
在实际系统中,数据收集阶段必须明确:
- 时间范围:过去 24 个月?过去 5 年?
- 覆盖范围:哪些区域、哪些小区?
- 标签定义:成交价是总价还是单价?含税吗?是否包含车位?
这些“口径选择”决定了模型学习到的究竟是哪种规律。
1.4.3 数据清洗:缺失、异常、口径与泄露
常见清洗与风险包括:
1. 缺失值处理
- 面积缺失:删除样本还是插补?
- 地铁距离缺失:可能代表无法定位,需谨慎处理
2. 异常值与极端点
- 录入错误(多一个 0)
- 极端豪宅(模型可能被拉偏)
3. 时间一致性与泄露(data leakage) 若特征中包含“成交后才能知道的信息”(如最终议价幅度),训练时会得到虚高表现,上线必然崩溃。 4. 重复样本与多次挂牌 同一房源多次挂牌可能造成相关性过强,需按房源 ID 去重或按时间处理。
数据清洗并非“琐碎工作”,而是模型可靠性的根基。大量“算法无效”的根因,实则是数据口径与标签定义不稳定。
1.4.4 特征工程:把现实描述成可学习的变量
以线性回归为例,一个简单且可解释的特征集合可以包括:
- $x_1$:面积(平方米)
- $x_2$:房龄(年)
- $x_3$:到最近地铁站距离(米)
- $x_4$:是否学区房(0/1)
- $x_5$:楼层(数值或分档)
- $x_6$:区域(类别特征,需独热编码)
类别特征如“区域”通常需编码成向量(独热或其他编码),否则线性模型无法直接使用。
特征工程的一个重要原则是: 让特征“在预测时可获得”,并且与目标变量存在稳定关系。
1.4.5 训练:选择模型并拟合参数
一个可解释的起点模型是线性回归:
$$ \hat{y}=w^\top x + b $$
其中 $w$ 表示每个特征的边际贡献(在其他特征不变的条件下)。
训练时最常见的目标之一是最小化均方误差(MSE):
$$ \min_{w,b}\frac{1}{n}\sum_{i=1}^n (w^\top x_i + b - y_i)^2 $$
如果担心过拟合(尤其是特征维度高、样本相对少),可加入 $L_2$ 正则(岭回归):
$$ \min_{w,b}\frac{1}{n}\sum_{i=1}^n (w^\top x_i + b - y_i)^2 + \lambda \|w\|_2^2 $$
这样会倾向于较小的权重,从而减少模型对噪声的敏感性。
下面给出一段简化的训练伪代码(用于直觉理解,不强调工程细节):
```python import numpy as np
def train_ridge_regression(X, y, lr=1e-2, lam=1e-2, steps=2000): n, d = X.shape w = np.zeros(d) b = 0.0
for _ in range(steps): y_hat = X @ w + b
MSE loss + L2 regularization
grad_w = (2/n) * (X.T @ (y_hat - y)) + 2 * lam * w grad_b = (2/n) * np.sum(y_hat - y)
w -= lr * grad_w b -= lr * grad_b
return w, b ```
这段代码体现了机器学习的典型结构: 定义模型 → 定义损失 → 计算梯度 → 迭代优化参数。
1.4.6 评估:训练集表现不等于真实表现
评估的核心是回答:模型在“未来新样本”上表现如何?因此需要划分数据集:
- 训练集(train):用于拟合参数
- 验证集(validation):用于调参、选模型
- 测试集(test):用于最终报告性能(尽量只用一次)
常见评估指标:
- MAE:平均绝对误差(更直观,抗异常值)
- RMSE:均方根误差(对大误差更敏感)
- MAPE:平均绝对百分比误差(相对误差,适合价格尺度变化大)
在房价预测中,若业务更关心“相对偏差”,MAPE 往往比 RMSE 更贴近体验;但 MAPE 在真实值接近 0 时会不稳定,因此指标选择必须结合业务语义。
1.4.7 上线:从离线模型到在线系统
模型上线并非“把模型文件放到服务器”。一个可运行的机器学习系统至少包括:
- 特征生成与一致性:在线特征必须与训练特征同口径
- 模型服务:低延迟、可扩展
- 监控与告警:输入分布漂移、输出异常、性能下降
- A/B 测试:线上指标验证(转化率、停留时长、投诉率等)
- 回滚机制:异常时快速切换到旧模型或规则策略
可以用一个端到端流程图概括:
```mermaid graph LR A[需求定义与指标] --> B[数据收集] B --> C[数据清洗与标注] C --> D[特征工程] D --> E[训练与调参] E --> F[离线评估] F --> G[上线部署] G --> H[线上监控与A/B测试] H --> I[数据回流与迭代] I --> D ```
注意最后的回环:机器学习不是一次性项目,而是持续迭代的工程系统。上线后数据分布变化、用户行为变化、政策变化都会让模型退化,这要求系统具备持续学习与持续评估能力。
---
1.5 泛化能力与过拟合:机器学习的“第一性矛盾”
如果说机器学习有一个贯穿始终的主题,那就是:泛化(generalization)。我们训练模型的目的不是在训练集上拿满分,而是在未来数据上保持稳定表现。
1.5.1 训练误差与测试误差:为何会分离?
训练过程最小化的是经验风险 $R_n(\theta)$,它只关心训练集。但真正关心的往往是总体风险(期望风险):
$$ R(\theta)=\mathbb{E}_{(x,y)\sim \mathcal{P}}[\ell(f_\theta(x),y)] $$
其中 $\mathcal{P}$ 是真实世界数据分布。由于我们无法直接访问总体,只能用有限样本近似,因此会出现:
- 训练误差很低,但测试误差很高:过拟合
- 训练误差很高,测试误差也高:欠拟合
直觉上,过拟合意味着模型把训练数据中的“偶然性”当成“规律”记住了。
1.5.2 一个可视化直觉:模型复杂度与误差的 U 型关系
当模型复杂度增加时:
- 训练误差通常单调下降(更容易拟合)
- 测试误差往往先下降后上升(先学到规律,后开始记噪声)
这并不是“复杂模型一定差”,而是提醒我们:复杂度必须与数据规模、噪声水平、正则化手段相匹配。深度学习之所以能用极复杂模型取得成功,靠的不只是模型容量,还包括大规模数据、强正则、合适结构、优化技巧与工程系统。
1.5.3 正则化:限制模型“胡来”的方式
常见正则化手段包括:
- **参数范数惩罚**:如 $L_2$(岭回归)、$L_1$(稀疏化)
- **早停(early stopping)**:验证集性能不再提升就停止训练
- **数据增强**:对输入做合理变换(图像翻转、裁剪;文本扰动等)
- **交叉验证**:更稳健地估计泛化误差
- **结构约束**:例如树的最大深度、神经网络的 dropout
这些方法背后的共同理念是: 宁可少学一点训练集细节,也要在新数据上稳健。
1.5.4 偏差—方差:理解欠拟合与过拟合的语言
在更统计化的表述中,我们常用偏差—方差分解来解释误差来源(在特定假设下成立):
- **偏差(bias)**:模型假设过强导致无法表达真实规律(欠拟合)
- **方差(variance)**:模型对数据扰动过于敏感(过拟合)
- **噪声(noise)**:数据本身的不可约误差(测量误差、随机性)
工程实践中,你可以把它当作调参的指南针:
- 欠拟合:更强模型、更丰富特征、训练更久
- 过拟合:更多数据、更强正则、更简模型、改善数据质量
---
1.6 统一语言:本书的符号约定
为了让后续章节在数学表达上保持一致,本书采用以下常用约定(并非唯一标准,但会贯穿全书):
1. 标量、向量、矩阵
- 标量:$x, y, \lambda$
- 向量:$x\in\mathbb{R}^d$(必要时用粗体 $\mathbf{x}$ 表示)
- 矩阵:$X\in\mathbb{R}^{n\times d}$($n$ 个样本,$d$ 维特征)
2. 数据集与样本
- 数据集:$\mathcal{D}=\{(x_i,y_i)\}_{i=1}^n$
- 第 $i$ 个样本:$(x_i,y_i)$
3. 模型与参数
- 模型:$f_\theta(\cdot)$
- 参数:$\theta$(线性模型中常写 $w,b$)
4. 预测与损失
- 预测:$\hat{y}=f_\theta(x)$
- 损失函数:$\ell(\hat{y},y)$
- 经验风险:$R_n(\theta)=\frac{1}{n}\sum_{i=1}^n \ell(f_\theta(x_i)