人工智能基础与机器学习理论

这一篇是「人工智能训练师基础」系列的第二篇,承接上一篇《数据结构与算法基础》,专门把”人工智能基础与机器学习理论”这一章拎出来细讲。为什么单独成篇?因为机器学习是人工智能的核心内容,再加上”人工智能基础”在原大纲里是重点章节,需要系统梳理。这一章学透了,人工智能的根基就稳了。讲解风格和前一篇保持一致:博客串讲,生活化类比,不用表格不用图,目标是让你”听明白、能理解”。

下面正式开始,从 AI 的历史三幕剧讲起。


AI发展三幕剧

AI 这个词听着很玄,本质就是一句话——让机器表现出类似人的智能行为。但”怎么让机器智能”这件事,历史上走过三条完全不同的路,这就是常说的”三大学派”。

第一幕是符号主义,大概是上世纪 50 年代到 80 年代的主流。它的核心思想是:智能就是逻辑推理,人思考靠符号操作,那机器也一样,把知识写成”如果…那么…”的规则,机器就能推理。代表作是专家系统,比如给人看病的 MYCIN。这条路的问题是,现实世界太复杂,规则写不完,而且机器只能用人事先写好的规则,学不会新东西。所以后来遇到了瓶颈,史称”第一次 AI 寒冬”。

第二幕是连接主义,模拟人脑神经元的方式来做智能。1943 年就有人提出 MP 模型,1958 年 Rosenblatt 提出感知机,这俩是鼻祖。但当时感知机只能解决线性可分问题,连异或(XOR)都搞不定,被 Minsky 一顿批判,又进入了寒冬。直到 1986 年 Hinton 等人把反向传播算法(BP)真正推广开来,多层神经网络才重新火起来。【需网络查询确认:BP 算法最早由谁、哪一年提出,Hinton 1986 论文确切出处】

第三幕就是现在大家都熟悉的深度学习时代,大概从 2006 年 Hinton 提出”深度信念网络”开始预热,2012 年 AlexNet 在 ImageNet 上一战成名,把错误率刷下去一大截,从此 CNN、RNN、Transformer 一路狂奔。这背后的功臣其实是三样:大数据、GPU 算力、算法改进(比如 ReLU 激活函数解决梯度消失、Dropout 缓解过拟合)。

一句话总结这三幕:符号主义靠”人写规则”,连接主义靠”机器学权重”,深度学习是连接主义在算力和数据加持下的升级版。

应用领域速览

常见的就三大块。

计算机视觉(CV),处理图像视频。经典任务有图像分类(这张图是猫还是狗)、目标检测(图里有哪些物体、位置在哪,用边界框标出来)、图像分割(每个像素属于哪个类)。背后主力模型从 CNN(LeNet、VGG、ResNet)一路发展到现在的 Vision Transformer。

自然语言处理(NLP),处理文本语音。任务包括文本分类、命名实体识别、机器翻译、问答系统、文本生成。传统方法有 TF-IDF、word2vec,后来 LSTM/GRU 一阵风,现在 Transformer 一统天下,BERT、GPT 都是它的变体。注意 Transformer 的核心是自注意力机制(Self-Attention),它解决了 RNN 不能并行、长距离依赖弱的问题。

推荐系统,给用户推东西。常见思路有协同过滤(”跟你相似的人喜欢啥,你就喜欢啥”)、基于内容(”你喜欢的东西的同类”)、混合推荐。评估常用 CTR(点击率)、AUC、NDCG。

感知机与反向传播:神经网络的起点

感知机是神经网络的”细胞”。它干的事很简单:输入一堆特征 x1、x2…xn,每个乘一个权重 w,加起来再过一个激活函数(最早是阶跃函数),输出 0 或 1。数学上就是 sign(w·x + b)。它的几何意义是:在特征空间里画一条线(高维是超平面),把两类点分开。但前提是数据得”线性可分”,也就是真的能一刀切开,否则感知机不收敛。

光记公式不形象,咱来一个具体的计算示例走一遍。假设我们要判断一个水果是不是苹果,给两个特征:x1 是”红度”(01),x2 是”圆度”(01)。来一个样本,红度 0.8、圆度 0.9。权重 w1=0.6、w2=0.4,偏置 b=-0.5。感知机的计算就两步:

第一步,加权求和:z = w1·x1 + w2·x2 + b = 0.6·0.8 + 0.4·0.9 + (-0.5) = 0.48 + 0.36 - 0.5 = 0.34

第二步,过激活函数。如果用阶跃函数 sign,z>0 就输出 1(判正类,是苹果),z<=0 输出 0(判负类,不是苹果)。这里 z=0.34>0,所以输出 1,判断为苹果。

整个过程用 Python 写出来就这点东西:

1
2
3
4
5
6
7
def perceptron(x1, x2, w1, w2, b):
z = w1 * x1 + w2 * x2 + b
return 1 if z > 0 else 0

# 预测一个红度0.8、圆度0.9的水果
result = perceptron(0.8, 0.9, 0.6, 0.4, -0.5)
print(result) # 输出 1,判定为苹果

你看,感知机其实就是在画那条”分界线”,权重控制方向,偏置控制位置。如果分错了,就根据错误方向调整 w 和 b,慢慢挪到能分开为止,这就是感知机的训练规则。

把感知机堆起来就是多层感知机(MLP)。输入层接特征,输出层给结果,中间夹着隐层。每个神经元做的事情还是”加权求和+激活”,关键是激活函数得是非线性的(ReLU、Sigmoid、Tanh),不然多层堆叠等价于一层,白搭。

那权重怎么学?这就是反向传播(BP)的活。前向传播算出预测值,跟真实标签比一下得到损失(比如交叉熵、MSE),然后把损失从输出层往回传,用链式法则算出每个权重的梯度,再用梯度下降更新权重。整个过程就是”前向算损失、反向传梯度、更新参数”三步循环。

光说链式法则太抽象,咱拿一个最简单的两层网络走一遍。假设网络长这样:输入层 1 个神经元 x,隐层 1 个神经元(权重 w1、偏置 b1,激活用 ReLU),输出层 1 个神经元(权重 w2、偏置 b2,激活用线性,方便算)。给一个样本 x=1.0,真实标签 y=1.0。初始参数 w1=0.5、b1=0.0、w2=0.8、b2=0.0,损失用 MSE。

前向传播:

隐层输入:z1 = w1·x + b1 = 0.5·1.0 + 0.0 = 0.5

隐层输出(过 ReLU,正数不变):a1 = ReLU(0.5) = 0.5

输出层输入:z2 = w2·a1 + b2 = 0.8·0.5 + 0.0 = 0.4

输出层输出(线性激活):a2 = z2 = 0.4

损失:L = ½·(a2 - y)² = ½·(0.4 - 1.0)² = ½·0.36 = 0.18

反向传播:

先算输出层梯度。L 对 a2 的偏导是 (a2 - y) = 0.4 - 1.0 = -0.6

L 对 w2 的梯度:∂L/∂w2 = (∂L/∂a2)·(∂a2/∂w2) = -0.6 · a1 = -0.6 · 0.5 = -0.3

L 对 b2 的梯度:∂L/∂b2 = -0.6 · 1 = -0.6

再算隐层梯度。L 对 a1 的偏导要”借道” w2:∂L/∂a1 = (∂L/∂a2)·(∂a2/∂a1) = -0.6 · w2 = -0.6 · 0.8 = -0.48

ReLU 在正区间导数是 1,所以 L 对 z1 的偏导就是 -0.48

L 对 w1 的梯度:∂L/∂w1 = -0.48 · x = -0.48 · 1.0 = -0.48

L 对 b1 的梯度:∂L/∂b1 = -0.48 · 1 = -0.48

参数更新(学习率 η=0.1):

w2 = w2 - η·(∂L/∂w2) = 0.8 - 0.1·(-0.3) = 0.83

b2 = b2 - η·(∂L/∂b2) = 0.0 - 0.1·(-0.6) = 0.06

w1 = w1 - η·(∂L/∂w1) = 0.5 - 0.1·(-0.48) = 0.548

b1 = b1 - η·(∂L/∂b1) = 0.0 - 0.1·(-0.48) = 0.048

更新完再前向算一次,新的预测值 a2 应该比 0.4 更接近真实标签 1.0,这就是反向传播”往损失变小的方向走”的过程。真实网络层数多、参数多,但底层逻辑和这个例子一模一样——前向算预测、算损失、反向一层层传梯度、按梯度反方向更新参数。

这里有个常见的坑:梯度消失和梯度爆炸。Sigmoid 的导数最大才 0.25,多层一乘就趋近 0,梯度传不到浅层,这叫梯度消失;反过来权重太大,梯度越乘越大,叫梯度爆炸。解法:换 ReLU 激活函数(导数在正区间是 1)、BatchNorm 归一化、残差连接(ResNet 的核心)、梯度裁剪。

几个绕不开的基本概念

AI 是大目标,机器学习是实现这个目标的主流方法。它的定义可以这么记:让机器从数据中自动学习规律,并对新数据做出预测或决策,而不是靠人硬编码规则。注意三个关键词——数据、自动学习、预测。

样本、特征、标签这三个是一伙的。一条样本就是一条数据记录,比如一个人;特征是描述这条样本的属性,比如年龄、收入、浏览历史;标签是我们要预测的目标,比如”是否会买”。有标签的训练叫监督学习,没标签的就是无监督学习。

数据集要切成三份,这个切法几乎是重点。训练集用来让模型学,占大头(一般 60%~80%);验证集用来调超参数和选模型,比如试不同的学习率、树的深度,看哪个在验证集上表现好;测试集只在最后用一次,评估模型的最终性能,绝不能拿测试集去调参,否则就是”偷看答案”,成绩虚高。一个常见做法是 K 折交叉验证:把训练集切 K 份,轮流拿其中一份当验证集,其余 K-1 份训练,K 次结果平均,数据少的时候特别有用。

K 折交叉验证光说不好懂,咱拿 K=5 走一遍。假设你有 100 条训练数据,先把它们打乱均分成 5 份,每份 20 条,编号 Fold 1 到 Fold 5:

第一轮:Fold 1 当验证集,Fold 2~5(共 80 条)训练,算出验证集准确率记为 A1

第二轮:Fold 2 当验证集,其余 4 份训练,得到准确率 A2

第三轮:Fold 3 当验证集,得到 A3

第四轮:Fold 4 当验证集,得到 A4

第五轮:Fold 5 当验证集,得到 A5

最后把 5 个准确率平均,(A1+A2+A3+A4+A5)/5,就是这次交叉验证的最终评估值。这样做的好处是每条数据都”被验证过一次”,评估比单次切分更可靠,特别适合数据量小的场景。K 常用 5 或 10,数据极少时还可以用留一法(Leave-One-Out,K 等于样本数)。

泛化能力是机器学习的灵魂。一个模型在训练集上表现好不算本事,能在没见过的新数据上表现好才是真本事,这就是泛化。我们做的一切——正则化、Dropout、交叉验证、控制模型复杂度——归根结底都是为了提升泛化能力,而不是把训练集拟合得多么完美。

三种学习类型

这块用类比最好记。

监督学习,就像”有老师教”。老师(标签)告诉你每道题的标准答案,你做完对照答案调整。分两类任务:标签是离散的叫分类(猫狗识别、垃圾邮件判定),标签是连续的叫回归(预测房价、预测销量)。

无监督学习,就像”自己找规律”。没人给答案,你只能从一堆数据里发现结构。典型任务是聚类(把相似的样本凑一堆)和降维(把高维数据压到低维,方便可视化或去噪)。

强化学习,就像”试错得奖励”。没有标签,只有一个智能体(agent)在环境(environment)里行动,每做一个动作(action)环境给一个奖励(reward)反馈,智能体的目标是学出一个策略(policy),让长期累计奖励最大。关键词就是这五个:智能体、环境、状态、动作、奖励。典型例子是 AlphaGo 下围棋、机器人学走路、游戏 AI。常见的算法有 Q-Learning、SARSA、DQN(深度 Q 网络)、PPO。

注意一个易错点:强化学习的”奖励”和监督学习的”标签”不一样。标签是每条样本都有的标准答案,奖励是动作之后环境给的反馈,可能是延迟的(比如围棋要下到最后才知道输赢),而且不一定告诉你”应该怎么做”,只告诉你”做得怎么样”。

算法地图:分类、回归、聚类、关联

这块知识点最密,分四组讲。

分类算法

逻辑回归,名字叫”回归”其实是做二分类的。它在线性回归 w·x+b 的外面套一个 Sigmoid 函数,把输出压到 0~1 之间,解释成”正类的概率”。概率大于 0.5 就判正类。损失函数用对数损失(交叉熵)。多分类就用 Softmax 推广。优点是简单、可解释、给出概率;缺点是只能学线性边界,复杂关系搞不定。

Sigmoid 函数公式长这样:σ(z) = 1 / (1 + e^(-z)),其中 z = w·x + b。无论 z 多大或多小,输出都被压到 (0,1) 区间,刚好可以解释成概率。举个具体例子:假设我们做一个垃圾邮件分类器,特征 x 是”免费这个词出现的次数”,权重 w=0.8、偏置 b=-1.5。来了一封邮件,”免费”出现 3 次,那 z = 0.8·3 + (-1.5) = 2.4 - 1.5 = 0.9。套进 Sigmoid:σ(0.9) = 1/(1 + e^(-0.9)) ≈ 1/(1 + 0.4066) ≈ 0.711。意思是模型认为这封邮件是垃圾邮件的概率约 71.1%,大于 0.5,判为垃圾邮件。

用 Python 验证一下:

1
2
3
4
5
6
7
8
9
10
import math

def sigmoid(z):
return 1 / (1 + math.exp(-z))

# 特征:免费出现3次,权重0.8,偏置-1.5
z = 0.8 * 3 + (-1.5)
prob = sigmoid(z)
print(f"z = {z}, 垃圾邮件概率 = {prob:.4f}") # z = 0.9, 概率 ≈ 0.7109
print("判定:", "垃圾邮件" if prob > 0.5 else "正常邮件")

KNN(K 近邻),思想最朴素——“物以类聚”。来一个新样本,看它周围 K 个邻居,多数是哪类就判哪类。K 太小容易被噪声带偏(过拟合),K 太大决策边界太粗(欠拟合)。距离常用欧氏距离,也要注意特征要先标准化。KNN 是”懒惰学习”,训练阶段啥也不干,预测时才计算,所以预测慢但训练快。

KNN 也来一个具体例子。假设有 5 个训练样本,每个样本有两个特征(x1, x2),标签是 A 或 B:

样本 1:(1.0, 1.0, A)

样本 2:(1.2, 0.9, A)

样本 3:(0.8, 1.1, A)

样本 4:(4.0, 4.0, B)

样本 5:(4.2, 3.8, B)

来了一个新样本 (1.1, 1.0),问它属于哪类,K=3。先用欧氏距离算它到每个训练样本的距离:

到样本 1:√((1.1-1.0)² + (1.0-1.0)²) = √0.01 = 0.1

到样本 2:√((1.1-1.2)² + (1.0-0.9)²) = √(0.01+0.01) = √0.02 ≈ 0.141

到样本 3:√((1.1-0.8)² + (1.0-1.1)²) = √(0.09+0.01) = √0.1 ≈ 0.316

到样本 4:√((1.1-4.0)² + (1.0-4.0)²) = √(8.41+9.0) ≈ 4.18

到样本 5:√((1.1-4.2)² + (1.0-3.8)²) = √(9.61+7.84) ≈ 4.18

按距离从小到大排序:样本 1 (0.1) < 样本 2 (0.141) < 样本 3 (0.316) < 样本 4 ≈ 样本 5 (4.18)

取最近 K=3 个:样本 1、2、3,标签都是 A。投票结果 A 得 3 票、B 得 0 票,新样本判为 A 类。

朴素贝叶斯,基于贝叶斯定理,加一个”朴素”假设——特征之间条件独立。这个假设很强、基本不成立,但实际效果出奇的好,尤其文本分类(垃圾邮件)。

决策树,模拟人做判断的过程,一串 if-else。每个节点选一个特征做分裂,叶子节点给出预测。关键是”怎么选分裂特征”——经典标准有信息增益(ID3)、信息增益率(C4.5)、基尼系数(CART)。决策树最大的优点是可解释性强,最大的缺点是容易过拟合,解法是剪枝或上集成。

信息增益这个概念光看名字不好懂,咱用熵公式算一遍。熵的公式是 H(D) = -Σ pᵢ·log₂(pᵢ),pᵢ 是第 i 类样本占总数的比例,熵越大说明数据越”乱”。信息增益就是”分裂前熵 - 分裂后熵”,分裂后熵越小,说明这一刀切下去越干净,增益越大,就选这个特征分裂。

举个具体例子。假设有 14 条样本要分”是否打网球”,其中 9 条打、5 条不打。分裂前熵:H(D) = -(9/14)·log₂(9/14) - (5/14)·log₂(5/14) ≈ -0.643·(-0.637) - 0.357·(-1.486) ≈ 0.410 + 0.530 = 0.940 bits。

现在考察”天气”这个特征,它有三个取值:晴、阴、雨。按天气分组后:

晴天 5 条样本(2 打、3 不打),熵 H(晴) = -(2/5)·log₂(2/5) - (3/5)·log₂(3/5) ≈ 0.971 bits

阴天 4 条样本(4 打、0 不打),熵 H(阴) = -(4/4)·log₂(4/4) - 0 = 0 bits(纯了!)

雨天 5 条样本(3 打、2 不打),熵 H(雨) = -(3/5)·log₂(3/5) - (2/5)·log₂(2/5) ≈ 0.971 bits

分裂后的加权熵 = (5/14)·0.971 + (4/14)·0 + (5/14)·0.971 ≈ 0.347 + 0 + 0.347 = 0.694 bits

信息增益 = H(D) - 分裂后熵 = 0.940 - 0.694 = 0.246 bits

这个 0.246 就是”天气”这个特征的信息增益,再用同样方法算其他特征的增益,选最大的那个做分裂特征。ID3 就是这么干的,C4.5 用增益率做了修正(避免偏向取值多的特征),CART 用基尼系数。

随机森林,Bagging 的代表,建很多棵决策树,每棵用自助采样抽出的子数据集训练,分裂时只在部分特征里选最优,最后投票或平均,核心思想是”三个臭皮匠顶个诸葛亮”。

SVM(支持向量机),找一条”最宽的马路”把两类点分开,间隔最大化,离马路最近的那些点叫支持向量,线性不可分时用核函数把数据映射到高维空间。

梯度提升树,Boosting 的代表,和随机森林的”并行投票”不同,Boosting 是”串行纠错”——每棵新树专门去拟合前面所有树的残差。代表算法:GBDT、XGBoost、LightGBM、CatBoost。

这里 Bagging vs Boosting 的区别一定要讲清楚:Bagging 是并行、降方差、树独立;Boosting 是串行、降偏差、树有依赖、后一棵纠前一棵的错。这是重点知识。

回归算法与梯度下降

线性回归,最基础的,y = w·x + b,用最小二乘法(MSE 损失)求 w 和 b。岭回归(Ridge),线性回归加 L2 正则化,让权重都变小但不为 0,模型更平滑。Lasso 回归,线性回归加 L1 正则化,妙处是会产生稀疏解——很多权重直接变 0,相当于自动做特征选择。这也是 L1 vs L2 最核心的区别:L1 产生稀疏(特征选择),L2 产生平滑(权重都变小)。弹性网络(Elastic Net),L1 和 L2 混着用。

线性回归的参数怎么求?最常用的就是梯度下降。咱用一个一元函数走一遍整个过程,让你看清”初始点、求导、更新步长”这三步是怎么循环的。

假设我们要最小化的损失函数是 J(w) = w² + 2w + 1,这是个开口向上的抛物线,最小值在 w=-1 处(你可以心算验证:J(-1)=0)。梯度下降的步骤是:

第一步,求导:dJ/dw = 2w + 2

第二步,设初始点 w₀ = 0,学习率 η = 0.1

第三步,迭代更新:w_{新} = w_{旧} - η · (dJ/dw)

来跑:

第 0 步:w=0,梯度=2·0+2=2,更新 w = 0 - 0.1·2 = -0.2

第 1 步:w=-0.2,梯度=2·(-0.2)+2=1.6,更新 w = -0.2 - 0.1·1.6 = -0.36

第 2 步:w=-0.36,梯度=2·(-0.36)+2=1.28,更新 w = -0.36 - 0.1·1.28 = -0.488

第 3 步:w=-0.488,梯度=2·(-0.488)+2=1.024,更新 w = -0.488 - 0.1·1.024 = -0.5904

第 4 步:w=-0.5904,梯度=2·(-0.5904)+2=0.8192,更新 w = -0.5904 - 0.1·0.8192 = -0.67232

你看,每一步梯度都在变小,w 在一步步逼近真实的极小值点 -1。再跑几十轮,w 会非常接近 -1。这就是梯度下降的精髓——沿着梯度的反方向走,每走一步损失就降一点,直到收敛。如果学习率太大,w 会左右横跳甚至发散;太小,收敛慢得急人。实战中常用 Adam 这种自适应优化器,给每个参数动态调学习率,比纯 SGD 省心得多。

1
2
3
4
5
6
7
8
9
# 梯度下降最小化 J(w) = w^2 + 2w + 1,最小值在 w=-1
w = 0.0
lr = 0.1
for step in range(50):
grad = 2 * w + 2 # dJ/dw
w = w - lr * grad
if step % 10 == 0:
print(f"第{step}步: w = {w:.6f}")
print(f"最终: w = {w:.6f}") # 应接近 -1

聚类算法

K-Means,最常用,指定 K 个簇,先随机放 K 个中心点,每个样本归到最近的中心,然后中心更新为该簇均值,反复迭代。缺点是得自己指定 K、对初始中心敏感、只适合凸形簇。层次聚类,建一棵聚类树,不用事先指定 K 但计算量大。DBSCAN,基于密度,优点是不用指定 K、能发现任意形状的簇、自带噪声检测。高斯混合(GMM),软聚类,给出每个点属于每类的概率,和 K-Means 的区别是硬划分 vs 软划分。

K-Means 的过程光说不练没感觉,咱走一个具体例子。假设有 6 个一维数据点:1, 2, 4, 5, 8, 9,要分成 K=2 个簇。

初始化:随机选两个点当中心,比如 c1=1、c2=2。

第一轮迭代

每个点到两个中心的距离(一维就是绝对差),归到更近的那个:

点 1:到 c1 距离 0、到 c2 距离 1 → 归 c1 簇

点 2:到 c1 距离 1、到 c2 距离 0 → 归 c2 簇

点 4:到 c1 距离 3、到 c2 距离 2 → 归 c2 簇

点 5:到 c1 距离 4、到 c2 距离 3 → 归 c2 簇

点 8:到 c1 距离 7、到 c2 距离 6 → 归 c2 簇

点 9:到 c1 距离 8、到 c2 距离 7 → 归 c2 簇

第一轮分簇结果:c1 簇 = {1},c2 簇 = {2,4,5,8,9}

更新中心:c1 簇均值 = 1,c2 簇均值 = (2+4+5+8+9)/5 = 5.6

第二轮迭代(用新中心 c1=1、c2=5.6):

点 1:到 c1 距离 0、到 c2 距离 4.6 → 归 c1

点 2:到 c1 距离 1、到 c2 距离 3.6 → 归 c1

点 4:到 c1 距离 3、到 c2 距离 1.6 → 归 c2

点 5:到 c1 距离 4、到 c2 距离 0.6 → 归 c2

点 8:到 c1 距离 7、到 c2 距离 2.4 → 归 c2

点 9:到 c1 距离 8、到 c2 距离 3.4 → 归 c2

第二轮分簇结果:c1 簇 = {1,2},c2 簇 = {4,5,8,9}

更新中心:c1 = (1+2)/2 = 1.5,c2 = (4+5+8+9)/4 = 6.5

第三轮迭代(c1=1.5、c2=6.5):

点 1、2 归 c1(距离 0.5、0.5 vs 5.5、4.5)

点 4、5、8、9 归 c2(距离 2.5、3.5 vs 0.5、1.5、1.5、2.5)

分簇结果和上一轮一样:c1={1,2}、c2={4,5,8,9},中心不变(c1=1.5、c2=6.5),收敛!

你看,三轮就收敛了。最终把 {1,2,4,5,8,9} 分成了 {1,2} 和 {4,5,8,9} 两组,中心分别是 1.5 和 6.5。整个过程就是”分配—更新—再分配—再更新”,直到分簇不再变化。注意 K-Means 对初始中心敏感,初始中心选不好可能收敛到次优解,所以实战中常用 K-Means++ 来智能选初始点。

关联规则

这是购物篮分析那一套,”买啤酒的人也爱买尿布”。核心概念三个:支持度(Support)= 同时买 A 和 B 的交易数 / 总交易数,衡量规则有多普遍;置信度(Confidence)= P(B|A),衡量规则的可靠程度;提升度(Lift)= 置信度 / P(B),Lift>1 说明 A 确实促进 B,Lift=1 说明独立,Lift<1 说明 A 反而抑制 B。提升度是最容易被忽略但最能说明问题的指标。Apriori 算法经典但慢,FP-Growth 是它的优化,建 FP 树只扫两次数据库,比 Apriori 快很多。

支持度、置信度、提升度光记公式不会用,咱来一个购物篮的数字例子。假设有 10 笔交易记录,我们看”买牛奶(A)→ 买面包(B)”这条规则:

买牛奶的交易有 6 笔(A 发生 6 次)

买面包的交易有 5 笔(B 发生 5 次)

同时买牛奶和面包的交易有 4 笔(A∩B = 4 笔)

总交易数 = 10

支持度 Support(A→B) = A∩B 的交易数 / 总交易数 = 4/10 = 0.4,意思是 40% 的交易里同时出现了牛奶和面包,这条规则够普遍。

置信度 Confidence(A→B) = A∩B 的交易数 / A 的交易数 = 4/6 ≈ 0.667,意思是”买了牛奶的人里,有 66.7% 也买了面包”,看起来挺靠谱?

提升度 Lift(A→B) = 置信度 / P(B) = 0.667 / (5/10) = 0.667 / 0.5 = 1.333

Lift = 1.333 > 1,说明”买牛奶”确实”促进”了”买面包”——买牛奶的人比一般人更可能买面包(66.7% vs 50%),这条规则是有效的。如果 Lift 刚好等于 1,说明买不买牛奶和买不买面包相互独立,规则没用;如果 Lift 小于 1,说明买牛奶反而抑制了买面包,规则是反向的。所以光看置信度会被骗,一定要算提升度。

评估指标:怎么判断模型好不好

分类任务里,混淆矩阵是基础中的基础。把预测和真实对照,分四种情况:真阳性(TP,预测正实际正)、真阴性(TN,预测负实际负)、假阳性(FP,预测正实际负,误报)、假阴性(FN,预测负实际正,漏报)。所有分类指标都从这四个数算出来。

光记 TP/TN/FP/FN 容易混,咱拿一个二分类的具体例子走一遍。假设我们做了一个癌症筛查模型,对 100 个病人做预测,结果是这样:

实际有癌症的病人 30 个,实际没癌症的 70 个。

模型预测”有癌症”的共 25 个,预测”没癌症”的共 75 个。

在预测”有癌症”的 25 个里,真正有癌症的 20 个,没癌症被误判的 5 个。

在预测”没癌症”的 75 个里,真正没癌症的 65 个,有癌症被漏判的 10 个。

套进混淆矩阵:

TP(真阳性)= 预测正且实际正 = 20

FP(假阳性)= 预测正但实际负 = 5

FN(假阴性)= 预测负但实际正 = 10

TN(真阴性)= 预测负且实际负 = 65

验算一下总数:TP+FP+FN+TN = 20+5+10+65 = 100,对得上。

现在算几个核心指标:

准确率 Accuracy = (TP+TN) / 总数 = (20+65) / 100 = 0.85,整体 85% 预测对。

精确率 Precision = TP / (TP+FP) = 20 / (20+5) = 0.80,意思是”我说有癌症的 25 个人里,真正有癌症的占 80%”。

召回率 Recall = TP / (TP+FN) = 20 / (20+10) = 0.667,意思是”真正有癌症的 30 个人里,我抓到了 66.7%”。注意这里召回率偏低,10 个病人被漏诊了,对癌症筛查来说这是要命的——漏诊一个病人代价极大。

F1 分数 = 2·P·R / (P+R) = 2·0.80·0.667 / (0.80+0.667) = 1.067 / 1.467 ≈ 0.727,是精确率和召回率的调和平均,平衡了这一对矛盾。

用 Python 算一遍更直观:

1
2
3
4
5
6
7
8
9
10
11
TP, FP, FN, TN = 20, 5, 10, 65

accuracy = (TP + TN) / (TP + FP + FN + TN)
precision = TP / (TP + FP)
recall = TP / (TP + FN)
f1 = 2 * precision * recall / (precision + recall)

print(f"Accuracy = {accuracy:.4f}") # 0.8500
print(f"Precision = {precision:.4f}") # 0.8000
print(f"Recall = {recall:.4f}") # 0.6667
print(f"F1 = {f1:.4f}") # 0.7273

回到那个钓鱼类比:精确率高像是”每次下钩都钓到鱼,但可能漏掉很多”(只钓确定有鱼的点);召回率高像是”把所有有鱼的地方都撒网,但可能捞上来一堆杂物”(宁可错杀一千不可放过一个)。再换个医疗筛查的例子:筛查癌症,召回率重要(漏诊一个病人代价大),哪怕精确率低点也能接受;反过来垃圾邮件过滤,精确率重要(把正常邮件判成垃圾邮件很要命),漏几个垃圾邮件无所谓。

F1 是精确率和召回率的调和平均,2·P·R/(P+R),专门平衡这俩。ROC 曲线横轴是假阳性率 FPR,纵轴是真阳性率 TPR(就是召回率),曲线下面积就是 AUC。AUC 越接近 1 越好,0.5 就是瞎猜,好处是跟阈值无关、不受数据不平衡影响,是比赛最常用的指标之一。

对数损失(Log Loss)衡量预测概率和真实标签的差异,越接近真实概率分越低。它比单纯的准确率严格,因为它要求”概率预测得准”。

回归任务用 MSE(均方误差,对大误差敏感)、MAE(平均绝对误差,对异常值鲁棒)、R²(决定系数,0~1 之间,越接近 1 越好)。

过拟合与欠拟合:模型的两种”病”

过拟合就是”学生死记硬背”。平时刷题都会(训练集准确率 99%),一到考试就懵(测试集一塌糊涂),因为他把训练题的每个细节甚至错题都背下来了,没学到真正的规律。表现是训练误差低、测试误差高,模型太复杂、把噪声也学进去了。

欠拟合正好相反,”根本没复习”。连训练集都学不好,更别说测试集。原因是模型太简单、特征太少、训练不够。表现是训练误差就很高。

怎么判断:看训练误差和测试误差的差距。两个都高是欠拟合,训练低测试高是过拟合,两个都低才是理想状态。

过拟合的解法:增加数据、降低模型复杂度、正则化(L1/L2)、Dropout、早停、数据增强、集成学习。欠拟合的解法反过来:增加模型复杂度、加更多特征、训练更久、减小正则化强度。

数据不平衡与正则化

数据不平衡是分类任务里的常见坑。比如欺诈检测,正常交易 99.9%、欺诈 0.1%,模型很容易学成”全猜正常”,准确率 99.9% 但毫无价值。处理思路:重采样(过采样少数类用 SMOTE、欠采样多数类)、代价敏感学习(给少数类加权重)、换评估指标(看召回率、F1、AUC 而非准确率)、集成方法。

SMOTE 是重点:对少数类每个样本找 K 个近邻,在它和近邻连线上随机生成新样本,比直接复制更合理。注意 SMOTE 是过采样不是欠采样,这是常见易错点。

SMOTE 具体怎么生成新样本?咱走一遍。假设少数类里有个样本 A,特征是 (2, 3)。第一步,在少数类里找 A 的 K=5 个最近邻,比如找到的近邻里有个样本 B,特征是 (4, 7)。第二步,在 A 和 B 的连线上随机选一个点作为新样本。连线的向量是 B-A = (4-2, 7-3) = (2, 4)。第三步,随机生成一个 0~1 之间的数 gap(比如 0.4),新样本 = A + gap·(B-A) = (2 + 0.4·2, 3 + 0.4·4) = (2.8, 4.6)。这个 (2.8, 4.6) 就是生成的新样本,它位于 A 和 B 之间,既不是简单复制 A,也不是简单复制 B,而是少数类区域里一个”合理的新点”。对少数类的每个样本都这么生成若干个新点,少数类就被”撑大”了,数据更平衡。

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

# 少数类样本 A 和它的近邻 B
A = np.array([2.0, 3.0])
B = np.array([4.0, 7.0])

# 在 A、B 连线上随机生成一个新样本
gap = np.random.uniform(0, 1) # 0~1 之间的随机数
new_sample = A + gap * (B - A)
print(f"gap = {gap:.4f}, 新样本 = {new_sample}") # 例如 gap=0.4, 新样本 = [2.8, 4.6]

正则化统一收一下:在损失函数后面加一个对权重的惩罚项,防止权重过大。L1(Lasso)加 ||w||₁ 产生稀疏解做特征选择;L2(Ridge)加 ||w||² 让权重都变小但不为 0 模型平滑;弹性网络两者结合。神经网络里 Dropout、BatchNorm、Early Stopping 也都起到正则化作用。

最后说特征工程和降维。特征工程包括缺失值处理、编码(one-hot、label encoding)、归一化(Min-Max 缩到 0~1)、标准化(Z-score 均值 0 方差 1)、分箱、特征组合。”数据决定上限、模型逼近上限”。

降维这块,PCA 是最经典的无监督降维方法,基本思路是”找数据方差最大的方向”。它的步骤可以拆成几步:先把数据按特征做标准化(去量纲影响),然后算数据的协方差矩阵,对这个矩阵做特征值分解,得到一组特征值和特征向量,把特征值从大到小排序,挑前 k 个最大的特征值对应的特征向量组成投影矩阵,最后把原始数据乘上这个投影矩阵就得到降维后的数据。一句话概括就是”找方差最大的几个方向,把数据投影过去”。为什么选方差大的方向?因为方差大代表信息量大,方差小的方向近似常数、没信息。LDA 是有监督降维,找的是”类间方差大、类内方差小”的方向,所以要用到标签信息,最多能降到”类别数减 1”维。t-SNE 是非线性降维,主要用于可视化,把高维数据压到 2 维或 3 维画出来看。PCA vs LDA 的核心区别:PCA 无监督看方差最多降到特征数,LDA 有监督看类别可分性最多降到类别数减 1。

人工智能与机器学习重点回顾

监督、无监督、强化三种学习,区别在”有没有标签”和”反馈形式”。分类和回归,看标签是离散还是连续。逻辑回归是分类不是回归,名字唬人。L1 产生稀疏做特征选择,L2 平滑权重都变小。Bagging 并行降方差(随机森林),Boosting 串行降偏差(XGBoost 一族)。精确率是”我说对的比例”,召回率是”真阳性抓住的比例”。筛查病人重召回,垃圾邮件重精确。F1 是两者的调和平均。过拟合是训练好测试差,欠拟合是训练就差。准确率在不平衡数据上会骗人,要看 F1、AUC、召回率。SMOTE 是少数类过采样方法,不是欠采样。训练集学、验证集调参、测试集最后评估一次,三个不能混用。PCA 无监督降维看方差,LDA 有监督降维看类可分性,t-SNE 主要用来可视化。支持度衡量规则普遍性,置信度衡量可靠性,提升度才是判断”是否真有促进”的关键,Lift=1 说明独立。KNN 预测慢训练快、要标准化特征;决策树易过拟合要剪枝;SVM 找最宽间隔、靠支持向量、用核技巧处理非线性。梯度消失换 ReLU、用 BatchNorm 和残差,梯度爆炸用梯度裁剪。强化学习的奖励是延迟的、是反馈不是答案,和监督学习的标签本质不同。