1204 综合练习

Part A:给定数据集的精讲精练(共 6 题)

练习 1:“鸢尾花决策树 —— 从训练到剪枝”

🎯 目标:掌握决策树的完整训练流程,理解 max_depth 对过拟合的影响。 📂 数据集sklearn.datasets.load_iris(鸢尾花,3 分类,4 个特征)

【详细操作步骤(Step-by-Step)】

第 1 步:导入模块

1import numpy as np
2import matplotlib.pyplot as plt
3from sklearn.datasets import load_iris
4from sklearn.model_selection import train_test_split
5from sklearn.tree import DecisionTreeClassifier, plot_tree
6from sklearn.metrics import accuracy_score

第 2 步:加载数据并划分

1X, y = load_iris(return_X_y=True)
2X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
3
4print(f"训练集:{X_train.shape[0]} 条,测试集:{X_test.shape[0]} 条")

第 3 步:训练不同深度的决策树

 1depths = [2, 4, 6, None]  # None 表示不限制深度
 2train_scores = []
 3test_scores = []
 4
 5for depth in depths:
 6    dt = DecisionTreeClassifier(max_depth=depth, random_state=42)
 7    dt.fit(X_train, y_train)
 8    train_scores.append(dt.score(X_train, y_train))
 9    test_scores.append(dt.score(X_test, y_test))
10    print(f"max_depth={depth}: 训练集={train_scores[-1]:.3f}, 测试集={test_scores[-1]:.3f}")

第 4 步:绘制性能对比图

1plt.figure(figsize=(8, 5))
2plt.plot([str(d) for d in depths], train_scores, marker='o', label='训练集准确率')
3plt.plot([str(d) for d in depths], test_scores, marker='s', label='测试集准确率')
4plt.xlabel('max_depth')
5plt.ylabel('准确率')
6plt.legend()
7plt.grid(True)
8plt.title('决策树不同深度性能对比')
9plt.show()

第 5 步:可视化最佳树结构

1best_dt = DecisionTreeClassifier(max_depth=3, random_state=42)
2best_dt.fit(X_train, y_train)
3
4plt.figure(figsize=(14, 8))
5plot_tree(best_dt, feature_names=load_iris().feature_names, 
6          class_names=load_iris().target_names, filled=True, rounded=True)
7plt.show()
8
9print(f"特征重要性:{dict(zip(load_iris().feature_names, best_dt.feature_importances_))}")

第 6 步:回答以下问题

  1. max_depth=None 时,训练集准确率是多少?测试集准确率是多少?是否出现过拟合?
  2. 哪个 max_depth 在测试集上表现最好?
  3. 最重要的特征是哪一项?具体数值是多少?

练习 2:“手算基尼系数 —— 理解特征分裂依据”

🎯 目标:通过手动计算 + 代码验证,深刻理解基尼系数如何指导特征选择。 📂 数据集:下表是简化版“西瓜好坏”数据集(6 个样本,2 个特征)

样本 色泽(0=浅绿,1=深绿) 根蒂(0=蜷缩,1=稍蜷) 好瓜(1=好,0=坏)
1 0 0 0
2 0 1 1
3 1 0 1
4 1 1 1
5 0 0 0
6 1 0 1

【详细操作步骤(Step-by-Step)】

第 1 步:手动计算根节点的基尼系数

公式:Gini = 1 - Σ(P_i)²,其中 P_i 是第 i 类样本的比例。

当前 6 个样本中,好瓜有____个,坏瓜有____个。

  • P(好瓜) = ____ / 6 = ____
  • P(坏瓜) = ____ / 6 = ____
  • Gini(根节点) = 1 - ()² - ()² = ____

第 2 步:手动计算按“色泽”分裂后的基尼增益

按色泽=0(浅绿)分组:样本 、____ → 好瓜____个,坏瓜____个。

  • Gini(色泽=0) = 1 - ()² - ()² = ____

按色泽=1(深绿)分组:样本 、____ → 好瓜____个,坏瓜____个。

  • Gini(色泽=1) = 1 - ()² - ()² = ____

加权平均 Gini(色泽) = (3/6) × ____ + (3/6) × ____ = ____

基尼增益 = Gini(根节点) - Gini(色泽) = ____

第 3 步:手动计算按“根蒂”分裂后的基尼增益

按根蒂=0(蜷缩)分组:样本 → 好瓜____个,坏瓜____个。

  • Gini(根蒂=0) = 1 - ()² - ()² = ____

按根蒂=1(稍蜷)分组:样本 → 好瓜____个,坏瓜____个。

  • Gini(根蒂=1) = 1 - ()² - ()² = ____

加权平均 Gini(根蒂) = (4/6) × ____ + (2/6) × ____ = ____

基尼增益 = Gini(根节点) - Gini(根蒂) = ____

第 4 步:得出结论

  • 按“色泽”分裂的增益是 ____,按“根蒂”分裂的增益是 ____。
  • 决策树会优先选择 ____ 作为根节点(填“色泽”或“根蒂”),因为它的基尼增益更____(大/小)。

第 5 步:代码验证

 1import numpy as np
 2from sklearn.tree import DecisionTreeClassifier, plot_tree
 3import matplotlib.pyplot as plt
 4
 5X = np.array([[0,0], [0,1], [1,0], [1,1], [0,0], [1,0]])
 6y = np.array([0, 1, 1, 1, 0, 1])
 7
 8dt = DecisionTreeClassifier(random_state=42)
 9dt.fit(X, y)
10
11plt.figure(figsize=(8, 6))
12plot_tree(dt, feature_names=['色泽', '根蒂'], 
13          class_names=['坏瓜', '好瓜'], filled=True, rounded=True)
14plt.show()
15
16print(f"根节点分裂特征:{'色泽' if dt.tree_.feature[0] == 0 else '根蒂'}")

代码运行结果是否与你手动计算的结论一致?______(填“是”或“否”)

练习 3:“过拟合观察 —— 树深度对泛化的影响”

🎯 目标:通过在一个带噪声的数据集上训练不同深度的决策树,亲眼见证过拟合的发生。 📂 数据集sklearn.datasets.make_classification(自行生成含噪数据)

【详细操作步骤(Step-by-Step)】

第 1 步:生成含噪声数据

 1from sklearn.datasets import make_classification
 2from sklearn.model_selection import train_test_split
 3from sklearn.tree import DecisionTreeClassifier
 4from sklearn.metrics import accuracy_score
 5import matplotlib.pyplot as plt
 6import numpy as np
 7
 8# 生成 500 个样本,2 个特征(方便可视化),有重叠
 9X, y = make_classification(n_samples=500, n_features=2, n_redundant=0,
10                           n_clusters_per_class=1, class_sep=0.8,
11                           flip_y=0.08, random_state=42)
12X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
13
14plt.scatter(X[:, 0], X[:, 1], c=y, s=20, cmap='coolwarm', edgecolors='k')
15plt.title('含噪声的二分类数据')
16plt.show()

第 2 步:定义决策边界可视化函数

 1def plot_decision_boundary(model, X, y, title):
 2    x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
 3    y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
 4    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 200),
 5                         np.linspace(y_min, y_max, 200))
 6    Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
 7    Z = Z.reshape(xx.shape)
 8    plt.contourf(xx, yy, Z, alpha=0.3, cmap='coolwarm')
 9    plt.scatter(X[:, 0], X[:, 1], c=y, s=20, cmap='coolwarm', edgecolors='k')
10    plt.title(title)
11    plt.grid(True)

第 3 步:训练三个不同深度的决策树

 1depths = [2, 10, None]
 2fig, axes = plt.subplots(1, 3, figsize=(15, 4))
 3
 4for idx, depth in enumerate(depths):
 5    dt = DecisionTreeClassifier(max_depth=depth, random_state=42)
 6    dt.fit(X_train, y_train)
 7    
 8    train_acc = dt.score(X_train, y_train)
 9    test_acc = dt.score(X_test, y_test)
10    
11    plot_decision_boundary(dt, X_train, y_train, 
12                           f'max_depth={depth}\n训练集:{train_acc:.3f}, 测试集:{test_acc:.3f}')
13    axes[idx] = plt.gca()
14
15plt.tight_layout()
16plt.show()

第 4 步:回答以下问题

深度 训练集准确率 测试集准确率 判断(欠拟合/正常/过拟合)
max_depth=2 ____ ____ ______
max_depth=10 ____ ____ ______
max_depth=None ____ ____ ______
  1. 哪个深度的决策边界最简单(几乎是直线)?____
  2. 哪个深度的决策边界最曲折,在每个样本周围都形成小区域?____
  3. 对于这个含噪声的数据集,你建议使用哪个 max_depth?为什么?

练习 4:【独立实战】“随机森林 —— 决策树的救火队员”

🎯 目标:在同一个数据集上对比单棵决策树和随机森林,验证集成学习的抗过拟合能力。 📂 数据集sklearn.datasets.load_breast_cancer(乳腺癌二分类)

任务要求

  1. 加载数据:使用 load_breast_cancer,划分训练集和测试集(test_size=0.3, random_state=42)。

  2. 训练三个模型

    • 决策树(max_depth=None
    • 决策树(max_depth=4,预剪枝)
    • 随机森林(n_estimators=100
  3. 记录性能表格

模型 训练集准确率 测试集准确率 是否过拟合?
决策树(不限深度) ____ ____ ______
决策树(max_depth=4) ____ ____ ______
随机森林(100棵) ____ ____ ______
  1. 特征重要性对比

    • 提取决策树(不限深度)的 feature_importances_
    • 提取随机森林的 feature_importances_
    • 绘制两张柱状图(并排),观察两者的差异。
  2. 结论:随机森林的特征重要性相比单棵决策树,是更“平滑”还是更“极端”?这说明了什么?

练习 5:【独立实战】“随机森林调参 —— 树的数量与泛化能力”

🎯 目标:探究 n_estimators 对随机森林性能的影响,观察边际递减效应。 📂 数据集sklearn.datasets.make_moons(半月形数据,非线性)

任务要求

  1. 生成数据make_moons(n_samples=500, noise=0.15, random_state=42),划分训练/测试集。

  2. 训练随机森林:固定 max_depth=5,分别设置 n_estimators = [1, 5, 10, 20, 50, 100, 200]

  3. 记录并绘图

    • 横轴:n_estimators
    • 纵轴:训练集准确率 和 测试集准确率(两条曲线)
    • 观察两条曲线何时趋于稳定(收敛)。
  4. 训练时间记录

    • 使用 time.time() 记录每个 n_estimators 的训练耗时。
    • 绘制“n_estimators vs 训练耗时”折线图。
  5. 结论

    • 从准确率角度看,最优的 n_estimators 是多少?
    • 从训练时间角度看,性价比最高的 n_estimators 是多少?
    • 如果部署到生产环境,你会选择哪个 n_estimators?为什么?

练习 6:【独立实战】“XGBoost 入门 —— 安装、训练与参数初探”

🎯 目标:完成 XGBoost 的安装与基础训练,体验 Boosting 与 Bagging 的差异。 📂 数据集sklearn.datasets.load_wine(葡萄酒数据集,3 分类)

任务要求

  1. 环境准备:在终端或 Jupyter 中执行 pip install xgboost,确认安装成功。

  2. 加载数据:使用 load_wine,划分训练集和测试集。

  3. 训练三个模型(全部使用默认参数):

    • 决策树(DecisionTreeClassifier
    • 随机森林(RandomForestClassifiern_estimators=100
    • XGBoost(xgb.XGBClassifiern_estimators=100
  4. 记录性能表格

模型 训练集准确率 测试集准确率 训练耗时(秒)
决策树 ____ ____ ____
随机森林 ____ ____ ____
XGBoost ____ ____ ____
  1. learning_rate 实验

    • 固定 n_estimators=50,分别设置 learning_rate = [0.01, 0.05, 0.1, 0.3, 0.5, 0.9]
    • 记录每个学习率对应的测试集准确率。
    • 绘制“学习率 vs 测试集准确率”折线图。
    • 标注出最佳学习率。
  2. 回答

    • XGBoost 的训练耗时比随机森林____(快/慢),原因是______。
    • learning_rate 过小(如 0.01)会导致什么后果?______
    • learning_rate 过大(如 0.9)会导致什么后果?______

练习 7:【独立实战】“三模型擂台赛 —— 谁是最终的王者?”

🎯 目标:在同一个“硬”数据集上,同时对比 4 个模型,培养工程选型能力。 📂 数据集sklearn.datasets.make_classification(1000 个样本,5 个特征,含噪声)

任务要求

  1. 生成数据

    1X, y = make_classification(n_samples=1000, n_features=5, n_informative=4,
    2                           n_redundant=1, n_clusters_per_class=1,
    3                           flip_y=0.06, random_state=42)
  2. 训练以下 4 个模型(均使用默认参数):

    • 决策树(DecisionTreeClassifier
    • 决策树 + 剪枝(max_depth=6
    • 随机森林(RandomForestClassifiern_estimators=100
    • XGBoost(XGBClassifiern_estimators=100learning_rate=0.1
  3. 输出汇总表格(包含训练集准确率、测试集准确率、训练耗时):

模型 训练集准确率 测试集准确率 训练耗时(秒) 推断速度推断
决策树(不限深度) ____ ____ ____ 极快
决策树(max_depth=6) ____ ____ ____ 极快
随机森林 ____ ____ ____ 较快
XGBoost ____ ____ ____ 较快
  1. 选型建议
    • 如果项目要求“可解释性优先”,你选哪个?______
    • 如果项目要求“预测精度优先”,你选哪个?______
    • 如果项目要求“训练速度优先”,你选哪个?______
    • 如果项目要求“综合性价比最优”,你选哪个?______

Part B:不给定数据集的开放设计挑战(共 3 题)

练习 8:【造数据挑战】“信用卡欺诈检测 —— 极度不平衡数据下的决策树调优”

背景:某银行信用卡中心需要构建欺诈交易检测模型。真实业务中,欺诈交易占比通常低于 1%。你需要模拟这个场景,并训练决策树模型。

任务要求

  1. 自行构造不平衡数据

    • 使用 make_classification 生成 5000 个样本,2 个特征,正例(欺诈)占比设置为 2%(提示:使用 weights 参数)。
    • 添加适量噪声(flip_y=0.01)。
  2. 模型训练

    • 训练决策树(max_depth=None)和决策树(max_depth=4)。
    • 分别输出测试集上的 准确率(Accuracy)召回率(Recall,正例)
  3. 分析

    • 哪个模型在准确率上表现更好?哪个在召回率上表现更好?
    • 在欺诈检测场景中,准确率和召回率哪个更重要?为什么?
    • 你认为业务方更应该关注哪个指标?

练习 9:【综合设计挑战】“电商用户复购预测 —— 模型选型与交付”

背景:某电商平台要预测“用户在未来 30 天内是否会复购”。数据团队提供了 10 个特征(用户画像 + 历史行为),但业务方强调:模型必须能够输出“最重要的 3 个影响因素”,以便运营团队制定干预策略。

任务要求

  1. 自行生成数据

    • 10 个特征,2000 个样本,二分类。
    • 设置 2 个特征对标签有强影响(高重要性),其余为弱相关或噪声。
  2. 模型选型

    • 从决策树、随机森林、XGBoost 中选择 最合适的一个
    • 要求:训练后能输出特征重要性,且重要性排序稳定。
  3. 交付物

    • 输出最重要的 3 个特征名称及其重要性分数。
    • 将重要性绘制成柱状图(从高到低排序)。
    • 撰写 100 字以内的“业务建议”,说明运营团队应针对这 3 个特征采取什么行动。
  4. 扩展思考

    • 如果业务方说“我们想看具体的决策规则(if-else)”,你应该换成哪个模型?

练习 10:【综合设计挑战】“甲方需求书 —— 医疗辅助诊断系统”

背景:某三甲医院要开发一套“糖尿病风险筛查”辅助诊断系统。以下是甲方提出的需求(你作为乙方需要完成选型与交付)。

【甲方需求】

  1. 数据描述:数据集包含 8 个生理指标(如血糖、BMI、年龄等),共 2000 条记录,二分类(高风险/低风险)。
  2. 硬性约束
    • 诊断必须能在 0.5 秒内 给出结果(单条样本推断速度)。
    • 医生需要看到 决策路径(即“为什么判断该患者为高风险”),模型必须可解释。
    • 准确率 ≥ 88%。
  3. 软性要求:如果可能,最好能给出每个患者的具体“风险评分”(0~100 分),而不只是二分类。

任务要求

  1. 自行生成数据:使用 make_classification 生成符合 8 个特征、2000 个样本的数据集。

  2. 模型选型论证

    • 从决策树、随机森林、XGBoost、线性 SVM、RBF-SVM 中选择最合适的一个(或一组)。
    • 必须明确说明:选了谁,放弃了谁,为什么。
  3. 代码实现

    • 训练所选模型。
    • 测量单条样本的推断速度(< 0.5 秒必须达标)。
    • 输出测试集准确率(≥ 88% 必须达标)。
    • 提供可视化决策依据(树形图 / 特征重要性 / 规则提取)。
  4. 加分项

    • 如果模型能够输出“风险评分”(概率),额外加分。
    • 如果对模型进行了超参数调优(GridSearchCV),额外加分。

📌 练习时间指南

练习题 难度 建议课时 对应章节
练习 1 ★☆☆ 0.5 课时 决策树原理与可视化
练习 2 ★★☆ 0.5 课时 决策树原理与可视化
练习 3 ★★☆ 0.5 课时 决策树原理与可视化
练习 4 ★★☆ 1 课时 随机森林与集成思想
练习 5 ★★☆ 1 课时 随机森林与集成思想
练习 6 ★★★ 1 课时 XGBoost 视野扩展
练习 7 ★★★ 1.5 课时 综合
练习 8 ★★☆ 1 课时 决策树 + 随机森林
练习 9 ★★★ 1.5 课时 综合
练习 10 ★★★★ 2 课时 综合
  • 练习 1-3 为 课后作业 布置。
  • 练习 4-7 为 实训课任务
  • 练习 8-10 可能用于 期中/期末项目选题