跳至内容

超参数调优:方法、最佳实践与示例

一份实用的超参数调优指南,涵盖其工作原理、主要搜索方法(网格、随机、贝叶斯)、评估策略,以及如何在 Python 与 R 中运行。
已更新 2026年10月6日  · 15分钟 阅读

使用 AI 探索

ChatGPTClaudePerplexity

模型准确率不佳并不是因为您选错了算法——而是因为您从未对它进行调优。

大多数人用默认设置训练一个模型,看到准确率徘徊在 80% 左右,就断言该算法不适合他们的任务。但算法不是问题所在。每个机器学习模型都有控制其学习方式的参数,这些参数在训练开始之前就已设定。如果设得合适,您可以在相同模型和相同数据上再多拿出 10%–20% 的准确率。

这些参数称为超参数。是否选得好,决定了模型只是“还行”还是“几乎总能答对”。超参数调优就是搜索能带来最佳性能的组合的过程。

本文将带您了解什么是超参数调优、哪些搜索策略最有效、如何在不自欺的情况下评估结果,以及如何在 Python 和 R 中完成这一切。

如果您是数据科学与机器学习新手,建议先学习Python 机器学习基础课程,再开展更高级的主题。

什么是超参数调优?

超参数调优是寻找能让模型学得最好的设置的过程。

每个机器学习模型都有两类数值。一类在训练过程中从数据中学习得到,比如神经网络中的权重,或决策树中的分裂点。另一类在训练开始前就设定好,即超参数。它们控制模型如何学习——多快、多深、是更应当泛化还是更倾向记忆。

默认超参数的存在是为了让模型跑起来,并非为了让它在您的特定数据集上达到最佳。一个适用于图像分类的默认学习率,逻辑上并不一定适合表格数据。对干净数据集尚可的默认树深度,在噪声较多的数据上会过拟合。道理就是这样。

调优的过程会在不同的超参数取值组合间搜索,对每个组合训练一个模型,并保留在验证数据上表现最好的那个。

通常,这带来的提升甚至优于切换到一个更“高级”但未调优的算法。

超参数 vs 模型参数

区别在于由谁、何时设定。

模型参数由算法在训练期间学习得到。您不会手动设置它们。训练过程通过查看数据并最小化损失函数来调整参数。例如:

  • 神经网络中的权重与偏置
  • 线性回归中的系数
  • 决策树中的分裂阈值
  • 支持向量机中的支持向量

超参数由您在训练开始前选择。它们控制学习过程的工作方式,但算法本身不会对其做任何调整。如果您不设置,库就会使用默认值。例如:

  • 梯度下降的学习率
  • 随机森林中的树的数量
  • 逻辑回归中的正则化强度
  • 支持向量机中的核函数类型

下面是并排对比:

  模型参数 超参数
设定者 训练算法 您
设定时机 训练期间 训练之前
是否从数据中学习 是 否
示例 权重、系数、分裂点 学习率、树深、正则化强度
不同运行间是否变化 每次重新训练都会变化 仅当您改变它们时才变化

模型参数回答“学到了什么”。超参数回答“如何去学”。

超参数调优如何工作

调优是一个循环。

您先选定要搜索的超参数,并为每个超参数定义一个取值范围。随后用某个取值组合训练模型,在验证数据上评估效果,再根据结果决定下一步尝试什么。

循环大致如下:

  1. 选择超参数并为每个确定一个取值范围。
  2. 训练模型,使用某个具体的取值组合。
  3. 评估性能,在验证集上使用与任务匹配的指标。
  4. 更新超参数,基于所得的经验——要么转到预定义列表中的下一个组合,要么用上一次的结果来指导下一次选择。
  5. 重复,直到性能不再提升或计算预算用尽。

迭代间如何更新,决定了不同搜索方法的区别。手动调优靠直觉更新;网格搜索依次遍历预定义列表;贝叶斯方法会建立一个关于哪些组合可能有效的模型来更新。

下面逐一介绍这些方法。

超参数搜索方法

您选择的搜索方法决定了计算消耗多少,以及找到好超参数的可能性有多大。

手动搜索

手动搜索是最简单的方法。您选定一组超参数,训练模型,查看结果,再基于所见进行调整。

当模型较小、超参数不多,且您对算法有经验时,这种方法可行。如果您已经知道 XGBoost 往往喜欢 0.05 左右的学习率和 6 的树深,就可以从这里开始,再根据观察调整。

当搜索空间变大时,手动搜索就不行了。三个超参数各有五个合理取值,就已经是 125 种组合了,没有人会手动调 125 个模型。

网格搜索

网格搜索会检查预定义取值列表中的每一种组合。

您定义一个网格——例如学习率取 [0.01, 0.05, 0.1],树深取 [3, 5, 7]——网格搜索就会为这九种组合各训练一个模型。它穷举且可复现。

问题在于计算成本。

再增加一个有五个取值的超参数,训练次数就会乘以五。网格搜索也会在不重要的取值上浪费精力——如果树深对分数几乎没影响,网格搜索仍会为您列出的每个深度训练一个模型。

对于只有两三个超参数的小搜索空间,网格搜索是不错的默认选择。

随机搜索

随机搜索会从取值范围中随机抽样组合,而不是按固定网格逐一遍历。

您为每个超参数定义一个分布,随机搜索就从这些分布中抽取组合。它比网格搜索更高效,因为不会在无关紧要的取值上浪费训练——如果三项超参数中只有一项影响性能,随机搜索仍会在很多不同取值上探索那一项重要超参数。

Grid search versus random search

网格搜索 vs 随机搜索

对于超参数多于两项的情况,随机搜索是更好的默认选择。

贝叶斯优化

贝叶斯优化会利用先前试验的结果来决定下一步尝试什么。

它构建一个关于“超参数组合如何映射到性能”的概率模型,然后选择下一个组合,该组合要么具有最高的期望得分,要么具有最高的不确定性。这就是探索与利用的权衡:要么探索可能不错的新区域,要么利用已知不错的区域。

与随机或网格搜索相比,贝叶斯方法用远更少的试验就能找到好的超参数。代价是每次试验会稍慢些,因为算法在选择下一个点前需要拟合其内部模型。Optuna 和 Hyperopt 等库可帮您完成这些。

当训练代价高昂、您只能负担少量运行时,使用贝叶斯优化。

逐次淘汰与 Hyperband

逐次淘汰与 Hyperband 通过及早停止表现差的运行来降低计算时间。

逐次淘汰会用较小的训练预算启动许多超参数组合,淘汰最差的一半,为留下来的组合将预算加倍,并重复上述过程。

Hyperband 是逐次淘汰的封装器,会用不同的预算划分多次运行,这样您就无需猜测正确的起始配置。

当训练很慢且搜索空间很大时,这两种方法都很有用。它们在“早期性能能够较好指示最终性能”的情形下效果最佳,如神经网络与梯度提升。

以下是各方法对比:

  计算成本 搜索效率 最佳适用场景
手动搜索 低 低 小型模型、具备先验经验
网格搜索 高 低 2–3 个超参数、小范围取值
随机搜索 中 中 4 个以上超参数、重要性未知
贝叶斯优化 中 高 训练代价高、预算小
逐次淘汰 / Hyperband 低到中 高 大搜索空间、训练缓慢

评估超参数性能

如果您不选择合适的取值范围,调优走不远。

如果评估方式有误,您会选错超参数。需要处理好四件事——如何划分数据、如何度量性能、优化哪个指标,以及如何保持测试集的“干净”。

训练集、验证集与测试集划分

在调优前,将数据分为三部分。

训练集用于模型学习。验证集用于在调优期间为每个超参数组合打分。测试集只在最后一次使用,用于衡量最终模型在未见数据上的表现。

如果您针对测试集调优,会得到一个看似很好的准确率数字,但模型在生产中的表现会打折。您基于测试集做的每个调优决策,都会将它的信息泄漏进模型。

常见的划分是中等规模数据集 60/20/20,或更大数据集 80/10/10。

交叉验证

当验证集偏小,交叉验证是一种更好的超参数打分方式。

将训练数据分为 k 折——通常为 5 或 10。对每个超参数组合,在 k-1 折上训练、在剩余一折上验证,然后轮换。最终分数是所有折的平均值。

交叉验证能更稳定地估计某个超参数组合的泛化能力,因为您不再依赖于某一次“幸运”或“不幸”的验证划分。代价是每个组合需要训练 k 个模型,而不是一个。

当数据集较小、单次验证划分不够可靠且您能负担额外训练成本时,使用交叉验证。

选择评估指标

您要优化的指标应与您真正关心的目标一致。

准确率适用于类别均衡的分类,但对不均衡问题就没意义。比如,一个把所有样本都预测为“非欺诈”的欺诈检测模型,准确率也能达到 99%,却漏掉所有实际案例。针对不均衡分类,用精确率、召回率、F1 或 ROC-AUC。针对回归,根据是否在意离群点,使用 RMSE、MAE 或 R 平方。

在开始调优前,选定一个主要指标并始终坚持使用它。

避免数据泄漏

当验证集或测试集的信息进入训练过程时,就发生了数据泄漏。

以下是一些常见情形:

  • 在划分前对全量数据做缩放/标准化,导致验证集统计量泄漏进训练
  • 特征工程使用了整个数据集的目标值
  • 针对测试集调优,而不是独立的验证集
  • 时间序列数据划分未遵守时间顺序

所有预处理步骤只在训练集上拟合,再应用到验证与测试。在 scikit-learn 中,这正是 Pipeline 的用途——将预处理与建模封装为一个对象,严格遵守数据划分。

实施超参数调优

大多数机器学习库都内置了搜索与交叉验证工具,您无需从零实现。

在 Python 中进行超参数调优

Scikit-learn 提供了两类覆盖大多数用例的调优类——用于网格搜索的 GridSearchCV 和用于随机搜索的 RandomizedSearchCV。二者可包裹任意 scikit-learn 估计器,对每个组合执行交叉验证,并最终返回最佳模型。

GridSearchCV 接收一个估计器、一个超参数取值字典以及交叉验证折数。它会为每个组合训练模型,并保留得分最高的那个。

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import make_classification

X, y = make_classification(n_samples=1000, random_state=42)

param_grid = {
    "n_estimators": [100, 200, 500],
    "max_depth": [5, 10, 20],
    "min_samples_leaf": [1, 5, 10],
}

grid = GridSearchCV(RandomForestClassifier(random_state=42), param_grid, cv=5)
grid.fit(X, y)

print(grid.best_params_)
print(grid.best_score_)

GridSearchCV results in Python

Python 中的 GridSearchCV 结果

RandomizedSearchCV 使用相同的接口,但会从分布中抽样,而非遍历固定列表。这让您在固定试验次数下覆盖更广范围。

from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint

param_dist = {
    "n_estimators": randint(100, 500),
    "max_depth": randint(3, 20),
    "min_samples_leaf": randint(1, 10),
}

random_search = RandomizedSearchCV(
    RandomForestClassifier(random_state=42),
    param_dist,
    n_iter=30,
    cv=5,
    random_state=42,
)
random_search.fit(X, y)

print(random_search.best_params_)

RandomizedSearchCV results in Python

Python 中的 RandomizedSearchCV 结果

对于贝叶斯优化,Optuna 是标准之选。它会基于以往结果选择下一个组合,因此当训练代价较高时,比随机搜索收敛更快。

import optuna
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

def objective(trial):
    params = {
        "n_estimators": trial.suggest_int("n_estimators", 100, 500),
        "max_depth": trial.suggest_int("max_depth", 3, 20),
        "min_samples_leaf": trial.suggest_int("min_samples_leaf", 1, 10),
    }
    model = RandomForestClassifier(**params, random_state=42)
    return cross_val_score(model, X, y, cv=5).mean()

study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=30)

print(study.best_params)

Optuna results in Python

Python 中的 Optuna 结果

trial.suggest_* 方法定义搜索空间,Optuna 根据目前看到的得分来决定下一步尝试的组合。

在 R 中进行超参数调优

R 有两个很棒的选择——caret 和 tidymodels。两者都能完成相同的事情——定义网格、运行交叉验证、返回最佳模型——但 tidymodels 是现代默认之选。

使用 caret,您将调优网格传给 train() 函数,并指定重采样方法。

library(caret)

data <- iris
ctrl <- trainControl(method = "cv", number = 5)

grid <- expand.grid(
  mtry = c(2, 3, 4)
)

model <- train(
  Species ~ .,
  data = data,
  method = "rf",
  trControl = ctrl,
  tuneGrid = grid
)

print(model$bestTune)

Caret results in R

R 中的 Caret 结果

tidymodels 将工作流程拆分为清晰的步骤——模型规范、预处理配方和调优网格。更为详尽,但在实践中更具可扩展性。

library(tidymodels)

data <- iris
split <- initial_split(data, prop = 0.8)
train_data <- training(split)

rf_spec <- rand_forest(
  mtry = tune(),
  trees = tune(),
  min_n = tune()
) |>
  set_engine("ranger") |>
  set_mode("classification")

grid <- grid_regular(
  mtry(range = c(2, 4)),
  trees(range = c(100, 500)),
  min_n(range = c(1, 10)),
  levels = 3
)

folds <- vfold_cv(train_data, v = 5)

results <- tune_grid(
  rf_spec,
  Species ~ .,
  resamples = folds,
  grid = grid
)

show_best(results, metric = "accuracy")

Tidymodels results in R

R 中的 Tidymodels 结果

该工作流程与 Python 完全一致——定义要搜索的内容、定义打分方式,然后交由库运行循环。

应该调哪些超参数?

不是每个超参数都值得调,因为通常只有少数几个主导性能。下面按模型家族列出通常最先要调的那些。

决策树与随机森林

这三个应始终调优:

  • 最大深度控制每棵树能长多深。树太浅会欠拟合,太深会过拟合。这通常是首要调的参数。
  • 每个叶节点的最小样本数,规定叶节点至少需要多少训练样本。取值越大,越强迫树去泛化而非记忆单行数据。
  • 随机森林中的树的数量。更多的树能带来更稳定的模型,但过了几百棵后回报递减。最后再调它。

梯度提升模型

梯度提升(XGBoost、LightGBM、CatBoost)对超参数比随机森林更敏感。关注这些:

  • 学习率控制每棵新树对前面树的纠正幅度。学习率越低往往越准确,但需要更多的树。这是最重要的超参数。
  • 估计器数量,即提升轮数。与学习率联动——降低一个,就提升另一个。
  • 树深控制单棵树的复杂度。与随机森林相比,提升通常偏好更浅的树,常见为 3 到 8。

支持向量机

对于 SVM,超参数选择影响很大,甚至可能超过其他模型:

  • C 控制“最大间隔”与“正确分类训练样本”的权衡。C 越大,正则化越弱。
  • Gamma 控制单个训练样本影响力延伸的距离。Gamma 低影响更远,Gamma 高影响更近。
  • 核函数决定 SVM 能学习到的决策边界形状。非线性问题从 rbf 开始,高维稀疏数据用 linear。

神经网络

神经网络在常见模型家族中拥有最大的搜索空间。先调这些:

  • 学习率是深度学习中最重要的超参数。过高会发散,过低又难以收敛。尝试数量级跨越的取值,如 1e-4、1e-3、1e-2。
  • 批量大小同时影响训练速度与最终准确率。更大的批量每个 epoch 训练更快,但往往泛化更差。
  • 优化器(Adam、带动量的 SGD、AdamW)决定网络如何更新权重。Adam 是不错的默认选择。
  • 训练轮数(Epochs)指模型看完整个训练集的次数。建议用早停而非手动调这个值。

超参数调优的常见挑战

调优很耗资源,尤其当您想为每个参数测试多个取值且参数很多时。以下是一些常见挑战。

计算成本是最大的约束。您尝试的每个组合都意味着训练一个完整模型,交叉验证还要将其乘以折数。一个包含 100 种组合且 5 折的网格就是 500 次拟合。如果每次拟合耗时 10 分钟,那就是三天多。

庞大的搜索空间呈乘法增长。五个超参数、每个五个取值就是 3,125 种组合。此时网格搜索已不现实,需要用随机搜索或贝叶斯方法替代。

边际收益递减往往比多数人预期来得更早。前几轮调优通常带来最大收益。后续 50 轮可能只再挤出 1% 的准确率提升。到某个节点,额外算力更值得花在获取更多数据或改进特征上。

准确率与时间的权衡在生产中比在开发中更重要。若一个模型高出 0.5% 的得分,却需要双倍训练时间,而您需要每日重训,那可能不值得。您应事先决定:多少准确率值得花多少算力。

超参数调优的最佳实践

调优机器学习模型的超参数时,建议遵循以下良好习惯:

  • 先调最具影响力的超参数: 提升和神经网络调学习率;决策树调最大深度;SVM 调 C 与 gamma。先把这些调整到合理范围,再处理其他。
  • 大搜索空间从随机搜索开始: 网格搜索会在不重要的超参数上浪费算力。随机搜索覆盖更全面,适合超参数多于两三个的情况。
  • 使用交叉验证: 单次验证划分可能运气好或差。五折能更诚实地估计某个组合的泛化能力。
  • 设定现实的搜索范围: 如果学习率范围是 [0.001, 100],您会在永远不奏效的取值上浪费时间。先用已知对该算法合理的范围,再基于观察逐步收窄。
  • 跟踪您的实验: 记录每次运行的超参数取值、得分与随机种子。MLflow、Weights & Biases,甚至 CSV 都可以。不做记录就无法复现结果。
  • 设定计算预算: 在开始前就决定您能负担的试验次数,而不是事后。这会迫使您选择匹配预算的搜索方法,并避免不必要的长时间调优。

超参数调优的常见错误

多数调优失败源于一些容易避免的错误。以下是几个例子:

  • 混淆超参数与模型参数。 权重与系数在训练中由算法学习。您不会手动设置、也不会去“调优”它们。如果您正尝试调某些本该由算法学习的东西,那就把两者混为一谈了。
  • 针对测试集调优。 您基于测试分数做的每个决定都会把它的信息泄漏进模型。最后得到的数字会过于乐观,生产表现会打折。请使用独立验证集或交叉验证。
  • 搜索不必要的大参数网格。 一个包含七个超参数、每个十个取值的网格共有一千万种组合。您无法搜索那么多。在开始前就先缩小范围,挑出两三个最关键的超参数,并给出合理的取值区间。
  • 优化了错误的指标。 在不均衡数据集上用准确率,会得到一个永远预测多数类的模型。选择能反映您真正关切的指标,并在开始调优前就确定它。
  • 手动调优时一次改动过多超参数。 如果您在同一步同时调整学习率与批量大小,就无法知道是哪一个导致了变化。手动调优时请一次只动一个。

超参数调优 vs 特征工程

两者都能提升模型,但发力点不同。

特征工程提升输入数据。您从现有特征中构造新特征、对类别变量编码、处理缺失值并去除噪声。更好的特征能为模型提供更有用的学习信号。

超参数调优则提升模型如何从给定特征中学习。它改变的是算法在数据上的行为,而不是改变数据本身。

两者相辅相成。项目早期、数据仍较原始且模型缺失明显信号时,特征工程通常带来最大收益。特征足够好后,超参数调优能带来更小但稳定的提升。

如果模型遇到瓶颈、不确定该先做哪一个,就看错误分析。如果模型错过了数据中看似显而易见的模式,是特征问题;如果过拟合或欠拟合,是调优问题。

为何超参数调优在机器学习中如此重要

调优是任何机器学习工作流中的标准步骤。

它常常比更换算法带来更大的收益。比如,在同一数据上,一个调优良好的随机森林往往能胜过一个调优糟糕的梯度提升模型,尽管后者更为复杂。

调优也有助于泛化。像最大深度、dropout 率这样的超参数,直接控制模型的过拟合程度。把这些设对,是区分“只会背训练集”与“在新数据上也表现良好”的关键。

在生产中,调优能将概念验证变成可靠的系统。

默认设置能让您起步,但并不能在重训与业务要求下保持模型的竞争力。每个严肃的机器学习团队都会把调优视为流程的一部分。

结语

超参数调优是围绕“搜索—评估—聚焦”的迭代循环,旨在找到适合您特定数据的有效方案。

最佳结果来自三者的结合——匹配您算力预算的搜索方法、能产出相关分数的验证方式,以及可回溯尝试历史的实验跟踪。

从随机搜索或网格搜索起步。当训练成本高到“试验次数本身很重要”时,转向贝叶斯优化。无论采用何法,都要调与您的模型相关的超参数,保持测试集干净,并记录每一次运行。

如果您考虑从事机器学习职业,欢迎报名我们的机器学习工程师学习路径,助您在 2026 年胜任岗位。


Dario Radečić's photo
Author
Dario Radečić
LinkedIn
常驻克罗地亚的高级数据科学家。顶级科技写作者,已发表 700 多篇文章,累计获得超过 1,000 万次阅读。著有《使用 TPOT 实现机器学习自动化》。

常见问题

什么是机器学习中的超参数调优?

超参数调优是寻找能让模型在您的数据上学得最好的设置的过程。超参数是在训练前设定的值,如学习率或树深,它们控制模型“如何学”,而非“学什么”。调优会在这些取值组合间搜索,选择在验证集上表现最佳的那一组。

为什么超参数调优很重要?

默认超参数能让模型跑起来,但不会针对您的具体问题做优化。调优通常比换用更复杂的算法带来更好的准确率提升,并且它直接影响模型对新数据的泛化能力。

超参数与模型参数有什么区别?

模型参数由算法在训练中学习得到——例如神经网络的权重或决策树的分裂点。超参数由您在训练前设定,控制学习如何进行,如学习率或树的数量。您不会手动调模型参数,算法也不会改动您的超参数。

我该用网格搜索还是随机搜索?

当搜索空间较小、只有两三个超参数且每个只有少量取值时,网格搜索即可。一旦超参数更多,随机搜索能在相同算力下更好地覆盖空间,因为它不会把运行浪费在不重要的取值上。经验法则是:当您对应试的取值有较强把握时用网格搜索;当没有时用随机搜索。

何时应使用贝叶斯优化而非随机搜索?

当训练代价高、每次试验都要耗费真实时间或金钱时,贝叶斯优化值得额外配置。它利用以往运行结果来决定下一步尝试,因此用远更少的试验就能找到很强的超参数。如果您能负担上百次快速训练,随机搜索更简单且通常够用;当试验次数被限制在几十次时,再选择贝叶斯方法。

主题
机器学习

与 DataCamp 一起学习

课程

Python 中的超参数调优

4 小时
25.4K
学习 Python 中的自动超参数调优技巧,包括网格搜索、随机搜索和智能搜索。
查看详情Right Arrow
开始课程
查看更多Right Arrow