AI/ML 详解:经典 ML 算法

Day 16 · 2026-06-02 · 难度 ★★☆
面向:有编程经验的非 AI 方向工程师

前 15 天我们一直在讲 LLM。但 LLM 是金字塔尖,底座是 1950–2000 年沉淀下来的经典 ML。今天回到地基:四个至今仍在生产系统里大规模运行的算法。它们的共同点——可解释、便宜、在表格数据上常常打败深度学习。理解它们,你才真正懂「机器学习」这四个字到底学了什么。

线性回归Linear Regression

监督学习回归
一句话类比

线性回归就是一个权重可学习的打分公式。你做容量规划时手写过 cost = 0.3·CPU + 0.5·内存 + 0.2·IO 这种加权和——那些系数是你拍脑袋定的。线性回归做的事一模一样,只是让数据自己算出最优系数,目标是让预测误差最小。

它解决什么问题 + 工作机制

痛点:你有一堆「输入特征 → 数值结果」的历史样本(房子面积→价格、请求数→延迟),想找一条规律去预测新样本。线性回归假设结果是输入的加权和

ŷ = w₁x₁ + w₂x₂ + … + wₙxₙ + b

其中 xᵢ 是特征(面积、房间数),wᵢ 是权重(这个特征多重要),b 是偏置(基准值)。怎么找最优的 w?定义一个「错得多严重」的度量——均方误差(MSE):把每个样本的预测值减真实值、平方、求平均。

Loss = (1/N) · Σ (yᵢ − ŷᵢ)²

为什么平方而不是绝对值?三个原因:① 平方处处可导,能用梯度下降优化;② 大误差被放大(错 10 的惩罚是错 1 的 100 倍),逼模型别犯大错;③ 数学上有闭式解——直接一个矩阵公式 w = (XᵀX)⁻¹Xᵀy 算出答案,不用迭代。这就是「最小二乘法」,1805 年勒让德就在用了,比神经网络早 150 年。

代码示例
from sklearn.linear_model import LinearRegression
import numpy as np

# 特征:[面积, 房间数]   标签:价格(万)
X = np.array([[50, 1], [80, 2], [120, 3], [200, 4]])
y = np.array([300, 480, 700, 1100])

model = LinearRegression()
model.fit(X, y)              # 一行求解最优权重(闭式解)

print(model.coef_)          # 每个特征的权重 w
print(model.intercept_)     # 偏置 b
print(model.predict([[100, 2]]))  # 预测 100㎡/2 室的价格
常见误区 + 实践场景
「线性回归只能拟合直线,太弱了」——错。它对参数是线性的,但你可以喂它非线性特征:加一列 x²、log(x)、x₁·x₂,它就能拟合曲线和交互效应。真正的限制不是「直线」,而是需要你手动设计特征——这正是深度学习要替代的部分。
📌 超级个体场景:用它给自己的时间投入建模——「每周写作 N 小时 → 订阅增长」。系数告诉你哪个动作 ROI 最高,比凭感觉做决策可靠。线性回归是最便宜的因果直觉工具
Takeaway + 思考题
💡 线性回归是所有 ML 的「Hello World」:一个加权和 + 一个误差度量 + 一个优化方法。神经网络只是把这三件事堆叠了上百万次。
🤔 你最近一个「拍脑袋定权重」的决策公式,如果有 50 条历史数据,能不能让回归替你算系数?

逻辑回归Logistic Regression

监督学习分类概率
一句话类比

逻辑回归 = 线性回归 + 一个把任意数值压成「概率」的阀门。它像一个带校准概率的准入控制器(admission controller):不只输出「放行/拒绝」,而是给出「这个请求有 87% 概率是正常流量」。名字里有「回归」,干的却是分类的活。

它解决什么问题 + 工作机制

痛点:很多任务要的是是/否而非数值——这封邮件是垃圾吗?这个用户会流失吗?线性回归输出 (−∞, +∞),没法当概率。逻辑回归在加权和外面套一个 Sigmoid 函数把它挤进 (0, 1):

p = σ(wᵀx + b),  σ(z) = 1 / (1 + e−z)

直觉:z 很大 → p 趋近 1(几乎确定是正类);z 很小(很负)→ p 趋近 0;z=0 → p=0.5(最不确定)。这条 S 形曲线把「线性打分」平滑映射成「概率」。背后的数学身份是对数几率(log-odds)wᵀx+b = log(p/(1−p))——模型其实在线性地预测「赢面的对数」。

训练不用 MSE,而用交叉熵 / 对数损失:真实是正类时惩罚 −log(p),真实是负类时惩罚 −log(1−p)。为什么换损失?因为 Sigmoid 套 MSE 会让损失函数变「非凸」(坑坑洼洼,梯度下降卡在局部最优);交叉熵恰好让它重新变成凸函数,且等价于最大似然估计——数学上最自然的选择。

代码示例
from sklearn.linear_model import LogisticRegression

# 特征:[邮件长度, 含'免费'次数]   标签:1=垃圾 0=正常
X = [[20, 0], [15, 3], [200, 0], [30, 5]]
y = [0, 1, 0, 1]

clf = LogisticRegression()
clf.fit(X, y)

# predict_proba 给的是概率,不是硬标签——这才是逻辑回归的价值
print(clf.predict_proba([[18, 4]]))  # [[P(正常), P(垃圾)]]
print(clf.predict([[18, 4]]))        # 默认 0.5 阈值后的硬标签
常见误区 + 实践场景
「输出 0.9 就是 90% 准确」——混淆了概率准确率。0.9 是模型对这一条的置信度;模型是否「校准良好」(说 0.9 的样本里真有 90% 是正类)要单独验证。还有:默认 0.5 阈值不是金科玉律——做欺诈检测时你可能愿意把阈值降到 0.2,宁可误报也别漏过。
📌 超级个体场景:给收件箱/任务流做一个轻量「重要性打分器」。逻辑回归的权重可直接读——你能看到「发件人是老板」贡献了多少分,比黑箱模型更适合需要解释的个人决策系统。
Takeaway + 思考题
💡 逻辑回归是工业界用得最多的分类器,不是因为最强,而是因为快、可解释、输出校准概率。神经网络的最后一层(Softmax)本质就是多分类版逻辑回归。
🤔 你的哪个「二元判断」(值不值得做、靠不靠谱)其实可以拆成几个可量化特征,交给一个打分器?

决策树 & 随机森林Decision Tree & Random Forest

监督学习集成树模型
一句话类比

决策树就是一棵自动生成的嵌套 if-else 路由表——和你写过的规则引擎一模一样,只是规则由数据自己学出来。随机森林则是用 quorum 投票替代单点决策:种几百棵互不相同的树,让它们投票,靠多数表决消除单棵树的随机偏差——和分布式系统用副本冗余对抗单点故障是同一个思想。

它解决什么问题 + 工作机制

痛点:线性模型要你手动设计特征、还假设关系是线性的。决策树不假设任何形状,它贪心地反复切分数据:每一步问「按哪个特征、哪个阈值切,能让两边最‘纯’?」纯度用 基尼不纯度(Gini)衡量:

Gini = 1 − Σ pₖ²

pₖ 是某节点里第 k 类的占比。全是同一类 → Gini=0(最纯);五五开 → Gini=0.5(最乱)。树就是不断选「切完后加权 Gini 下降最多」的切法,直到叶子足够纯。这给你一个完全可读的模型——能画出来给非技术的人看。

但单棵树有致命伤:方差极高,换几个样本就长成完全不同的树,容易过拟合。随机森林(Breiman 2001)用两层随机性解耦这些树:

  • Bagging(自助采样):每棵树只在有放回随机抽样的子集上训练——像对数据分片采样;
  • 随机特征子集:每次切分只考虑随机一部分特征,强迫不同树看不同角度。
随机森林 = 多棵去相关的树投票

样本+特征随机 树1: 垃圾 树2: 正常 树3: 垃圾 …树500
          └──────── 多数投票(quorum)────────┘
最终输出 垃圾(312 票 vs 188)

关键数学直觉:平均 N 个近似独立、各自有噪声的预测,方差约降到 1/N(和你重复测量取均值降噪是同一个统计原理)。bagging 让树彼此独立,投票就把单棵树的过拟合「平均掉」了——这就是集成学习以弱胜强的核心。

代码示例
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)

# n_estimators=树的数量;越多越稳,但收益递减
rf = RandomForestClassifier(n_estimators=300, max_depth=5)
rf.fit(X, y)

# 几乎免费的特征重要性——森林天然能排序哪个特征最有用
for name, imp in zip(["花萼长","花萼宽","花瓣长","花瓣宽"], rf.feature_importances_):
    print(f"{name}: {imp:.2f}")
常见误区 + 实践场景
「树越深越好」——错。单棵深树会把训练集背到死(过拟合),泛化反而差。随机森林靠「多棵浅树投票」而非「一棵深树」取胜;想要单个生产模型时,更常用的是梯度提升(XGBoost / LightGBM)——同样是树集成,但用 boosting(逐棵纠错)而非 bagging(并行投票),在表格数据竞赛里至今稳压深度学习
📌 超级个体场景:手上有一份结构化数据(用户行为表、个人记账、实验记录),不要第一反应上神经网络。随机森林 / XGBoost 几行代码、不用调参就能给你一个强 baseline + 特征重要性排序,告诉你「哪些变量真正驱动结果」。
Takeaway + 思考题
💡 单棵树可解释但不稳;随机森林牺牲一点可解释性,用「群体的智慧」换来鲁棒——这是分布式冗余思想在 ML 里的完美映射。
🤔 你熟悉的「副本投票 / quorum 共识」和随机森林的「多树投票」,在「如何制造成员间的独立性」上各自怎么做?独立性为什么是两者的命门?

支持向量机Support Vector Machine (SVM)

监督学习分类核方法
一句话类比

SVM 找的是两类数据之间最宽的「隔离带 / DMZ」。别的分类器随便画一条能分开两边的线就满足了;SVM 偏要画那条离两边都最远的线——隔离带越宽,对新数据越鲁棒。而决定这条线的,只有贴着边界的少数几个关键样本(支持向量),就像一个优化问题里真正「绷紧」的那几条约束。

它解决什么问题 + 工作机制

痛点:能分开两类的直线有无数条,哪条泛化最好?SVM 给出明确答案——最大化间隔(margin),即决策边界到最近样本的距离。几何上,间隔等于 2/‖w‖,所以「最大化间隔」等价于「最小化 ‖w‖」,在「所有点都被正确分到隔离带外」的约束下求解:

min ½‖w‖² s.t. yᵢ(wᵀxᵢ + b) ≥ 1

直觉:‖w‖ 越小,隔离带越宽;约束保证每个样本都站在自己一侧、且离边界至少「一个单位」。最优解只由那几个压在边界上的支持向量决定——删掉其它样本,边界纹丝不动。这让 SVM 在高维小样本下特别稳。

但数据常常线性不可分(一条直线分不开)。SVM 的杀手锏是核技巧(kernel trick):把数据隐式映射到更高维空间,让原本绕成一团的两类变得能用平面切开——类比你给 SQL 查询加一个计算列(比如 x²+y²),原本分不开的环形数据立刻可分。妙处在于核函数不用真的算高维坐标,只算样本间的相似度,省掉天文数字的计算:

RBF 核:K(x, x′) = exp(−γ‖x − x′‖²)

γ 控制「影响半径」:大 γ → 每个点只管附近,边界弯曲(易过拟合);小 γ → 影响范围大,边界平滑。这是 SVM 最关键的旋钮。

代码示例
from sklearn.svm import SVC
from sklearn.datasets import make_circles

# 环形数据:内圈一类、外圈一类,直线绝对分不开
X, y = make_circles(n_samples=200, noise=0.1, factor=0.4)

# 用 RBF 核:隐式升维,把环形变得可分
clf = SVC(kernel="rbf", C=1.0, gamma="scale")
clf.fit(X, y)

print("支持向量数量:", len(clf.support_))  # 只有少数样本决定边界
print("准确率:", clf.score(X, y))
常见误区 + 实践场景
「SVM 过时了,被深度学习淘汰」——一半对。在大数据、图像、文本上确实让位给神经网络;但在样本少(几百到几千)、维度高的场景(生物信息、小型分类任务),SVM 依然又准又稳,且不需要 GPU。选错工具不是算法的错——没有银弹,只有合不合适
📌 超级个体场景:你手头只有 300 条标注样本(比如人工标的「优质 / 普通」文章),用神经网络必然过拟合。换上 RBF 核 SVM,往往是小样本分类的最佳起点
Takeaway + 思考题
💡 SVM 教给我们两个永恒的思想:「最大间隔」= 留余量才鲁棒;「核技巧」= 换个空间看,难题变简单。这两条远比 SVM 本身活得更久。
🤔 「升维让不可分变可分」——这个在你别的领域(数据建模、问题拆解、跨学科思考)里有没有对应的直觉:换一个表示空间,纠缠的问题忽然解开?

深入资源Further Reading

深入思考Deep Questions

1. 今天四个算法都是「监督学习」。它们和前 15 天的 LLM 在「学什么」上,本质区别和共同点是什么?
共同点:都是从数据里拟合一个函数 f(输入)→输出,本质都是「最小化某个损失」——LLM 的下一词预测也是分类(在几万词表上做 Softmax,就是超大号逻辑回归)。区别在三层:(1) 特征——经典 ML 要你手工设计特征(面积、词频),深度学习自动从原始数据学表示,这是「表示学习」的革命;(2) 容量与数据——线性/SVM 参数少、几百条样本就能跑,LLM 上千亿参数、要海量数据,否则过拟合;(3) 可解释性——逻辑回归的权重你能逐条读懂,LLM 是黑箱。深层 insight:神经网络可以看成「把特征工程自动化的逻辑回归塔」——每一层都在做线性变换+非线性激活,最后一层就是逻辑回归。理解经典 ML,你才看得懂深度学习「省掉了人类做特征工程」这件事到底多关键。
2. 为什么在「表格 / 结构化数据」上,XGBoost 这类树集成至今常常打败深度学习?这对「该不该无脑上大模型」有什么启示?
表格数据的特点:特征异质(数值/类别混杂)、维度不高、样本有限、特征间无空间/时序结构。树模型天生擅长:(1) 对特征尺度不敏感,不用归一化;(2) 自动处理非线性和特征交互(每次切分就是一次交互);(3) 对无关特征鲁棒,自动忽略。而神经网络的强项——从原始信号学层次化表示——在「已经是人工特征」的表格上发挥不出来,反而因样本少容易过拟合,还要大量调参。启示:模型选择要匹配数据结构,不是越大越好。图像/文本/音频这种「高维、有结构、海量」的非结构化数据是深度学习主场;但企业里大量的表格预测问题,一个 XGBoost 几行代码就吊打精心调的神经网络,还便宜百倍、可解释。「无脑上大模型」常常是用航母运快递
3. 随机森林靠「多树投票」降方差,SVM 靠「最大间隔」求鲁棒。这两条降低过拟合的思路,背后是不是同一个东西?
表面不同,深层都在对抗过拟合 = 模型记住了噪声而非规律,但下注在不同机制上。随机森林走「平均消噪」路线:单棵树高方差(对训练集敏感),但只要让多棵树误差方向不相关,平均后方差按 ~1/N 衰减——这是集成 / 统计平均的思想,和「多次测量取均值」「分布式多副本」同源。SVM 走「留余量」路线:不追求把训练点分得多开心,而是让决策边界离数据尽量远,留出缓冲——这是正则化 / 奥卡姆剃刀的思想,对应「别把规则贴着样本画,留 buffer 才扛得住扰动」。统一视角:两者都在主动牺牲训练集上的拟合度,换取对未见数据的稳定——这正是泛化的核心张力(bias-variance trade-off)。理解这一点,你看任何 ML 方法都能问一句:「它是怎么花钱买鲁棒的?」
4. 这些算法 50-200 年前就发明了(最小二乘 1805、SVM 1995),为什么直到今天还在生产系统里大规模运行?
因为它们击中了大多数现实问题的真实复杂度。一个反直觉的事实:工业界 80% 的 ML 价值不来自最前沿模型,而来自把经典算法用对地方。原因:(1) 可解释性是刚需——金融风控、医疗、招聘等高风险场景法律上要求能解释决策,逻辑回归的权重天然合规,黑箱大模型反而不能用;(2) 成本与延迟——逻辑回归推理是一次点积,微秒级、零 GPU;LLM 一次推理贵几个数量级;(3) 数据现实——多数公司没有训练大模型的数据量,但有几千条表格数据,正好是经典 ML 的甜区;(4) 鲁棒可维护——简单模型故障模式清晰、易调试、易监控。深层启示对「AI 超级个体」尤其重要:真正的工程判断力不是永远追最新,而是知道每个问题配多重的工具。能用线性回归解决的,别上 Transformer——这种「克制」本身就是稀缺能力。