简介
在本实验中,你将学习如何使用连续减半搜索方法,从多个候选参数中迭代地选择最佳参数组合。此方法在 Scikit-learn 库的 HalvingGridSearchCV 和 HalvingRandomSearchCV 类中实现。本实验将使用 HalvingRandomSearchCV 类。
虚拟机使用提示
虚拟机启动完成后,点击左上角切换到 笔记本 标签页,以访问 Jupyter Notebook 进行练习。
有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。
如果你在学习过程中遇到问题,请随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。
导入所需库
本实验将使用以下库:pandas、numpy、matplotlib、sklearn.datasets、RandomForestClassifier、randint 和 HalvingRandomSearchCV。使用以下代码导入它们:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.ensemble import RandomForestClassifier
from scipy.stats import randint
from sklearn.experimental import enable_halving_search_cv
from sklearn.model_selection import HalvingRandomSearchCV
加载数据集
sklearn.datasets 模块中的 make_classification 函数用于生成一个分类数据集。该数据集包含 400 个样本和 12 个特征。加载数据集的代码如下:
rng = np.random.RandomState(0)
X, y = datasets.make_classification(n_samples=400, n_features=12, random_state=rng)
定义参数空间
定义一个字典 param_dist,其中包含要搜索的超参数及其各自的值。超参数有 max_depth、max_features、min_samples_split、bootstrap 和 criterion。max_features 和 min_samples_split 的搜索范围使用 scipy.stats 模块中的 randint 函数定义。定义参数空间的代码如下:
param_dist = {
"max_depth": [3, None],
"max_features": randint(1, 6),
"min_samples_split": randint(2, 11),
"bootstrap": [True, False],
"criterion": ["gini", "entropy"],
}
创建一个减半随机搜索对象
创建一个 HalvingRandomSearchCV 对象,用于在参数空间中进行搜索。该对象接受以下参数:
estimator:要优化的估计器param_distributions:要搜索的参数空间factor:每次迭代中候选数量减少的因子random_state:用于搜索的随机状态
创建该对象的代码如下:
clf = RandomForestClassifier(n_estimators=20, random_state=rng)
rsh = HalvingRandomSearchCV(
estimator=clf, param_distributions=param_dist, factor=2, random_state=rng
)
拟合减半随机搜索对象
使用 fit 方法将 HalvingRandomSearchCV 对象拟合到数据集上。拟合该对象的代码如下:
rsh.fit(X, y)
分析结果
搜索对象的 cv_results_ 属性包含搜索结果。使用以下代码将其转换为 pandas 数据框:
results = pd.DataFrame(rsh.cv_results_)
通过将 params 列转换为字符串来创建 params_str 列。删除具有相同 params_str 和 iter 值的重复行:
results["params_str"] = results.params.apply(str)
results.drop_duplicates(subset=("params_str", "iter"), inplace=True)
然后,使用 pivot 方法根据迭代次数和参数组合对平均测试分数进行透视:
mean_scores = results.pivot(
index="iter", columns="params_str", values="mean_test_score"
)
最后,使用以下代码绘制迭代过程中的平均测试分数:
ax = mean_scores.plot(legend=False, alpha=0.6)
labels = [
f"iter={i}\nn_samples={rsh.n_resources_[i]}\nn_candidates={rsh.n_candidates_[i]}"
for i in range(rsh.n_iterations_)
]
ax.set_xticks(range(rsh.n_iterations_))
ax.set_xticklabels(labels, rotation=45, multialignment="left")
ax.set_title("Scores of candidates over iterations")
ax.set_ylabel("mean test score", fontsize=15)
ax.set_xlabel("iterations", fontsize=15)
plt.tight_layout()
plt.show()
结果解读
该图表展示了各候选方案在迭代过程中的平均测试分数。在第一次迭代时,所有候选方案都使用少量资源进行评估。在第二次迭代时,仅对表现最佳的一半候选方案使用两倍的资源进行评估。此过程会一直重复,直到最后一次迭代,此时仅剩下 2 个候选方案。最佳候选方案即为在最后一次迭代中平均测试分数最高的那个。
总结
在本实验中,你学习了如何使用连续减半搜索方法,从多个候选方案中迭代地选择最佳参数组合。我们使用了 Scikit-learn 库中的 HalvingRandomSearchCV 类来实现该搜索方法。通过绘制迭代过程中的平均测试分数图,对搜索结果进行了分析和解读。