正在加载中...

展开本页目录
算法教程GridRandomSearch-网格、随机搜索

GridRandomSearch-网格、随机搜索

No.140 · 在线教程

GridRandomSearch-网格、随机搜索 的真实核心主要位于:

GridRandomSearch-网格、随机搜索

1. 方法概述

GridRandomSearch-网格、随机搜索 的真实核心主要位于:

  • core/calculator.py
  • ui/upload_widget.py
  • ui/results_widget.py
  • ui/main_window.py

从代码实现看,这不是“任意算法的超参数自动搜索平台”,而是一个基于 sklearn 的有限模型族参数搜索器。它只支持 4 类模型:

  • svm
  • random_forest
  • knn
  • gboost

并支持两种搜索方式:

$$ \text{search\_method}\in\{\text{GridSearchCV},\ \text{RandomizedSearchCV}\} \tag{1} $$

设数据集为

$$ \mathcal{D}=\{(x_i,y_i)\}_{i=1}^{N} \tag{2} $$

程序先在训练集上做参数搜索,再用最优模型在测试集上计算分类或回归指标。

2. 数据约束与预处理

2.1 特征列与目标列

上传页允许用户:

  1. 选择一个目标列;
  2. 从“仅数值列可选”的复选框中勾选特征列。

设选中的特征集合为 \(S\),目标列为 \(y\),则进入建模的特征矩阵为

$$ X=\mathcal{D}[S] \tag{3} $$

代码会对选中列执行:

$$ X_{\text{num}}=\mathrm{to\_numeric}(X) \tag{4} $$

若出现非数值、空值或转换失败,则直接报错。

另外,如果用户把目标列也勾成了特征列,start_analysis() 会自动把它从特征列表里移除。

2.2 常数列与目标列约束

_prepare_data() 还会额外检查:

  1. 至少选择 1 个特征列;
  2. 特征列中不能出现标准差为 0 的常数列;
  3. 目标列不能为空。

分类任务时,代码会先做标签编码:

$$ y^{(\text{enc})}=\mathrm{LabelEncode}(y) \tag{5} $$

并要求:

  • 至少 2 个类别;
  • 每个类别至少 2 个样本。

回归任务时,目标列必须可转为数值,否则报错。

2.3 可选标准化

模型真正使用的是一个 Pipeline。当 normalize=True 时,管道为

$$ \hat x=\frac{x-\mu}{\sigma} \tag{6} $$

后接具体模型;当 normalize=False 时,则只保留 model 步骤。

这里有一个实现细节需要说明:标准化开关对 4 类模型都可见,包括树模型和 KNN;代码并不会因为模型类型不同而自动关闭该选项。

3. 模型族与参数网格

3.1 支持的模型

根据 _build_estimator(),分类与回归分别映射到如下 estimator:

  1. svm
    • 分类:SVC(probability=True)
    • 回归:SVR()
  2. random_forest
    • 分类:RandomForestClassifier
    • 回归:RandomForestRegressor
  3. knn
    • 分类:KNeighborsClassifier
    • 回归:KNeighborsRegressor
  4. gboost
    • 分类:GradientBoostingClassifier
    • 回归:GradientBoostingRegressor

因此该模块并不支持任意 sklearn 模型动态注入。

3.2 参数名会统一改写到 model__

由于 estimator 被包装在 Pipeline 里,参数网格会被自动归一化:

$$ \theta_j \mapsto \texttt{model\_\_}\theta_j \tag{7} $$

例如用户输入 {"C": [0.1, 1, 10]},实际传给 GridSearchCV 的是 {"model__C": [...]}

3.3 默认网格有 UI 版与 core 版两套

这里还有一个容易忽略的实现细节:

  1. 上传页会先把一套默认 JSON 网格写到文本框中;
  2. 若直接绕过 UI 调用 GridRandomSearchCalculatorparam_grid=None,则 core/calculator.py 还有另一套后备默认网格。

两套默认网格并不完全一致,所以“默认搜索范围”要区分是界面默认还是底层后备默认

4. 网格搜索与随机搜索

4.1 交叉验证目标

给定超参数 \(\theta\),代码使用交叉验证平均分作为目标值:

$$ f(\theta)=\frac{1}{K}\sum_{k=1}^{K}\mathrm{Score}\big(\mathcal{M}_{\theta},\mathcal{D}^{(k)}_{\text{train}},\mathcal{D}^{(k)}_{\text{valid}}\big) \tag{8} $$

其中 cv=K,并且 refit=True

评分映射由 UI 固定为:

  • 分类:accuracyf1_macrof1_weightedroc_auc_ovr
  • 回归:neg_root_mean_squared_errorneg_mean_absolute_errorr2

4.2 网格搜索

当搜索方式为 GridSearchCV 时,程序在用户给定网格 \(\Theta_{\text{grid}}\) 上枚举候选,并求

$$ \hat\theta=\arg\max_{\theta\in\Theta_{\text{grid}}} f(\theta) \tag{9} $$

这对应标准的穷举式网格搜索。

4.3 随机搜索

当搜索方式为 RandomizedSearchCV 时,程序执行 n_iter 次随机抽样。由于当前 UI 传入的参数网格通常是 JSON / Python 字典中的离散候选列表,因此其真实随机搜索更接近

$$ \theta^{(t)}\sim \mathrm{SampleFromListGrid}(\Theta),\qquad t=1,\dots,n_{\text{iter}} \tag{10} $$

而不是连续分布上的贝叶斯优化或自定义概率密度采样。

4.4 负指标会被转换成正向展示值

cv_results_ 整理阶段,代码会对负号评分做一次展示转换:

$$ s_{\text{display}}= \begin{cases} -s_{\text{cv}}, & \text{若 scoring 以 } \texttt{neg\_} \text{ 开头} \\ s_{\text{cv}}, & \text{否则} \end{cases} \tag{11} $$

因此:

  • 若评分是 neg_root_mean_squared_error,导出的 score_display 实际显示 RMSE;
  • 若评分是 neg_mean_absolute_error,导出的 score_display 实际显示 MAE。

但搜索器内部仍然是“最大化负分数”,这与“最小化 RMSE / MAE”等价。

5. 训练 / 测试划分与最终评估

5.1 数据拆分

参数搜索之前,程序先执行

$$ \mathcal{D}_{\text{train}}\cup\mathcal{D}_{\text{test}}=\mathcal{D} \tag{12} $$

其中:

  • test_size 取值要求在 0.050.5 之间;
  • 分类任务使用 stratify=y
  • 回归任务不分层;
  • cv 不能超过训练集样本数;
  • 分类任务中 cv 还不能超过训练集中最小类别样本数。

5.2 分类指标

分类任务最终并不只输出“搜索时使用的单一评分”,而是统一计算:

$$ \mathrm{Accuracy}=\frac{1}{|\mathcal{D}_{\text{test}}|}\sum_i \mathbf{1}(\hat y_i=y_i) \tag{13} $$

并额外导出:

  • precision_macro
  • recall_macro
  • f1_macro
  • f1_weighted

如果训练时做过 LabelEncoder,预测结果表中的 y_truey_pred 会再逆变换回原始类别文本。

这里还要注意:即使搜索评分选的是 roc_auc_ovr,最终导出的测试集指标表里也没有单独再算一次 ROC-AUC

5.3 回归指标

回归任务统一导出:

$$ \mathrm{RMSE}=\sqrt{\frac{1}{n}\sum_{i=1}^{n}(y_i-\hat y_i)^2} \tag{14} $$

$$ \mathrm{MAE}=\frac{1}{n}\sum_{i=1}^{n}|y_i-\hat y_i| \tag{15} $$

$$ R^2=1-\frac{\sum_i(y_i-\hat y_i)^2}{\sum_i(y_i-\bar y)^2} \tag{16} $$

同时预测结果表里还会附加一列:

$$ \text{residual}_i=y_i-\hat y_i \tag{17} $$

6. 输出结果、图表与复现

6.1 Excel 工作表

_export_excel() 实际输出:

  • Parameters
  • RawData
  • ProcessedData
  • CV_Results
  • BestParams
  • Metrics
  • Predictions
  • Charts

其中一个很关键的实现口径是:

  • ProcessedData = df[self.feature_cols + [self.target_col]]

也就是说,导出的 ProcessedData 只是“被选中的原始列”,并不是标准化之后真正送入模型的矩阵。

6.2 图表输出

图表保存在结果目录下的 plots/ 中,主要包括:

  1. top_scores.png
    • CV_Results 中前 20 个配置的 score_display 画横向条形图;
  2. 分类任务:confusion_matrix.png
  3. 回归任务:prediction_scatter.png
  4. 回归任务:residuals_hist.png

其中 top_scores.png 使用的是展示分数 score_display,所以在 RMSE / MAE 评分下,图上的数值是已经转正后的误差大小。

6.3 结果路径与复现脚本

如果用户没有自定义路径,UI 默认输出到:

  • results/grid_random_search_时间戳/grid_random_search_results.xlsx

结果页还会自动写出:

  • repro_grid_random_search.py

并把输入文件或当前数据副本复制到 repro_inputs/,供后续复跑 GridRandomSearchCalculator

7. 实现说明与注意事项

根据当前真实代码,论文说明中应明确以下边界:

  1. 这不是任意算法的通用搜索器,而是 4 类 sklearn 模型的参数搜索界面。
  2. 特征列必须全部可转为数值,且不能有空值、非法值或常数列。
  3. 标准化只是 Pipeline 的一个开关,导出的 ProcessedData 不反映标准化后的训练矩阵。
  4. 随机搜索通常是在离散候选列表上抽样,而不是连续分布上的复杂采样。
  5. 若搜索评分是 RMSE / MAE,其 CV_Results 和参数摘要里会把负分数翻转成正向展示值。
  6. 分类任务即使使用 roc_auc_ovr 做搜索,最终测试集指标表也不会再导出 ROC-AUC。

8. 论文写作模板

8.1 方法描述模板

“本文采用基于 sklearn 参数搜索框架的超参数寻优方法,对候选模型在离散参数空间内进行系统搜索。具体而言,网格搜索对参数组合进行穷举评估,随机搜索则在给定候选列表中随机抽取若干组参数,并统一以交叉验证分数作为模型选择依据。依据项目当前实现,搜索对象限定为 svmrandom_forestknngboost 四类模型,且参数名在进入搜索器前会统一改写为 model__* 形式。因此,论文中应同时说明模型类型、搜索方式、参数空间与交叉验证评分函数。”

8.2 结果解释模板

结果部分可写为:最优参数组合在交叉验证阶段取得了最高的综合评分,并在测试集上表现出较好的泛化能力。对于分类任务,可结合 Accuracy、Precision、Recall、F1 等指标分析模型识别效果;对于回归任务,则应结合 RMSE、MAE 与 \(R^2\) 评价预测误差与拟合优度。若搜索评分采用 RMSE 或 MAE 等误差型指标,需要进一步说明搜索器内部实际优化的是负误差分数,而导出结果中的 score_display 已转换为正向误差展示值,因此交叉验证最优分数与测试集误差指标的解释口径并不完全一致。

8.3 表格标题模板

  1. 表 1 网格搜索与随机搜索参数空间设置表
  2. 表 2 候选参数组合交叉验证结果汇总表
  3. 表 3 最优参数组合及测试集评价指标结果表
  4. 表 4 不同模型搜索结果对比表

8.4 图表题注模板

  1. 图 1 Top-N 候选参数组合交叉验证分数对比图。
  2. 图 2 最优模型在测试集上的预测效果图。
  3. 图 3 不同搜索策略下模型性能对比图。

8.5 表格示例

表 1 参数搜索最优结果汇总

项目 结果
模型类型
搜索方式 grid / random
最优参数组合
交叉验证最优分数
测试集指标

表注:候选参数组合得分来自 CV_Results 工作表;若采用误差型评分函数,应注明 score_display 为正向展示后的误差值。

9. 单篇终审补充

9.1 图题与表题对齐建议

当前 Grid/Random Search 模块的真实工作簿包含:

  • Parameters
  • RawData
  • ProcessedData
  • CV_Results
  • BestParams
  • Metrics
  • Predictions
  • Charts

其中 CV_Results 是最适合在论文中体现“参数搜索过程”的结果表,BestParamsMetrics 适合正文做最优结果汇总。不要把 ProcessedData 误写成标准化后的训练矩阵,当前实现导出的只是“被选中的原始列拼接结果”。

图文件保存在结果目录下的 plots/ 子目录,当前真实输出:

  • top_scores.png
  • 分类任务时:confusion_matrix.png
  • 回归任务时:prediction_scatter.png
  • 回归任务时:residuals_hist.png

因此图题应根据任务类型分别写,不要在同一份论文结果里同时声称程序一定导出了混淆矩阵和残差直方图。

9.2 终审说明

这篇文档最需要避免的误写,是把“随机搜索”描述成连续参数分布上的通用随机采样。当前真实实现更偏向在预定义候选列表上抽样,因此论文若强调搜索空间,应把它写成“离散候选参数集”更准确。

另外,当前 repro 脚本已经使用 repro_inputs/... 相对路径,结果目录中可见如 repro_inputs/grid_random_search_repro_data.csv 的输入引用。这篇可直接按新框架写可复现性。

9.3 全量强化补充

本篇终审补充绑定的真实算法目录为 具体的算法3/可解释与AutoML/GridRandomSearch-网格、随机搜索。该算法的 results 目录以 ui_flow_pytest_grid 为主结果池,目录内累积了多轮 UI 输出工作簿和一份 repro 再生产物,因此文档必须区分“最新主结果”与“repro 结果”。

本次优先绑定的主结果工作簿为 具体的算法3/可解释与AutoML/GridRandomSearch-网格、随机搜索/results/ui_flow_pytest_grid/grid_ui_results_1774775165.xlsx,同目录内还存在 具体的算法3/可解释与AutoML/GridRandomSearch-网格、随机搜索/results/ui_flow_pytest_grid/grid_random_search_repro.xlsx。两者实测工作表一致,均包含:

  • Parameters
  • RawData
  • ProcessedData
  • CV_Results
  • BestParams
  • Metrics
  • Predictions
  • Charts

因此当前目录里既有 UI 主结果池,也有脚本复现生成的 grid_random_search_repro.xlsx。论文或交付说明若只想引用“主运行结果”,应优先点名某一份 grid_ui_results_<timestamp>.xlsx;若要说明可复现性,再单独引用 grid_random_search_repro.xlsx,不能把两类结果混成一次导出。

当前目录中的真实图文件为:

  • 具体的算法3/可解释与AutoML/GridRandomSearch-网格、随机搜索/results/ui_flow_pytest_grid/plots/top_scores.png
  • 具体的算法3/可解释与AutoML/GridRandomSearch-网格、随机搜索/results/ui_flow_pytest_grid/plots/confusion_matrix.png

这一轮目录是分类任务结果池,因此当前图证据应写为“Top scores 图 + 混淆矩阵图”。同目录下并没有与这轮分类结果对应的 prediction_scatter.pngresiduals_hist.png,因此不能把回归图一并写进本轮结果说明。

复现实物方面,该目录实际包含:

  • 具体的算法3/可解释与AutoML/GridRandomSearch-网格、随机搜索/results/ui_flow_pytest_grid/repro_grid_random_search.py
  • 具体的算法3/可解释与AutoML/GridRandomSearch-网格、随机搜索/results/ui_flow_pytest_grid/repro_inputs/grid_random_search_repro_data.csv

脚本中明确写成 INPUT_FILE = 'repro_inputs/grid_random_search_repro_data.csv'OUTPUT_FILE = 'grid_random_search_repro.xlsx'。因此同目录下的 grid_random_search_repro.xlsx 应视为 repro 再生产物,而不是某一轮 UI 主结果。

10. 软件实现核查补充(2026-07)

  • 当前主结果目录应写作 具体的算法3/可解释与AutoML/GridRandomSearch-网格、随机搜索/results/ui_flow_pytest_grid
  • 正文应围绕 RawDataProcessedDataPredictionsBestParamsMetricsTrialsCharts 来写。
  • 图证应对应 top_scores.pngconfusion_matrix.png,并把分类结果与回归结果分开说明。
  • 复现脚本应按 repro_grid_random_search.py + repro_inputs/grid_random_search_repro_data.csv 的口径说明。