查看全课大纲(第 99 / 101 节)
  1. 1.数据分析基本概念
  2. 2.学习数据分析的一般路线
  3. 3.数据分析的流程
  4. 4.数据类型
  5. 5.环境部署(1)
  6. 6.环境部署(2)
  7. 7.课程介绍
  8. 8.TXT文件操作
  9. 9.JSON文件操作
  10. 10.CSV文件操作
  11. 11.Excel文件操作
  12. 12.数据库及SQL常用语法
  13. 13.数据库基本操作
  14. 14.数据库多表连接
  15. 15.实战:欧洲职业足球数据库分析
  16. 16.爬虫简介
  17. 17.URL管理模块
  18. 18.网页下载模块
  19. 19.网页解析模块(1)
  20. 20.网页解析模块(2)
  21. 21.Scrapy简介
  22. 22.Scrapy使用步骤(1)
  23. 23.Scrapy使用步骤(2)
  24. 24.Scrapy使用步骤(3)
  25. 25.Scrapy使用步骤(4)
  26. 26.实战:获取国内城市空气质量指数数据
  27. 27.NumPy和SciPy介绍
  28. 28.多维数组
  29. 29.多维数组操作
  30. 30.NumPy的常用方法
  31. 31.向量化介绍
  32. 32.向量化及通用函数
  33. 33.实战:2016美国大选分析
  34. 34.数据结构-Series
  35. 35.数据结构-DataFrame
  36. 36.数据结构-Index
  37. 37.Series的索引操作
  38. 38.DataFrame的索引操作
  39. 39.索引操作总结
  40. 40.运算与对齐
  41. 41.函数应用操作(1) -- map
  42. 42.函数应用操作 (2) -- apply applymap
  43. 43.文件读写操作
  44. 44.排序操作
  45. 45.数据清洗--处理缺失数据
  46. 46.数据清洗--处理重复数据
  47. 47.数据清洗--替换数据
  48. 48.常用统计方法(1) -- describe quantile
  49. 49.常用统计方法(2) -- sum mean median count
  50. 50.常用统计方法(3) -- max min idxmax idxmin
  51. 51.常用统计方法(4) -- mad var std cumsum
  52. 52.实战:全球食品数据分析
  53. 53.层级索引
  54. 54.分组与聚合介绍
  55. 55.分组操作(1) -- GroupBy对象及常用聚合操作
  56. 56.分组操作(2) -- 自定义分组及聚合操作
  57. 57.透视表介绍
  58. 58.透视表操作
  59. 59.数据规整(1) -- 数据合并concat
  60. 60.数据规整(2) -- 数据连接merge
  61. 61.数据重构(3) -- 数据重构stack unstack
  62. 62.实战:互联网电影资料库分析
  63. 63.探索性数据分析EDA介绍
  64. 64.EDA的目的
  65. 65.EDA常用工具
  66. 66.Matplotlib绘图基本介绍
  67. 67.Matplotlib画布
  68. 68.散点图和柱状图的绘制
  69. 69.直方图的绘制
  70. 70.矩阵绘图
  71. 71.子图的使用
  72. 72.Matplotlib颜色、标记、线型
  73. 73.Matplotlib坐标刻度、标签、图例、标题
  74. 74.Seaborn介绍
  75. 75.数据集分布可视化(1) -- 单变量分布、双变量分布
  76. 76.数据集分布可视化(2) -- 变量关系可视化
  77. 77.类别数据可视化 -- 类别散布图、类别内数据分布、类别内统计图
  78. 78.交互式数据可视化工具Bokeh介绍
  79. 79.Bokeh绘制散点图、柱状图、盒子图、弦图
  80. 80.Bokeh绘制常用图形元素
  81. 81.3D绘图 -- mplot3d
  82. 82.3D曲线可视化
  83. 83.3D散点图可视化
  84. 84.3D柱状图可视化
  85. 85.Pandas绘图
  86. 86.实战:Lending Club借贷数据探索性分析及可视化
  87. 87.机器学习介绍及应用场景
  88. 88.机器学习建模介绍 (1) -- 分类
  89. 89.机器学习建模介绍 (2) -- 回归
  90. 90.机器学习建模介绍 (3) -- 聚类
  91. 91.机器学习分类
  92. 92.机器学习工具scikit-learn
  93. 93.使用scikit-learn的流程
  94. 94.数据集准备及划分
  95. 95.模型选择
  96. 96.数据预处理及特征工程
  97. 97.过拟合与欠拟合
  98. 98.模型调参介绍
  99. 99.模型调参方法
  100. 100.模型测试及评价
  101. 101.实战:通过移动设备行为数据预测性别和年龄

模型调参方法

约 13 分钟

📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)

小象实战讲义 · Python数据分析实战

在机器学习项目中,选择合适的模型参数(超参数)是提升模型性能的关键步骤。本节将介绍两种在scikit-learn中常用的模型调参方法:基于交叉验证的手动调参和自动化的网格搜索,帮助你系统化地找到最优参数组合,避免过拟合,提升模型的泛化能力。

💡 核心导读

  • 交叉验证调参原理:通过将训练集划分为多份,轮流作为验证集来评估不同参数下模型的性能,从而选择最优参数。
  • cross_val_score 手动调参:理解交叉验证的底层实现,手动遍历候选参数并评估。
  • 网格搜索 (GridSearchCV):自动化遍历多个参数的组合,通过交叉验证寻找全局最优解,大幅简化调参代码。
  • 调参实战流程:从候选参数定义、交叉验证评估到最终模型训练与测试的完整闭环。

交叉验证与手动调参

在上一节中,我们了解到交叉验证是评估模型泛化能力、防止过拟合的有效方法。在scikit-learn中,我们可以利用 cross_val_score 函数,基于交叉验证来评估不同参数下模型的性能。

其核心思想是:给定一个候选参数列表,对于每一个候选参数值,初始化一个模型,然后使用交叉验证计算该模型在训练集上的平均性能得分(如准确率)。最后,选择平均得分最高的参数作为最优参数。

下面的代码演示了这一完整过程。我们以K近邻分类器为例,调整其 n_neighbors (K值) 参数。

# 引入必要的库并构造示例数据
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.neighbors import KNeighborsClassifier

# 构造一个简单的分类数据集用于演示
# 特征X:20个样本,4个特征(模拟鸢尾花数据集结构)
np.random.seed(10) # 固定随机种子,确保示例可复现
X_demo = np.random.randn(20, 4)
# 标签y:20个样本,3个类别 (0, 1, 2)
y_demo = np.random.randint(0, 3, 20)

# K近邻模型的候选K值
k_candidates = [1, 3, 5, 7, 9]
print("使用三折交叉验证评估不同K值:")
print("-" * 40)

for k in k_candidates:
    # 初始化指定K值的模型
    knn_model = KNeighborsClassifier(n_neighbors=k)
    # 进行三折交叉验证,返回每折的得分
    val_scores = cross_val_score(knn_model, X_demo, y_demo, cv=3)
    # 计算三折得分的平均值作为该K值的性能评估
    val_score_mean = val_scores.mean()
    print(f'k={k}, 三折交叉验证平均准确率={val_score_mean:.4f}')
使用三折交叉验证评估不同K值:
----------------------------------------
k=1, 三折交叉验证平均准确率=0.1032
k=3, 三折交叉验证平均准确率=0.2143
k=5, 三折交叉验证平均准确率=0.4603
k=7, 三折交叉验证平均准确率=0.4524
k=9, 三折交叉验证平均准确率=0.4524

从输出可以看出,当 k=5 时,模型在交叉验证集上取得了最高的平均准确率(0.4603)。因此,我们选择 k=5 作为最优参数。

重要步骤回顾:

  1. 划分数据:示例中我们直接使用了全部数据 X_demo, y_demo 进行交叉验证。在实际项目中,应先将原始数据划分为训练集和测试集,调参过程只使用训练集。
  2. 交叉验证:cv=3 表示进行3折交叉验证。对于每个K值,模型会被训练和评估3次,最终返回3个得分。
  3. 计算与选择:对3个得分取平均值,代表该参数在当前数据上的泛化性能。选择平均分最高的参数。
  4. 最终训练:确定最优参数(k=5)后,需要使用整个训练集重新训练一个最终模型,再用独立的测试集评估其真实性能。

上述方法虽然清晰地展示了调参原理,但代码中包含了循环和手动计算平均值的步骤。当需要调整的参数不止一个时,代码会变得非常复杂。接下来,我们将介绍更强大的自动化工具。

网格搜索:自动化调参利器

网格搜索(Grid Search)是一种自动化超参数调优方法。它通过遍历给定的参数组合网格,对每一种组合使用交叉验证进行评估,最终返回性能最优的参数组合及对应的模型。

网格搜索的工作原理

假设一个模型有两个超参数 p1 和 p2:

  • p1 的候选值为 [1, 10, 100]
  • p2 的候选值为 [1000, 10000, 100000]

网格搜索会尝试所有可能的组合,共 3 × 3 = 9 种: (p1=1, p2=1000), (p1=1, p2=10000), …, (p1=100, p2=100000)。 对于每一种组合,都执行一次完整的交叉验证流程,并记录平均得分。最后,选择得分最高的那个参数组合作为最优解。

这种方法得名“网格”,因为当有两个参数时,候选值构成了一个二维网格,搜索过程就是遍历网格中的所有交点。参数越多,网格维度越高,组合数量呈指数级增长,计算成本也越大。

使用 GridSearchCV 实现调参

scikit-learn 提供了 GridSearchCV 类来方便地实现网格搜索。它将交叉验证和参数搜索封装在一起,代码简洁且功能强大。

# 使用 GridSearchCV 进行自动化网格搜索调参
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
import numpy as np

# 构造示例数据(与上一节保持一致,确保比较公平)
np.random.seed(10)
X_train_demo = np.random.randn(20, 4)
y_train_demo = np.random.randint(0, 3, 20)

# 1. 定义参数网格
# 键为参数名(必须与模型初始化参数名一致),值为候选值列表
param_grid = {'n_neighbors': [1, 3, 5, 7, 9]}

# 2. 初始化一个基础模型
base_knn = KNeighborsClassifier()

# 3. 初始化GridSearchCV对象
# 传入基础模型、参数网格、交叉验证折数
grid_search = GridSearchCV(estimator=base_knn,
                           param_grid=param_grid,
                           cv=3)

# 4. 在训练集上执行网格搜索
# 这一步会遍历所有参数组合,并进行交叉验证
grid_search.fit(X_train_demo, y_train_demo)

# 5. 查看最优参数
print(f"网格搜索找到的最优参数: {grid_search.best_params_}")
print(f"最优参数对应的交叉验证平均得分: {grid_search.best_score_:.4f}")
网格搜索找到的最优参数: {'n_neighbors': 5}
最优参数对应的交叉验证平均得分: 0.4603

可以看到,GridSearchCV 自动找到了最优参数 {'n_neighbors': 5},并且其最优得分 0.4603 与我们手动调参的结果完全一致——网格搜索本质上就是对每一种候选参数执行了我们刚才手动做的那套交叉验证流程,再自动挑出得分最高者。

获取最优模型与最终评估

GridSearchCV 有一个非常便利的特性:默认情况下(refit=True),它在找到最优参数后,会自动用这些最优参数在整个训练集上重新训练一个最终模型。这个模型可以通过 .best_estimator_ 属性直接获取。

# 获取网格搜索得到的最优模型并进行测试(每个代码块自包含:重建数据与网格搜索)
import numpy as np
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier

np.random.seed(10)
X_train_demo = np.random.randn(20, 4)
y_train_demo = np.random.randint(0, 3, 20)

param_grid = {'n_neighbors': [1, 3, 5, 7, 9]}
grid_search = GridSearchCV(estimator=KNeighborsClassifier(), param_grid=param_grid, cv=3)
grid_search.fit(X_train_demo, y_train_demo)

# 注意:这里为了演示最终评估,我们构造一个独立的“测试集”
np.random.seed(42) # 使用不同的种子,模拟独立数据
X_test_demo = np.random.randn(10, 4)
y_test_demo = np.random.randint(0, 3, 10)

best_model_from_grid = grid_search.best_estimator_
final_test_score = best_model_from_grid.score(X_test_demo, y_test_demo)
print(f"网格搜索得到的最优模型在测试集上的准确率: {final_test_score:.4f}")
网格搜索得到的最优模型在测试集上的准确率: 0.6000

代码解读与注意事项:

  • grid_search.best_estimator_ 已经是使用最优参数 (n_neighbors=5) 并在全部训练数据 (X_train_demo, y_train_demo) 上训练好的模型,可以直接用于预测或评估。
  • 测试集 (X_test_demo, y_test_demo) 是模型在训练和调参过程中从未见过的数据,用于模拟真实环境下的性能。示例中的准确率仅供参考——数据完全随机生成、没有实际规律,数值本身不具业务含义。
  • 重要:在实际项目中,必须严格区分训练集、验证集(交叉验证中产生)和测试集。测试集仅在最终评估时使用一次,以确保评估结果的公正性。

方法对比与工程实践建议

特性cross_val_score 手动循环GridSearchCV 网格搜索
代码复杂度较高,需自己写循环和结果记录低,API封装完善
可理解性高,一步步展示调参过程,利于学习原理中,底层过程被封装
多参数支持支持,但需要写多层循环,代码繁琐优秀,天然支持多参数网格搜索
功能完整性仅完成评估,需手动选择参数并重新训练完整,自动选择最优参数并重新训练 (refit=True)
适用场景教学演示,理解交叉验证调参原理工程实践,快速高效地进行超参数优化

工程实践建议:

  1. 理解原理:初学者建议先用 cross_val_score 手动实现一次,深入理解交叉验证调参的每一个步骤。
  2. 效率优先:在实际数据分析项目中,优先使用 GridSearchCV,它代码简洁,不易出错,且能处理复杂的多参数调优。
  3. 参数网格设计:对于连续型参数(如正则化系数C),可以尝试使用对数均匀分布(如 [0.001, 0.01, 0.1, 1, 10, 100])来设置候选值。scikit-learn 还提供了 RandomizedSearchCV(随机搜索)来处理更大的参数空间。
  4. 计算成本:网格搜索的计算量 = 参数组合数 × 交叉验证折数 × 模型训练时间。当参数组合很多时,计算成本会很高。需要根据实际情况权衡。

📝 动手练一练

  1. 概念辨析:在网格搜索中,如果将交叉验证的折数 cv 从 3 增加到 5,那么对于同一个有 5 个候选值的参数进行搜索,总共需要训练和评估模型多少次?这种增加会带来什么好处和代价?
👉 点击查看参考答案

参考答案:

  • 训练评估次数:参数候选值有5个,交叉验证折数为5。网格搜索会对每个参数值进行5折交叉验证。因此,总次数 = 5 (参数) × 5 (折) = 25 次模型的训练与评估。
  • 好处:增加交叉验证折数意味着每次评估时,验证集的数据量相对变小,训练集数据量变大,评估结果可能更稳定,对模型性能的估计可能更准确。
  • 代价:最直接的代价是计算时间显著增加。同时,更多的折数意味着更多的模型训练和验证循环,计算资源消耗更大。在实际中,通常根据数据集大小和计算资源在3、5、10折之间进行选择。
  1. 代码实践:假设你想为一个支持向量机分类器 (sklearn.svm.SVC) 调整两个参数:C (正则化参数,候选值 [0.1, 1, 10]) 和 kernel (核函数,候选值 ['linear', 'rbf'])。请写出定义参数网格 param_grid 的字典。
👉 点击查看参考答案

参考答案:

param_grid = {
    'C': [0.1, 1, 10],
    'kernel': ['linear', 'rbf']
}

这个网格将产生 3 (C) × 2 (kernel) = 6 种不同的参数组合供 GridSearchCV 进行搜索。

本章小结

本节我们深入探讨了机器学习模型调参的两种核心方法。交叉验证为我们提供了评估模型泛化能力的可靠框架,而基于此框架的网格搜索则实现了自动化、系统化的超参数优化,是提升模型性能不可或缺的工具。

📋 行动清单

  • 尝试手动调参:在一个小数据集上,使用 cross_val_score 手动编写循环,调整一个简单模型(如 KNeighborsClassifier)的参数,理解每一步的输出。
  • 应用网格搜索:使用 GridSearchCV 对同一个任务进行调参,对比两种方法的代码复杂度和结果,感受自动化调参的便捷。
  • 设计参数网格:为一个你感兴趣的模型(如 RandomForestClassifier),查阅其文档,找出2-3个关键超参数,并为其设计一个合理的候选值网格。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 本节课件:模型调参方法
    PDF · 127KB
    下载
  • 全套课件打包(第1-5章)
    ZIP · 12.8MB
    下载
  • 全套课件打包(第6-8章)
    ZIP · 15MB
    下载
  • 实战数据集:AppleStore 应用商城分析
    ZIP · 329KB
    下载
  • 实战数据集:女性服装电商分析
    ZIP · 2.8MB
    下载
  • Python 数据分析环境搭建指南
    PDF · 2MB
    下载
  • Scrapy 安装教程
    PDF · 12.7MB
    下载
  • 附加实战项目:AppleStore 应用商城数据分析
    ZIP · 0.3MB · ipynb + CSV 数据
    下载
  • 附加实战项目:银行电话营销数据分析
    ZIP · 0.4MB · ipynb + CSV 数据
    下载
  • 附加实战项目:女性服装电商评论数据分析
    ZIP · 2.7MB · ipynb + CSV 数据
    下载
  • 附加实战项目:美国化学学会杂志数据分析
    ZIP · 34.2MB · ipynb + SQLite 数据库
    下载