🏠 总目录📚 本教程 01 · 10分钟训第一个模型
📑 本页目录(点开跳转)

01 · 10 分钟训练你的第一个模型

10 分钟 | ⭐ 核心 | 🔨 必须动手 | 不用下载任何数据


🎯 一句话

机器学习的完整流程只有四步:拿数据 → 切分 → 训练 → 考试。这一节你把它跑一遍,并且亲眼看到「过拟合」长什么样


🔨 动手:复制这段代码跑

pip install numpy scikit-learn
# -*- coding: utf-8 -*-
"""10 分钟训练你的第一个模型 —— 不用下载任何数据"""
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.preprocessing import StandardScaler

# ===== 第 1 步:拿数据(sklearn 自带,569 个肿瘤样本,30 个特征)=====
X, y = load_breast_cancer(return_X_y=True)
print(f"数据形状:{X.shape}{X.shape[0]} 个样本,每个 {X.shape[1]} 个特征")
print(f"标签:{set(y)}   (0=恶性, 1=良性)")

# ===== 第 2 步:切分 —— 训练集用来学,测试集用来考试 =====
X_tr, X_te, y_tr, y_te = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y)
print(f"训练集 {len(X_tr)} 个,测试集 {len(X_te)} 个")

# ===== 第 3 步:训练两个模型 =====
# 模型A:逻辑回归(线性模型,需要标准化)
scaler = StandardScaler().fit(X_tr)
lr = LogisticRegression(max_iter=1000)
lr.fit(scaler.transform(X_tr), y_tr)

# 模型B:决策树,故意不限制深度
tree = DecisionTreeClassifier(random_state=42)
tree.fit(X_tr, y_tr)

# ===== 第 4 步:看结果 =====
print("\n" + "=" * 46)
print(f"{'模型':<16}{'训练集':>10}{'测试集':>10}{'差距':>10}")
print("=" * 46)
for name, m, Xa, Xb in [
    ("逻辑回归", lr, scaler.transform(X_tr), scaler.transform(X_te)),
    ("决策树(无限制)", tree, X_tr, X_te),
]:
    tr = m.score(Xa, y_tr)
    te = m.score(Xb, y_te)
    print(f"{name:<16}{tr:>9.1%}{te:>10.1%}{tr-te:>10.1%}")
print("=" * 46)

# ===== 第 5 步:给决策树限制深度,再看 =====
print("\n决策树深度对效果的影响:")
print(f"{'最大深度':<10}{'训练集':>10}{'测试集':>10}{'差距':>10}")
for d in [1, 2, 3, 5, 10, None]:
    t = DecisionTreeClassifier(max_depth=d, random_state=42).fit(X_tr, y_tr)
    tr, te = t.score(X_tr, y_tr), t.score(X_te, y_te)
    label = str(d) if d else "不限制"
    print(f"{label:<10}{tr:>9.1%}{te:>10.1%}{tr-te:>10.1%}")

🎉 你应该看到这个

数据形状:(569, 30)  →  569 个样本,每个 30 个特征
训练集 398 个,测试集 171 个

==============================================
模型                     训练集       测试集        差距
==============================================
逻辑回归                98.7%     98.8%     -0.1%
决策树(无限制)           100.0%     91.8%      8.2%
==============================================

决策树深度对效果的影响:
最大深度             训练集       测试集        差距
1             92.7%     91.2%      1.5%
2             96.5%     91.8%      4.7%
3             98.0%     92.4%      5.6%
5             99.5%     93.0%      6.5%
10           100.0%     91.8%      8.2%
不限制          100.0%     91.8%      8.2%

恭喜,你训了两个模型,而且已经撞上了机器学习最重要的问题。


🔍 盯着这三行看

① 决策树训练集 100%,测试集只有 91.8%

   训练集 100% = 它把 398 个样本的答案「全背下来了」
   测试集 91.8% = 遇到没背过的,就露馅了

   这就是【过拟合 Overfitting】——
   学会了「记住」,没学会「理解」

💡 人话类比:一个学生把往年真题答案全背了(训练集满分),但一考新题就不会(测试集拉胯)。他没学到规律,只记住了答案。

② 逻辑回归训练 98.7%、测试 98.8%,几乎没差距

能力弱(画不出复杂的分界线),反而被迫去找真正的规律——所以泛化得好。

🔑 第一个反直觉结论模型不是越强越好。 强到能背下全部数据,它就懒得去理解了。

③ 深度表格里那个「拐点」

   深度 1 → 3:训练涨,测试也涨   ← 模型在学真规律 ✅
   深度 5 → 10:训练涨,测试反而跌 ← 开始背答案了 ❌
                    ↑
              这个拐点就是你要找的最优复杂度

这张表的形状,是整个机器学习的缩影。 第 5 章会把它讲透。


🧩 顺便认识了四个核心概念

概念 在代码里 什么意思
特征 Feature X,形状 (569, 30) 用来做判断的输入。每行一个样本,每列一个特征
标签 Label y,值是 0/1 要预测的答案
训练/测试切分 train_test_split 留一部分不给模型看,用来当考卷 ⭐
过拟合 那个 8.2% 的差距 训练集好、测试集差

⚠️ test_size=0.3 那行是全代码最重要的一行。 不切分、拿训练集当考卷,你会得到 100% 的假象——这是新手第一大坑


🔗 和站内其他章的关系

相关的地方 根因在这
推荐算法第 3 章「按时间切分,别随机切」 就是这里的切分,只是推荐场景要防未来信息泄漏
Kaggle 第 2 章「训练策略与正则化」 正则化解决的就是这个过拟合
Kaggle 「CV 分数和 LB 分数对不上」 同一个问题的竞赛版

🎮 玩一下(改代码比读文字有用)

  1. 换个模型:加一行 from sklearn.ensemble import RandomForestClassifier,试试随机森林,差距变小了吗?
  2. 改切分比例test_size 从 0.3 改成 0.5,训练数据变少后过拟合更严重还是更轻?
  3. 换随机种子random_state 改成 0、1、2,分数波动有多大?——这个波动幅度,决定了「涨 0.5% 算不算真的涨」

🔗 这一章连到哪里

去哪 为什么
推荐算法 01 同一套「先跑通再问为什么」,那边 10 分钟做出一个推荐系统
智能体 01 同一套节奏的 Agent 版,不用 API Key 也能跑
Kaggle 25 ⭐ 这一章那段代码的工业版:同样是先有能跑的最小闭环,再逐环替换

✅ 检查点

  1. 机器学习的四步流程是什么?
  2. 决策树训练 100%、测试 91.8%,说明什么?
  3. 为什么能力更弱的逻辑回归反而泛化更好?
  4. 为什么必须切出测试集?
  5. 深度表格里的「拐点」意味着什么?
👀 答案
  1. 拿数据 → 切分(训练/测试)→ 训练 → 在测试集上考试。
  2. 过拟合——它背下了训练数据而没学到规律,遇到没见过的就不行。
  3. 它画不出太复杂的分界线,没能力去"背",只能去找真正的规律,所以泛化好。模型不是越强越好。
  4. 不切分就只能拿训练集评估,模型背下答案就是 100%,你会得到完全虚假的信心。
  5. 拐点之前模型在学真规律(训练测试同涨),之后开始背答案(训练涨测试跌)。拐点就是最优复杂度。

🛑 可以停在这里

走神救援

四步:拿数据→切分→训练→考试。⭐那段代码做了什么:用 sklearn 自带的乳腺癌数据(569 个样本 × 30 个特征,0=恶性 / 1=良性,不用下载),按 test_size=0.3 切成训练 398 / 测试 171,训两个模型——逻辑回归(线性,需先标准化)和故意不限深度的决策树,再把树深从 1 扫到"不限制"。⭐盯着看的那三行:①决策树训练 100.0%、测试只有 91.8%,差距 8.2%——它把 398 个样本的答案全背下来了,遇到没背过的就露馅,这就是过拟合(学会了"记住",没学会"理解");②逻辑回归 98.7% / 98.8%,差距 −0.1%——它能力弱、画不出复杂分界线,反而被迫去找真规律,⭐第一个反直觉结论:模型不是越强越好;③深度表里的拐点:深度 1→3 训练与测试同涨(91.2%→92.4%),深度 5 测试 93.0% 见顶,深度 10 和不限制都是训练 100.0% / 测试跌回 91.8%,⭐拐点就是最优复杂度,这张表的形状是整个机器学习的缩影。顺带认识的四个概念特征X,形状 (569, 30),每行一样本每列一个输入;标签y,0/1,要预测的答案;训练/测试切分=留一部分当考卷;过拟合=那个 8.2% 的差距。⚠️test_size=0.3 是全代码最重要的一行:不切分、拿训练集当考卷,你会得到 100% 的假象——这是新手第一大坑。再走一步就换随机种子看波动,它决定了"涨 0.5% 算不算真的涨"

下一节 👉 02-机器学习到底在干什么.md

打卡记录保存在你的浏览器里,首页能看到总进度