AMA4680 统计机器学习教程:从正则化、核方法、分类器到聚类与 MDP

这篇文章根据 AMA4680 Statistical Machine Learning 的讲义和 tutorial 资料整理。它适合作为一篇经典机器学习入门到进阶的路线图:先从线性代数与回归复习开始,然后进入 ridge / lasso / kernel methods,再到分类问题中的 decision tree、Naive Bayes、SVM、logistic regression、ANN,最后补上无监督学习的 clustering 和强化学习基础 MDP。

如果 AMA3602 更像“怎样把一个线性模型建扎实”,那么 AMA4680 更像“怎样理解经典机器学习算法家族”。这门课的价值不只是会背算法公式,而是建立一个清晰框架:什么是监督学习,为什么需要正则化,核方法在做什么,分类器如何定义边界,无监督学习如何发现结构,MDP 如何把机器学习从预测推进到决策。

原始资料:

1. 这门课在机器学习体系里的位置

机器学习可以先粗分成三类:

类型 训练数据 目标 典型算法
监督学习 有特征 xx 和标签 yy 学到 xyx\to y 的映射 linear regression, logistic regression, SVM, neural network
无监督学习 只有特征 xx 发现数据结构 PCA, k-means, hierarchical clustering, GMM
强化学习 状态、动作、奖励 学会做决策 MDP, value iteration, policy iteration

AMA4680 的主线基本覆盖这三类,但重点还是经典统计机器学习。它不急着跳到大模型,而是先回答几个基础问题:

  1. 模型为什么会过拟合?
  2. 正则化为什么能让模型更稳?
  3. kernel 为什么可以让线性方法处理非线性问题?
  4. 分类器怎样定义 decision boundary?
  5. 聚类没有 label 时到底在优化什么?
  6. MDP 如何把“预测”变成“选择动作”?

这几个问题是后面学习深度学习、推荐系统、RAG 评估、RLHF、Agent planning 时都会反复遇到的底层问题。

2. 线性代数与回归:机器学习的底座

经典机器学习大量使用向量、矩阵、内积、范数和投影。一个样本通常写成向量:

x=(x1,x2,,xp)TRpx=(x_1,x_2,\ldots,x_p)^T\in\mathbb R^p

一个数据集可以写成 design matrix:

X=[x11x12x1px21x22x2pxn1xn2xnp]X= \begin{bmatrix} x_{11} & x_{12} & \cdots & x_{1p}\\ x_{21} & x_{22} & \cdots & x_{2p}\\ \vdots & \vdots & \ddots & \vdots\\ x_{n1} & x_{n2} & \cdots & x_{np} \end{bmatrix}

线性回归写成:

y=Xβ+εy=X\beta+\varepsilon

普通最小二乘的估计量是:

β^=(XTX)1XTy\hat\beta=(X^TX)^{-1}X^Ty

这条公式在机器学习里非常重要,因为它揭示了两个事实:

  1. 训练模型本质上是在优化一个目标函数。
  2. 如果 XTXX^TX 不稳定,模型参数也会不稳定。

这就自然引出正则化。

3. 正则化:为什么不能只追求训练误差最小

如果只追求训练误差最小,模型可能把噪声也学进去。机器学习关心的不是训练集上的完美拟合,而是新数据上的泛化能力。

典型目标应该是:

loss on data+penalty on complexity\text{loss on data} + \text{penalty on complexity}

这个思想就是正则化。

3.1 Ridge Regression

Ridge regression 在最小二乘后面加 L2 penalty:

minβyXβ22+λβ22\min_\beta \|y-X\beta\|_2^2+\lambda\|\beta\|_2^2

解为:

β^ridge=(XTX+λI)1XTy\hat\beta_{ridge}=(X^TX+\lambda I)^{-1}X^Ty

和 OLS 相比,ridge 在 XTXX^TX 上加了 λI\lambda I,让矩阵更容易求逆,也让系数不会过度膨胀。

Ridge 的特点:

  • 可以缓解多重共线性。
  • 会把系数往 0 收缩。
  • 通常不会让系数精确变成 0。
  • 更偏向稳定预测,而不是自动变量选择。

Python 例子:

1
2
3
4
5
6
7
8
9
10
11
12
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

model = Ridge(alpha=1.0)
model.fit(X_train, y_train)

pred = model.predict(X_test)
rmse = mean_squared_error(y_test, pred, squared=False)
print(rmse)

3.2 LASSO

LASSO 使用 L1 penalty:

minβyXβ22+λβ1\min_\beta \|y-X\beta\|_2^2+\lambda\|\beta\|_1

它和 ridge 最大的区别是:LASSO 可以把一些系数压成 0,因此可以做变量选择。

Python 例子:

1
2
3
4
5
6
from sklearn.linear_model import Lasso

model = Lasso(alpha=0.05)
model.fit(X_train, y_train)

print(model.coef_)

如果你想处理共线性和预测稳定性,ridge 常常是好起点;如果你希望模型自动筛变量,LASSO 更有用。

4. Kernel Methods:把线性模型搬到高维空间

很多数据在原始空间里不是线性可分的。Kernel method 的核心思想是:不显式构造高维特征,而是通过 kernel function 计算样本之间的相似度。

一个 kernel 是函数:

K(x,z)K(x,z)

可以理解成某个隐藏特征空间里的内积:

K(x,z)=ϕ(x),ϕ(z)K(x,z)=\langle \phi(x),\phi(z)\rangle

常见 kernel:

Kernel 形式 直觉
Linear K(x,z)=xTzK(x,z)=x^Tz 原始空间内积
Polynomial K(x,z)=(1+xTz)dK(x,z)=(1+x^Tz)^d 加入多项式交互
Gaussian/RBF K(x,z)=exp(xz2)K(x,z)=\exp(-|x-z|^2) 距离越近越相似

Kernel 的好处是:模型可以学习非线性关系,但计算时仍然只使用 Gram matrix。

4.1 Kernel Ridge Regression

KRR 的预测函数写成:

f^(x)=i=1nciK(xi,x)\hat f(x)=\sum_{i=1}^n c_iK(x_i,x)

系数为:

c=(K+λnI)1yc^*=(K+\lambda nI)^{-1}y

其中 KK 是 Gram matrix,Kij=K(xi,xj)K_{ij}=K(x_i,x_j)

Python 手写一个 RBF kernel ridge 的核心:

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np

def rbf_kernel(X1, X2, gamma=1.0):
diff = X1[:, None, :] - X2[None, :, :]
dist2 = np.sum(diff ** 2, axis=2)
return np.exp(-gamma * dist2)

K = rbf_kernel(X_train, X_train, gamma=0.5)
lam = 0.01
c = np.linalg.solve(K + lam * len(X_train) * np.eye(len(X_train)), y_train)

K_test = rbf_kernel(X_test, X_train, gamma=0.5)
pred = K_test @ c

实际项目里可以直接用 scikit-learn:

1
2
3
4
5
from sklearn.kernel_ridge import KernelRidge

krr = KernelRidge(alpha=0.01, kernel="rbf", gamma=0.5)
krr.fit(X_train, y_train)
pred = krr.predict(X_test)

5. 分类问题:从概率到边界

回归预测连续值,分类预测类别。二分类通常把标签写成:

y{1,1}y\in\{-1,1\}

分类器是一个函数:

f:XYf:X\to Y

它的目标是在新样本上给出正确 label。

AMA4680 的分类部分包括 decision tree、Naive Bayes、SVM、logistic regression 和 ANN。它们看似不同,但其实都在回答同一个问题:如何把特征空间切成不同类别区域?

6. Naive Bayes:用条件概率做分类

Naive Bayes 基于贝叶斯公式:

P(Cx)=P(C)P(xC)P(x)P(C|x)=\frac{P(C)P(x|C)}{P(x)}

分类时只需要比较不同类别的相对大小:

C^=argmaxCP(C)P(xC)\hat C=\arg\max_C P(C)P(x|C)

朴素假设是:给定类别后,各个特征条件独立:

P(xC)=j=1pP(xjC)P(x|C)=\prod_{j=1}^pP(x_j|C)

所以分类规则变成:

C^=argmaxCP(C)j=1pP(xjC)\hat C=\arg\max_C P(C)\prod_{j=1}^pP(x_j|C)

这个假设很强,现实中经常不严格成立,但 Naive Bayes 仍然常常表现不错,尤其适合文本分类、词袋模型、离散特征分类。

6.1 Laplacian Smoothing

如果某个类别下从来没见过某个特征值,概率会变成 0,导致整个乘积为 0。Laplacian smoothing 用一个小的伪计数避免这个问题:

P(xj=aC)=NC,a+αNC+αKP(x_j=a|C)=\frac{N_{C,a}+\alpha}{N_C+\alpha K}

其中 KK 是该特征可能取值数量。

Python 例子:

1
2
3
4
5
6
7
8
9
10
from sklearn.naive_bayes import CategoricalNB
from sklearn.preprocessing import OrdinalEncoder

enc = OrdinalEncoder()
X_encoded = enc.fit_transform(X_cat)

clf = CategoricalNB(alpha=1.0)
clf.fit(X_encoded, y)

pred = clf.predict(enc.transform(new_samples))

7. SVM:最大间隔分类器

SVM 的核心不是“找一条能分开的线”,而是找一条 margin 最大的分界线。

对于线性二分类器:

f(x)=wTx+bf(x)=w^Tx+b

决策边界是:

wTx+b=0w^Tx+b=0

Hard-margin SVM 的优化问题:

minw,bw2\min_{w,b}\|w\|^2

subject to:

yi(wTxi+b)1,i=1,,ny_i(w^Tx_i+b)\ge 1,\quad i=1,\ldots,n

约束表示每个样本不仅要分对,还要离边界至少有一定距离。离边界最近、真正决定边界的点叫 support vectors。

现实数据往往不可完全线性分开,因此需要 soft margin,引入 slack variables:

minw,b,ξ12w2+Ciξi\min_{w,b,\xi}\frac{1}{2}\|w\|^2+C\sum_i\xi_i

subject to:

yi(wTxi+b)1ξi,ξi0y_i(w^Tx_i+b)\ge 1-\xi_i,\quad \xi_i\ge 0

其中 CC 控制“间隔更大”和“训练错误更少”之间的权衡。

Python 例子:

1
2
3
4
5
6
7
8
9
10
11
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline

clf = make_pipeline(
StandardScaler(),
SVC(kernel="rbf", C=1.0, gamma="scale")
)

clf.fit(X_train, y_train)
print(clf.score(X_test, y_test))

SVM 使用 RBF kernel 时,可以形成非线性边界。调参重点通常是:

  • C: 惩罚错误分类的强度。
  • gamma: RBF kernel 的局部性。
  • kernel: linear, poly, rbf 等。

8. Logistic Regression:线性边界上的概率模型

Logistic regression 虽然名字里有 regression,但它用于分类。它建模的是:

P(y=1x)=σ(wTx+b)P(y=1|x)=\sigma(w^Tx+b)

其中 sigmoid 函数为:

σ(z)=11+ez\sigma(z)=\frac{1}{1+e^{-z}}

当概率大于阈值时预测为 1,否则预测为 0。

Logistic regression 的优点:

  • 输出概率,解释性强。
  • 训练稳定,适合 baseline。
  • 可以加 L1/L2 正则化。
  • 在文本分类、CTR 预估、风控建模中非常常见。

Python:

1
2
3
4
5
from sklearn.linear_model import LogisticRegression

clf = LogisticRegression(max_iter=1000, penalty="l2")
clf.fit(X_train, y_train)
pred_proba = clf.predict_proba(X_test)[:, 1]

在项目里,logistic regression 经常是第一个应该尝试的分类 baseline。

9. ANN:从线性分类器到函数复合

人工神经网络可以理解成很多层函数复合:

xg1h1g2h2g3gky^x \xrightarrow{g_1} h_1 \xrightarrow{g_2} h_2 \xrightarrow{g_3} \cdots \xrightarrow{g_k} \hat y

每一层通常是:

g(x)=f(Wx+b)g(x)=f(Wx+b)

其中 WW 是权重矩阵,bb 是偏置,ff 是 activation function。

常见激活函数:

激活函数 形式 特点
Sigmoid 1/(1+ex)1/(1+e^{-x}) 输出在 0 到 1,早期常用
Tanh tanh(x)\tanh(x) 输出在 -1 到 1
ReLU max(0,x)\max(0,x) 现代网络常用,训练更稳

神经网络强大的原因不是某一层特别复杂,而是多层非线性复合可以表示非常复杂的函数。

一个最小 PyTorch 分类器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import torch
from torch import nn

class MLP(nn.Module):
def __init__(self, input_dim, hidden_dim, num_classes):
super().__init__()
self.net = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, num_classes)
)

def forward(self, x):
return self.net(x)

model = MLP(input_dim=20, hidden_dim=64, num_classes=2)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)

AMA4680 里的 ANN 是入门层面,但它刚好可以和后续 PyTorch 学习连接起来:线性模型、logistic regression 和 MLP 本质上是一条连续的路线。

10. Clustering:没有标签时怎么学习

无监督学习没有 yy,只有数据点 x1,,xnx_1,\ldots,x_n。Clustering 的目标是把相似点放在一起,不相似点分开。

10.1 K-means

K-means 的目标函数:

minC1,,CKk=1KxiCkxiμk2\min_{C_1,\ldots,C_K}\sum_{k=1}^K\sum_{x_i\in C_k}\|x_i-\mu_k\|^2

其中 μk\mu_k 是第 kk 个 cluster 的中心。

算法步骤:

  1. 初始化 KK 个中心。
  2. 把每个点分配给最近中心。
  3. 用每个 cluster 的均值更新中心。
  4. 重复直到收敛。

Python:

1
2
3
4
5
6
7
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

X_scaled = StandardScaler().fit_transform(X)

kmeans = KMeans(n_clusters=3, random_state=42, n_init="auto")
labels = kmeans.fit_predict(X_scaled)

K-means 简单高效,但假设 cluster 接近球形,并且需要提前指定 KK

10.2 Hierarchical Clustering

Agglomerative clustering 从每个点单独成类开始,逐步合并最相似的 clusters。

常见 linkage:

  • single linkage: 两个 cluster 中最近点距离。
  • complete linkage: 两个 cluster 中最远点距离。
  • average linkage: 两个 cluster 间平均距离。
  • ward linkage: 合并后组内平方和增加最小。

它的优点是可以画 dendrogram,适合探索层次结构。

1
2
3
4
5
6
from scipy.cluster.hierarchy import linkage, dendrogram
import matplotlib.pyplot as plt

Z = linkage(X_scaled, method="ward")
dendrogram(Z)
plt.show()

10.3 Gaussian Mixture Model and EM

GMM 假设数据来自多个 Gaussian distributions 的混合:

p(x)=k=1KπkN(xμk,Σk)p(x)=\sum_{k=1}^K\pi_k\mathcal N(x|\mu_k,\Sigma_k)

和 K-means 不同,GMM 给的是 soft assignment:一个点属于每个 cluster 的概率。

EM algorithm 分两步:

  1. E-step: 根据当前参数估计每个点属于每个 cluster 的概率。
  2. M-step: 根据这些概率重新估计 πk,μk,Σk\pi_k,\mu_k,\Sigma_k

Python:

1
2
3
4
5
from sklearn.mixture import GaussianMixture

gmm = GaussianMixture(n_components=3, covariance_type="full", random_state=42)
labels = gmm.fit_predict(X_scaled)
proba = gmm.predict_proba(X_scaled)

GMM 比 K-means 更灵活,但也更容易受初始化和分布假设影响。

11. MDP:从预测到决策

前面的 supervised learning 主要是在预测:给定 xx,预测 yy。MDP 进入的是决策问题:给定当前状态,我应该采取什么 action,才能让长期 reward 最大?

一个 Markov Decision Process 包括:

  • 状态空间 SS
  • 动作空间 AA
  • 转移概率 P(ss,a)P(s'|s,a)
  • 奖励函数 r(s,a)r(s,a)
  • 折扣因子 γ\gamma

Markov property 表示:未来只依赖当前状态和动作,不依赖更早历史。

11.1 Policy and Value Function

Policy 是从状态到动作的规则:

π:SA\pi:S\to A

Value function 表示从状态 ss 出发,遵循 policy π\pi 能获得的期望回报:

Vπ(s)=E[t=0γtr(st,at)s0=s]V^\pi(s)=\mathbb E\left[\sum_{t=0}^{\infty}\gamma^t r(s_t,a_t)\mid s_0=s\right]

Bellman equation:

Vπ(s)=r(s,π(s))+γsP(ss,π(s))Vπ(s)V^\pi(s)=r(s,\pi(s))+\gamma\sum_{s'}P(s'|s,\pi(s))V^\pi(s')

这条公式是强化学习的核心。它把“当前状态价值”写成“当前奖励 + 下一状态价值”的递归。

11.2 Value Iteration

最优价值函数满足 Bellman optimality equation:

V(s)=maxa[r(s,a)+γsP(ss,a)V(s)]V^*(s)=\max_a\left[r(s,a)+\gamma\sum_{s'}P(s'|s,a)V^*(s')\right]

Value iteration 就是反复做 Bellman update:

1
2
3
4
Initialize V(s)=0
repeat:
V_new(s)=max_a [r(s,a)+gamma * sum_s' P(s'|s,a)V(s')]
until convergence

一个简单 Python 结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np

def value_iteration(P, R, gamma=0.95, tol=1e-6):
n_states, n_actions, _ = P.shape
V = np.zeros(n_states)

while True:
Q = np.zeros((n_states, n_actions))
for s in range(n_states):
for a in range(n_actions):
Q[s, a] = R[s, a] + gamma * np.sum(P[s, a] * V)

V_new = Q.max(axis=1)
if np.max(np.abs(V_new - V)) < tol:
break
V = V_new

policy = Q.argmax(axis=1)
return V, policy

这部分和后续 Reinforcement Learning、Agent planning、control problem 都有关。

12. 怎么把 AMA4680 学成项目能力

如果只是学考试,可能会记公式、做计算题;但如果想把它变成项目能力,可以按下面方式迁移:

12.1 每类算法都做一个 baseline

任务 建议模型
表格回归 Linear Regression, Ridge, Lasso, KRR
表格分类 Logistic Regression, SVM, Naive Bayes
非线性分类 SVM with RBF kernel, MLP
用户分群 K-means, hierarchical clustering, GMM
决策问题 small MDP + value iteration

重点不是模型越复杂越好,而是每次都能说明:

  • 数据是什么?
  • loss/objective 是什么?
  • baseline 是什么?
  • 指标是什么?
  • 模型为什么改进?
  • 错误样本长什么样?

12.2 一个通用 sklearn 项目骨架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.metrics import classification_report
from sklearn.svm import SVC

X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)

pipe = Pipeline([
("scaler", StandardScaler()),
("clf", SVC())
])

param_grid = {
"clf__kernel": ["linear", "rbf"],
"clf__C": [0.1, 1, 10],
"clf__gamma": ["scale", 0.1, 1.0]
}

search = GridSearchCV(pipe, param_grid, cv=5, scoring="f1_macro")
search.fit(X_train, y_train)

pred = search.predict(X_test)
print(search.best_params_)
print(classification_report(y_test, pred))

这段代码把 AMA4680 的很多思想串起来了:标准化、模型选择、交叉验证、分类指标和泛化评估。

13. 学完这门课应该留下的直觉

AMA4680 最值得留下的是五个直觉:

  1. 机器学习不是套模型,而是定义目标函数并控制泛化误差。
  2. 正则化是对抗过拟合和不稳定估计的基本工具。
  3. Kernel method 让线性算法拥有非线性表达能力。
  4. 分类器本质上是在特征空间里学习 decision boundary。
  5. MDP 把机器学习从预测推进到 sequential decision making。

如果以后继续学 NLP、推荐系统、深度学习或 LLM 应用,这些内容仍然有用。比如 SVM 的 margin 思想对应分类边界,kernel 对应相似度函数,Naive Bayes 对应概率建模,GMM/EM 对应隐变量学习,MDP 对应 Agent 的状态、动作和长期目标。

经典机器学习不是“过时的东西”,它更像是一套压缩过的基本功。掌握它之后,再看深度学习和大模型,会更容易看懂那些复杂系统背后的简单结构。

AMA4680 统计机器学习教程:从正则化、核方法、分类器到聚类与 MDP

https://richardf123.github.io/2026/06/25/ama4680-statistical-machine-learning-guide/

作者

RichardF

发布于

2026-06-25

更新于

2026-06-25

许可协议