模型选择的有利方法——随机搜索

前言

随机搜索是一种超参数调优的方法,用于在机器学习模型中找到最佳的超参数组合。相对于传统的网格搜索,随机搜索的主要特点是不按照预定的网格顺序搜索超参数空间,而是随机选择超参数的组合进行评估。以下是对随机搜索的解释:

无序采样:随机搜索不像网格搜索那样按照预定的步幅在超参数空间中采样。相反,它通过在整个超参数空间中进行随机抽样,以一种无序的方式来探索不同的超参数组合

灵活性:随机搜索更加灵活,因为它不受网格搜索那种必须按照预定步幅搜索的限制。这使得随机搜索能够更广泛地覆盖超参数空间,有助于找到潜在的最优解

计算效率:由于随机搜索在超参数空间中进行随机抽样,通常需要评估较少的超参数组合。这使得它在计算上相对更为高效,尤其是在超参数空间较大的情况下,相比于网格搜索,随机搜索的计算负担更轻

实证表现:研究表明,虽然随机搜索不保证找到全局最优解,但在实践中,它通常能够找到与网格搜索相媲美甚至更好的超参数组合。这意味着随机搜索在实际应用中可能是一种更有效的超参数优化策略

总体而言,随机搜索是一种更加灵活且计算效率较高的超参数调优方法,特别适用于超参数空间较大或者我们对超参数的先验信息有限的情况

Scikit-learn实现了随机搜索模型选择的方法:为此,我们可以使用sklearn.model_selection模块中的RandomizedSearchCV类。许多RandomizedSearchCV中的参数与GridSearchCV中的参数行为类似。尽管如此,在RandomizedSearchCV中,我们使用param_distributions代替GridSearchCV中的param_grid,而param_distributions与param_grid类似,可以是一个字典或一个字典列表。然而,每个字典中键的可能值甚至可以包括分布。在RandomizedSearchCV中可以使用的分布是任意的,只要它们提供了用于抽样的rvs()方法, 此外,param_distributions抽样的次数由n_iter参数确定

在超参数调整中经常使用的两个分布是均匀分布和对数均匀分布(也称为倒数分布),它们分别由scipy.stats中的uniform和loguniform实现。如果随机变量在范围[a, b]内的概率密度函数在该范围内是常数,否则为0,则该随机变量服从均匀分布。而如果其对数在[log(a), log(b)]内均匀分布,则该随机变量服从对数均匀分布。这很有用,因为有时我们知道参数的下限,但没有参数的上限(例如,逻辑回归中的C参数)。在这些情况下,如果需要离散网格,通常会取指数增长的值,例如0.01、0.1、1、10、100等。这是因为对于小值的超参数,固定变化可能比对于大值的相同变化更影响结果。在同样的情况下,如果不是离散网格而是一个范围,使用对数均匀分布可以确保在诸如[0.01, 0.1]、[0.1, 1]、[1, 10]等区间内的抽样是均匀的

代码实现

接下来利用鸢尾花实现这一过程:

加载鸢尾花数据集并划分为训练集和测试集。

创建了一个逻辑回归模型。

定义了超参数的搜索范围。

使用分层K折交叉验证和随机搜索进行超参数调优。

打印了最佳得分、最佳超参数组合和最佳估计器在测试数据上的准确度。

创建了一个包含交叉验证结果的DataFrame


          
import pandas as pd
          
from sklearn import datasets
          
from sklearn.linear_model import LogisticRegression as LRR
          
from sklearn.model_selection import RandomizedSearchCV, StratifiedKFold, train_test_split
          
from scipy.stats import loguniform, uniform
          

          
# 加载鸢尾花数据集
          
iris = datasets.load_iris()
          

          
# 划分训练集和测试集
          
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=100, test_size=0.2, stratify=iris.target)
          

          
# 打印数据形状信息
          
print('X_train_shape: ' + str(X_train.shape) + '\nX_test_shape: ' + str(X_test.shape)+ '\ny_train_shape: ' + str(y_train.shape) + '\ny_test_shape: ' + str(y_test.shape) + '\n')
          

          
# 创建逻辑回归模型
          
lrr = LRR(max_iter=2000)
          

          
# 定义超参数的分布范围
          
distrs = [{'penalty': ['l2'], 'C': loguniform(0.01, 100)},
          
          {'penalty': ['elasticnet'], 'C': loguniform(0.01, 100), 'l1_ratio': uniform(0, 1), 'solver': ['saga']}]
          

          
# 创建分层K折交叉验证对象
          
strkfold = StratifiedKFold(n_splits=3, shuffle=True, random_state=42)
          

          
# 创建随机搜索CV对象
          
gscv = RandomizedSearchCV(lrr, distrs, cv=strkfold, n_jobs=-1, scoring=['accuracy', 'roc_auc_ovr_weighted'],
          
                           refit='accuracy', n_iter=10, random_state=42)
          

          
# 拟合模型并计算测试数据上的得分
          
score_best_estimator = gscv.fit(X_train, y_train).score(X_test, y_test)
          

          
# 打印结果
          
print('最高得分是: {:.3f}'.format(gscv.best_score_))
          
print('最佳超参数组合是: {}'.format(gscv.best_params_))
          
print('最佳估计器在测试数据上的准确度是: {:.3f}'.format(score_best_estimator))
          

          
# 创建DataFrame以显示CV结果的相关信息
          
df = pd.DataFrame(gscv.cv_results_)
          
df.iloc[:, 4:9]
      

picture.image


          
import matplotlib.pyplot as plt
          
import seaborn as sns
          

          
# Visualize the hyperparameter search results
          
plt.figure(figsize=(12, 6))
          
sns.scatterplot(x='param_C', y='mean_test_accuracy', data=df, hue='param_penalty', palette='viridis', marker='o', s=100)
          
plt.xscale('log')
          
plt.title('Hyperparameter Search Results')
          
plt.xlabel('C (Inverse of regularization strength)')
          
plt.ylabel('Mean Test Accuracy')
          
plt.show()
      

picture.image

这个代码将创建一个散点图,显示“ C”超参数和平均测试精度之间的关系,不同的惩罚类型通过颜色加以区分。X 轴显示在一个对数尺度上,以便更好地可视化“ C”值的分布。

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

0
0
0
0
评论
未登录
暂无评论