跳转至

13.1   什么是机器学习

社团招新季快到了。小率负责给同学推荐活动:有人喜欢篮球,有人喜欢摄影,有人只想找离宿舍近、时间不冲突的活动。

一开始,小率写了几条规则:喜欢运动就推荐篮球社,喜欢画画就推荐美术社,周末有空就推荐志愿活动。可是表格越整理越复杂:有的人同时喜欢音乐和摄影,有的人报名过但从不参加,有的人只在考试周之后有空。规则越写越长,推荐却仍然经常不合适。

图 13.1.0 小率和均哥整理校园活动推荐数据

规则写不完时怎么办

机器学习(Machine Learning) 不是让计算机凭空“变聪明”,而是把“人手写规则”的问题,改成“让程序从例子里学规则”的问题。它适合规则复杂、边界模糊、数据会变化的任务。

同学 最近参加活动 兴趣标签 空闲时段 最后选择
A 篮球、跑步 运动 周末下午 篮球社
B 摄影展 艺术、记录 周五晚上 摄影社
C 志愿服务 公益、社交 周末上午 志愿队
... ... ... ... ...
均哥,我能不能把所有推荐规则都列出来?
可以试,但现实会一直长出新情况。机器学习想做的是:从过去选择里学出可迁移的规律。

13.1.1   传统编程先写规则

传统编程的顺序很直接:

if "运动" in interest and free_time == "周末下午":
    recommend = "篮球社"
elif "摄影" in interest:
    recommend = "摄影社"
else:
    recommend = "综合社团"

人先想清楚规则,程序照着执行。这个办法在边界清楚时很好用,比如计算平均数、检查密码长度、按价格排序。

但推荐活动这种任务有两个麻烦:

  • 同一个特征可能在不同人身上含义不同。
  • 规则之间会互相打架,比如“喜欢音乐”和“只有周三有空”可能同时出现。
  • 以后出现新活动、新兴趣标签,旧规则很快过期。
也就是说,规则不是不能写,而是写到后面会越来越脆。
对。机器学习不是替代所有规则,而是处理那些规则难以完整写出的部分。

13.1.2   机器学习从例子里学规则

机器学习把顺序换了一下:给程序很多“输入 + 历史答案”,让算法找出一套预测规则。

图 13.1.1 从例子到模型再到推荐

用符号写,输入特征是:

\[ \mathbf{x}=(\text{兴趣标签},\ \text{活动历史},\ \text{空闲时段},\ \text{距离},\ldots) \]

历史答案是 \(y\),比如“最后选择的活动”。模型(Model)学到一个函数:

\[ \hat y=f_\theta(\mathbf{x}) \]

这里的 \(\theta\) 是模型需要学习的参数,\(\hat y\) 是对新同学的预测推荐。

三个格子

数据是例子,模型是规则的形状,目标是评分标准。训练模型,就是调整参数 \(\theta\),让预测结果尽量接近历史答案。


13.1.3   学习的重点是新样本

如果模型只会背旧表格,它并没有真的学会。机器学习最关心的是 泛化(Generalization):模型在没见过的新样本上是否仍然有效。

Tom Mitchell 的经典定义可以这样读:

如果程序在任务 \(T\) 上,随着经验 \(E\) 的增加,性能 \(P\) 提升,我们就说它在学习。

放进校园活动推荐:

符号 对应含义
\(T\) 给新同学推荐合适活动
\(E\) 过去同学的兴趣、活动记录和选择
\(P\) 推荐命中率、满意度、召回率等
如果旧数据上特别准,新同学来了却推荐错了呢?
那更像背题。机器学习真正要过的是“新题考试”。

13.1.4   用 Python 训练一个小模型

下面用一份拟真合成数据演示:根据“运动兴趣分、艺术兴趣分、周末是否有空”预测是否推荐活动 A。

import numpy as np
from sklearn.linear_model import LogisticRegression

rng = np.random.default_rng(2026)
n = 120
sports = rng.normal(0, 1, n)
art = rng.normal(0, 1, n)
weekend_free = rng.integers(0, 2, n)

score = 1.2 * sports + 0.7 * weekend_free - 0.4 * art
prob = 1 / (1 + np.exp(-score))
chosen = rng.binomial(1, prob)

X = np.column_stack([sports, art, weekend_free])
model = LogisticRegression().fit(X, chosen)

new_student = np.array([[1.0, -0.2, 1]])
print("推荐活动 A 的概率 =", round(model.predict_proba(new_student)[0, 1], 3))

这段代码里,sportsartweekend_free 是特征,chosen 是历史答案,LogisticRegression 是模型。它不是“懂社团”,而是在历史选择里学到一套可用于新同学的模式。

机器学习不是万能钥匙

如果历史选择本身有偏差,模型也会学到偏差;如果新学期活动完全换了一批,旧规律也可能失效。机器学习依赖数据,但不自动保证数据可信。

小率的笔记本

机器学习就是从例子里学习可泛化的规则。最小框架是数据、模型、目标;真正的考验不是训练集表现,而是没见过的新样本表现。