🐸 青蛙编程网
首页 / AI / 机器学习 / 2. 监督学习入门

监督学习入门

这是什么:监督学习(Supervised Learning) = 有答案可以对答案学:拿标好标签的样本练出规律。

为什么用:上一篇说了机器学习分三类,其中最常用、最适合入门的就是它。分类还是回归、训练集和测试集怎么划,全都要靠"特征对标签"这套基本功打地基。

如何用:本章用"根据面积和房间数预测房价"做例子,先把特征和标签拆清楚,再分清分类和回归。

特征与标签:线索与答案

监督学习的每个样本都由两部分组成:

  • 特征(feature):用来做判断的线索,也就是输入数据
  • 标签(label):要预测的标准答案,也就是人事先标好的结果

比如"根据面积和房间数预测房价",每行数据长这样:

houses = [
    # [面积(㎡), 房间数, 价格(万元)]
    [50, 1, 200],
    [80, 2, 320],
    [100, 3, 390],
    [120, 3, 460],
]

print("面积 | 房间 | 价格(标签)")
for area, rooms, price in houses:
    print(f"{area}㎡ | {rooms}室 | {price} 万")

你会看到:

面积 | 房间 | 价格(标签)
50㎡ | 1室 | 200 万
80㎡ | 2室 | 320 万
100㎡ | 3室 | 390 万
120㎡ | 3室 | 460 万

每行前两列是特征,最后一列是标签。机器要学的,就是"从特征推出标签"的规律。

再看一个分类例子:根据花瓣长宽判断鸢尾花品种。

flowers = [
    # [花瓣长(cm), 花瓣宽(cm), 品种]
    [1.4, 0.2, "setosa"],
    [4.7, 1.4, "versicolor"],
    [5.5, 2.0, "virginica"],
    [1.3, 0.2, "setosa"],
]

for pl, pw, label in flowers:
    print(f"花瓣 {pl}×{pw} cm → {label}")

输出:

花瓣 1.4×0.2 cm → setosa
花瓣 4.7×1.4 cm → versicolor
花瓣 5.5×2.0 cm → virginica
花瓣 1.3×0.2 cm → setosa

这里特征是"花瓣长、宽",标签是"品种"。

分类 vs 回归:标签长什么样

标签的类型决定了任务是分类还是回归:

  • 标签是类别(几个选项里选一个)→ 分类(classification)。比如"根据花瓣长宽判断鸢尾花品种",答案只有 setosa、versicolor、virginica 三选一
  • 标签是连续数字(可以无限细分)→ 回归(regression)。比如房价,可以是 200 万、213.5 万……任何数
名词 通俗解释 房价例子 鸢尾花例子 垃圾短信例子
特征 判断用的线索 面积、房间数 花瓣长、花瓣宽等 4 项 短信文本、是否含链接
标签 要预测的答案 价格(数字) 品种(类别) 是/不是垃圾短信(类别)
任务类型 由标签决定 回归 分类 分类

一句话判断:要预测"是什么类",用分类;要预测"是多少",用回归。

训练集与测试集:刷题册 vs 考卷

收集到的数据不能全拿来学,要分成两份:

  • 训练集(training set):给模型学习的"刷题册",通常占 80%
  • 测试集(test set):模型从没见过的"考卷",占 20%,用来验收真实水平

为什么非要留考卷?因为模型很容易"背题"而不"学会"。用训练集自己考自己,分数只会虚高。下一章《模型评估》会专门讲怎么给模型打分。

这里先记住铁律:考试题绝不能提前刷过。

代码示例:划分训练集/测试集

from sklearn.model_selection import train_test_split

# 150 朵花的特征和标签
X = [[5.1, 3.5], [4.9, 3.0], [6.0, 3.0], [6.5, 2.8]]  # 简化示例
y = [0, 0, 1, 1]

# 75% 刷题,25% 考试,固定随机种子保证每次结果一致
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42)

print("训练集样本数:", len(X_train))
print("测试集样本数:", len(X_test))

你会看到:

训练集样本数: 3
测试集样本数: 1

知识点全对上

代码/概念 对应含义
houses 里的 [50, 1] 特征:面积、房间数
houses 里的 200 标签:价格(连续数字 → 回归)
flowers 里的 "setosa" 标签:品种(类别 → 分类)
train_test_split(..., test_size=0.25) 把 25% 数据留作考卷
random_state=42 固定随机种子,每次划分结果一样

❓ 常见问题

Q1:特征越多越好吗?

不一定。特征太多且与预测目标无关,会带来噪音,模型更容易"学歪"。选特征的原则是:与目标强相关、可获取、维度不过高。

Q2:训练集和测试集的比例必须是 8:2 吗?

不是,8:2 是经验值。数据量少时可用 7:3 或 6:4;数据量巨大(百万级以上)时,测试集占比可适当降到 10% 左右。

Q3:标签写错了怎么办?

监督学习靠标签学规律,标签有误会直接教歪模型。数据清洗(纠正错误标签、剔除异常值)往往比选哪个算法更重要。

⚠️ 新手翻车现场

翻车一:把测试集也当训练集用

# 错误:把全部数据都 fit 进去,没有留考卷
model.fit(X, y)   # X, y 是全部 150 朵花
score = model.score(X, y)  # 在同一组数据上打分,分数虚高

问题:model.score(X, y) 在"刷题册"上考试,100% 准不代表会做新题。

修正:只用 X_train, y_train 调用 fit,只用 X_test, y_test 调用 score,两组数据不能混。

翻车二:标签和特征搞反

# 错误:把价格当特征,面积当标签
X = [[200], [320], [390], [460]]   # 价格作为输入
y = [[50, 1], [80, 2], [100, 3], [120, 3]]  # 面积房间作为输出

问题:逻辑颠倒了。应该是"用面积房间去预测价格",而不是反过来。

修正:始终问自己"我有什么(特征)→ 我想求什么(标签)",把已知的放 X,要预测的放 y。

📦 换皮小示例:判断邮件是否垃圾

把"房价预测"的套路套在文本分类上:

# 特征:邮件是否含"中奖""贷款""点击"(1=有,0=无)
# 标签:是否垃圾邮件(1=是,0=否)
emails = [
    [1, 1, 1, 1],  # 含三个关键词 → 垃圾
    [0, 0, 0, 0],  # 无关键词 → 正常
    [1, 0, 0, 0],  # 只含"中奖" → 垃圾
    [0, 1, 0, 1],  # 含"贷款"和"点击" → 垃圾
]

X = [[row[0], row[1], row[2]] for row in emails]  # 三个关键词特征
y = [row[3] for row in emails]                    # 标签

🎯 什么时候用监督学习

  • 有历史数据,且每条数据都有已知答案(标签)
  • 需要对新数据做分类(垃圾/非垃圾、猫/狗/其他)或回归(房价、气温、销量)
  • 答案可以人工标注,成本可接受

📝 本章小结

  • 监督学习 = 特征(线索)+ 标签(答案),机器从例子里学规律
  • 标签是类别 → 分类;标签是连续数字 → 回归
  • 数据要拆成训练集(刷题册)和测试集(考卷),比例常见 8:2
  • 铁律:考试题绝不能提前刷过,否则分数虚高
  • 记忆口诀:特征是线索,标签是答案;类别分类,数字回归;八成刷题,两成考试

动手改

  1. 在 houses 里加一行 90 平米、2 室的房子,猜猜价格大概多少?
  2. "根据邮件内容判断是不是垃圾邮件"——分类还是回归?
  3. "预测明天的气温"呢?
  4. 把上面的 train_test_split 改成 test_size=0.5,观察训练集和测试集各多少样本

下一章:第一个模型,用 scikit-learn 训练你人生第一个机器学习模型 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。