同一条数据:人手把阈值定在 3.0,训练集 0.768、测试集 0.867; 让机器在训练集上扫一遍,学到 5.0,测试集 0.987。 但样本只有 20 条时,学到的阈值在 3.6 到 6.1 之间乱跳。
前三章打完了 Python 的地基,这一章开始讲算法。 第一节先把最容易混的一件事说清:机器学习和人工智能到底谁包含谁。
一、三个词,一层套一层
人工智能是最大的那个圈,机器学习是圈里的一块,深度学习又是机器学习里的一块。 分界在于谁定规则。写死的判断是「人定规则」,从数据里找规律是「机器学习」。 举个最小例子:判断一封邮件是不是垃圾邮件。人定规则就是「含链接超过 3 个就算」; 机器学习是给一批已标好的邮件,让它自己找那条线画在哪。 Demo 用的就是这个场景的数字版:一维特征 x、标签由一条隐藏规律生成, 然后比较「人定阈值」和「从数据学阈值」。
二、实测:学出来的线比我拍的准
人手把阈值定在 3.0,因为「看着差不多」。训练集准确率 0.768,测试集 0.867。 机器在训练集上扫 197 个候选阈值,挑出准确率最高的那个:5.0。 训练集 0.952,测试集 0.987。 差了 12 个百分点。这不是算法多神,而是它真的去比了——而我只是拍了个数。 注意训练集和测试集的差距:人定规则那行是 0.768 对 0.867(测试反而高), 学出来那行是 0.952 对 0.987。两组都不算过拟合,因为参数只有一个。
三、扫描曲线:好阈值不止一个
把 8 个阈值点的训练集准确率打出来:1.0 是 0.524,3.0 是 0.768,5.0 是 0.952,8.0 掉回 0.768。 曲线是个单峰,峰顶在 5.0 附近,两边都往下掉。 这说明「找阈值」这件事本身不难——难的是知道该往哪个方向找。 真实场景里参数是几百上千维,没法画曲线,只能靠梯度或网格搜索。 但道理一样:在训练集上挑最好的那一组。
四、样本少的时候,学会飘
这里有个陷阱。我把「学阈值」重复了 30 次,每次只随机抽一部分训练数据: - 20 条样本:学到的阈值平均 4.89,标准差 0.70,范围 3.6 到 6.1。 - 250 条样本:平均 5.00,标准差 0.00,稳稳落在 5.0。 也就是说,20 条数据训练出来的模型,换一批数据就可能换个结论。 测试集准确率看着还有 0.956,但那是运气——这次恰好抽到了好样本。 这就是「小样本不可靠」的量化版本:不是「大概不准」,而是标准差 0.70 对 0.00。 所以别人说「我拿 30 条数据训了个模型效果很好」,你要问的不是准确率, 是「换个随机种子还是不是这个数」。
五、动手 Demo:人手定规则,还是让机器学阈值
造 400 条一维数据,正类概率随特征上升、拐点在 5.0; 先用一个人拍的阈值 3.0 算训练集与测试集准确率,再在训练集上扫 197 个候选阈值取最优; 打出 8 个阈值点的准确率;最后对 5 种样本量各重复抽 30 次,看学到的阈值稳不稳。
p = 1.0 / (1.0 + np.exp(-(x - 5.0) * 2.2)) # 真实规律
y = (rg.uniform(0, 1, n) < p).astype(int)
def score(th, sel):
return float(np.mean((x[sel] > th).astype(int) == y[sel]))
grid = np.linspace(0.1, 9.9, 197)
best = max(grid, key=lambda t: score(t, tr))
for m in (20, 50, 100, 200, 250):
for _ in range(30): # 每次重新抽样
sub = rg2.choice(tr, size=m, replace=False)
ths.append(max(grid, key=lambda t: score(t, sub)))
实跑输出:
--------------------------------------------------------------------
同一条数据:人手定规则,还是让机器学阈值
--------------------------------------------------------------------
样本数 400(训练 250/测试 150)
真实规律 正类概率随 x 单调上升,拐点在 5.0 附近
人手定的阈值 3.0
从训练集学到的阈值 5.0
做法 阈值 训练集准确率 测试集准确率
--------------------------------------------
人定规则 3.0 0.768 0.867
学习得到 5.0 0.952 0.987
扫一遍候选阈值(训练集准确率):
阈值 1.0 ################ 0.524
阈值 2.0 ################### 0.648
阈值 3.0 ####################### 0.768
阈值 4.0 ########################## 0.880
阈值 5.0 ############################# 0.952
阈值 6.0 ########################### 0.900
阈值 7.0 ######################### 0.844
阈值 8.0 ####################### 0.768
每种样本量重复抽 30 次,看学到的阈值抖不抖:
样本量 阈值均值 标准差 范围 测试集准确率
--------------------------------------------------
20 4.89 0.70 3.6~6.1 0.956
50 4.91 0.31 4.0~5.2 0.979
100 5.07 0.10 5.0~5.2 0.986
200 5.10 0.10 5.0~5.2 0.987
250 5.00 0.00 5.0~5.0 0.987
第一行和第四行对比:20 条时阈值 3.6~6.1、标准差 0.70;
200 条时范围收到 5.0~5.2、标准差 0.10。
所以「学习」不是魔法,它是【用样本量换稳定性】。
人定 3.0 那行:训练集 0.768、测试集 0.867。学出来的 5.0:0.952 和 0.987。 同一条数据,差 12 个百分点。 阈值扫描那八行是个单峰:0.524 一路爬到 0.952,再掉回 0.768。 峰顶就是 5.0,也就是真实规律里那个拐点。 抽样那五行是本节重点:20 条时范围 3.6~6.1、标准差 0.70; 250 条时范围 5.0~5.0、标准差 0.00。 注意 20 条那行的测试集准确率还有 0.956——它不低,但它不可信, 因为换 30 次抽样阈值就换 30 个位置。
30 秒实验
- 把噪声加大(拐点斜率从 2.2 改成 0.8),重跑一遍,看需要的样本量变多少。
- 把测试集比例从 150 改成 50,看准确率的波动变大还是变小。
- 想一想:为什么「训练集准确率高」本身不能说明模型好?
常见误区
- 「人工智能就是机器学习」——机器学习只是其中一块,还有搜索、规划、规则系统。
- 「模型准不准看准确率」——还要看这个数换一批数据还成不成立。
- 「样本少也能训」——30 条数据训出来的东西,换种子就换结论。
自测三问(点开对答案)
1. 机器学习跟人写规则的根本区别是什么? —— 规则由人写死,还是从数据里找出来。 2. 本次 Demo 里人定阈值和学到的阈值差多少准确率? —— 测试集 0.867 对 0.987,差 12 个百分点。 3. 为什么 20 条样本训出来的模型不可信? —— 重复抽样 30 次,阈值标准差 0.70,换批数据就换结论。机器学习分几类?下一节把监督、无监督、强化三种范式各跑一遍。
- ☐ (本节完,下一节 4.1.2 3个基本类型:了解机器学习算法的技术原理)