精华内容
下载资源
问答
  • 【机器学习】如何使用随机网格搜索,以缩短网格搜索速度?
    2022-03-01 15:24:55

    随机网格搜索RandomSearchCV学习笔记,内容包括:

    1. 随机网格搜索的基本原理
    2. 随机网格搜索的skelarn应用(案例:房价数据集_python)
    3. 随机网格搜索中连续型分布的应用(案例:房价数据集_python)
    • 索引

      🔣 函数及参数

      🔑 公式

      🗣 案例

      📌 名词解释

      📖 摘抄

    1 随机网格搜索的基本原理

    📖 影响枚举网格搜索运算速度的因素

    1 参数空间的大小:参数空间越大,需要建模的次数越多

    2 数据量的大小:数据量越大,每次建模时需要的算力和时间越多


    🗣 案例:全域参数空间VS部分参数空间(示意图)
    
    ```python
    n_e_list=range(50,350,50)
    m_d_list=range(2,7)
    
    comb=pd.DataFrame([(n_estimators, max_depth)
                       for n_estimators in n_e_list
                       for max_depth in m_d_list]) # 创建n_e_list和m_d_list的笛卡尔乘积
    
    fig,[ax1,ax2]=plt.subplots(1,2,dpi=100)
    ax1.scatter(comb.iloc[:,0],comb.iloc[:,1])
    ax1.set_title('GridSearch')
    
    ax2.scatter(comb.iloc[:,0],comb.iloc[:,1])
    ax2.scatter([50,250,200,200,300,100,150,150],[4,2,6,3,2,3,2,5],cmap='red',s=50)
    ax2.set_title('RandomSearch')
    plt.show()
    ```
    

    在这里插入图片描述


    📌 随机网格搜索
    随机抽取参数子空间,并在自空间中进行搜索的方法。

    对比枚举网格搜索的优势:

    • 运算速度快
    • 覆盖空间大
    • 最小损失与枚举网络的最小损失很接近

    📖 随机网格搜索的抽样特点

    随机网格搜索采用“循环迭代”。

    在这一次迭代中随机抽取1组参数进行建模,下一次迭代再随机抽取1组参数进行建模。由于这种随机抽样是不放回的,因此不会出现两次抽中同一组参数的问题。

    可以控制随机网格搜索的迭代次数,来控制整体被抽出的参数子空间的大小,这种做法往往被称为“赋予随机网格搜索固定的计算量,当全部计算量被消耗完毕之后,随机网格搜索就停止”。

    随机网格搜索在实际运行时,并不是先抽样出子空间,再对子空间进行搜索。


    2 随机网格搜索实现

    🔣 skelarn中随机网格搜索
    
    from sklearn.model_selection import RandomizedSearchCV
    
    RandomizedSearchCV(
        estimator, # 评估器
        param_distributions, # 全域参数空间
        *,
        n_iter=10, # 迭代次数
        scoring=None, # 评估指标
        n_jobs=None, 
        refit=True, # 是否挑选评估和最佳参数,在完整数据集上进行训练
        cv=None, # 交叉验证模式
        verbose=0,
        pre_dispatch='2*n_jobs', # 多任务并行时的任务划分数量
        random_state=None,
        error_score=nan, # 当网格搜索报错时返回结果,选择'raise'时将直接报错并中断训练过程,其他情况会显示警告信息后继续完成训练
        return_train_score=False, # 是否显示训练集中参数得分
    )
    
    NameDescription
    estimator调参对象,某评估器
    param_distributions全域参数空间,可以是字典或者字典构成的列表
    n_iter迭代次数,迭代次数越多,抽取的子参数空间越大
    scoring评估指标,支持同时输出多个参数
    n_jobs设置工作时参与计算的线程数
    refit挑选评估指标和最佳参数,在完整数据集上进行训练
    cv交叉验证的折数
    verbose输出工作日志形式
    pre_dispatch多任务并行时任务划分数量
    random_state随机数种子
    error_score当网格搜索报错时返回结果,选择’raise’时将直接报错并中断训练过程,其他情况会显示警告信息后继续完成训练
    return_train_score在交叉验证中是否显示训练集中参数得分

    🔣 案例:随机网格在随机森林上的应用_房价数据集

    📖 在相同的参数空间、模型下,随机网格搜索速度比普通网格搜索速度更快。
    运行时间≈n_iter/全域空间组合数*网格搜索
    
    from sklearn.ensemble import RandomForestRegressor as RFR
    from sklearn.model_selection import KFold
    
    param_grid_simple = {'n_estimators': range(50,150,10)
                        , 'max_depth': range(10,25,2)
                        , "max_features": ["sqrt",16,32,64,"auto"]
                        , "min_impurity_decrease": np.arange(0,5,2)
                       }
    
        #计算参数空间大小
        def count_space(param):
            no_option = 1
            for i in param_grid_simple:
                no_option *= len(param_grid_simple[i])
            print(no_option)
            
        count_space(param_grid_simple)
        
        # 训练模型
        model = RFR(random_state=7,verbose=True,n_jobs=4)
        cv = KFold(n_splits=5,shuffle=True,random_state=7)
        search = RandomizedSearchCV(estimator=model
                                    ,param_distributions=param_grid_simple
                                    ,n_iter = 600 #子空间的大小是全域空间的一半左右
                                    ,scoring = "neg_mean_squared_error"
                                    ,verbose = True
                                    ,cv = cv
                                    ,random_state=1412
                                    ,n_jobs=-1
                                   )
        
        search.fit(X,y)
        
        search.best_estimator_ # 查看模型参数结果
        # RandomForestRegressor(max_depth=18, max_features=16, min_impurity_decrease=0,
        #                       n_jobs=4, random_state=7, verbose=True)
        
        abs(search.best_score_)**0.5 # 查看模型RMSE分数
        # 29160.978459432965
        
        # 查看最优参数的模型效果
        from sklearn.model_selection import cross_validate
        ad_reg=RFR(max_depth=18
                   , max_features=16
                   , min_impurity_decrease=0
                   , random_state=7
                   , n_jobs=-1)
        
        def RMSE(cvresult,key):
            return (abs(cvresult[key])**0.5).mean()
        
        def rebuild_on_best_param(ad_reg):
            cv = KFold(n_splits=5,shuffle=True,random_state=7)
            result_post_adjusted = cross_validate(ad_reg,X,y
                                                  ,cv=cv
                                                  ,scoring="neg_mean_squared_error"
                                                  ,return_train_score=True
                                                  ,verbose=True
                                                  ,n_jobs=-1)
            print("训练RMSE:{:.3f}".format(RMSE(result_post_adjusted,"train_score")))
            print("测试RMSE:{:.3f}".format(RMSE(result_post_adjusted,"test_score")))
        
        rebuild_on_best_param(ad_reg)
        # 训练RMSE:10760.565
        # 测试RMSE:28265.808
    

    3 连续型参数空间

    📖 连续型可能来带更好的取值
    网格搜索:只能使用组合好的参数组合点;
    随机搜索:接受“分布”作为输入

    对于网格搜索,如果损失函数的最低点位于两组参数之间,在这种情况下,枚举网格搜索是不可能找到最小值的;
    对于随机网格搜索,由于是一段分布上随机选择参数点,因此在同样的参数空间中,取到更好的值的可能性更大。


    📖 当参数空间中包含某个分布的时候,无法估计全域参数空间的大小。


    📖 随机搜索中使用连续型分布的效果
    对比网格搜索,同样搜索空间下,运行速度更快,搜索与重建交叉验证结果RMSE略优;
    对比小空间网格搜索,运行时间较长,RMSE略优;
    对比大空间网格搜索,运行时间较长,RMSE略劣(模型效果不一定)。

    效果:连续型随机网格>大空间随机网格>随机网格>网格搜索
    运算速度:网格搜索>连续型随机网格>大空间随机网格>随机网格

    当枚举网格搜索所使用的全域参数空间足够大/足够密集时,枚举网格搜索的最优解是随机网格搜索的上限,因此理论上随机网格搜索不会得到比枚举网格搜索更好的结果


    🗣 案例:对min_impurity_decrease进行连续分布搜索

    param_grid_simple={'n_estimators':range(50,150,10)
                    ,'max_depth':range(10,25,2)
                    ,'max_features':range(10,20,2)
                    ,'min_impurity_decrease':scipy.stats.uniform(0,50)}
    
    model=RFR(random_state=7)
    cv=KFold(n_splits=5,shuffle=True,random_state=7)
    
    search=RandomizedSearchCV(estimator=model
                           ,param_distributions=param_grid_simple
                           ,n_iter=600
                           ,scoring='neg_mean_squared_error'
                           ,cv=cv
                           ,random_state=7
                           ,n_jobs=4)
    
    search.fit(X,y)
    
    search.best_estimator_
    # RandomForestRegressor(max_depth=18, max_features=16,
    #                       min_impurity_decrease=34.80143424780533, random_state=7)
    
    abs(search.best_score_)**0.5
    # 29155.5402993104
    
    rebuild_on_best_param(search.best_estimator_)
    # 训练RMSE:10733.842
    # 测试RMSE:28285.986
    
    更多相关内容
  • 如果您设置参数的上下限和间隔,框约束和核尺度,应用程序将搜索最佳参数集。
  • 本文介绍了如何使用网格搜索寻找网络的最佳超参数配置。 文章目录1. 准备数据集2. 问题建模2.1 训练集测试集拆分2.2 转化为监督学习问题2.3 前向验证2.4 重复评估2.5 网格搜索2.6 实例化3. 使用网格搜索寻找CNN最佳...
  • 将支持向量机(SVM)理论与网格搜索及交叉验证相结合,应用于梯级水电系统隐随机优化调度中,实现径流不确定条件下的梯级实际优化运行。以系统结构风险最小为SVM训练目标,结合参数分布规律,采用指数划分的网格搜索...
  • 比较了现今应用比较广泛的3种支持向量机( SVM)参数优化方法. 具体分析了网格法、遗传算法和粒子群算 法在 SVM参数优化方面的性能以及优缺点,... 实验表明改进的网格搜索法耗时短,更适用于有时间要求的说话人识别应用中.
  • 主要功能svm_grid_search使用以下参数执行网格搜索:要使用的内核名称,内核值,boxconstraint值和kktviolatonlevel级别的值。 它给出了带有训练过的 SVM 的输出数组,显示 SVM 是否无法训练(收敛)的数组,以及...
  • ML-DecisionTree-RandomForest-GridSearch-RandomizedGridSearch 机器学习-决策树,随机森林,网格搜索,随机网格搜索
  • 单台地震自动定位网格搜索法及其MATLAB试验.pdf
  • SIMPGRIDSEARCH 使用网格搜索 + 单纯形法的多维无约束非线性最小化。 X = SIMPGDSEARCH(OBJFUN,GDVALUES) 返回一个向量 X,它是 OBJFUN 中描述的函数(通常是一个 m 文件:OBJFUN.M)的最小值。 有关如何编写目标...
  • 网格搜索算法

    2018-04-23 19:55:40
    网格搜索算法,优化向量机。对于向量机的参数进行最优化处理
  • 比较了现今应用比较广泛的3种支持向量机(SVM)参数优化方法. 具体分析了网格法、遗传算法和粒子群算法在SVM参数优化方面的性能以及优缺点... 实验表明改进的网格搜索法耗时短,更适用于有时间要求的说话人识别应用中.
  • 网格搜索参数说明,数据集演示,当超参数过多,我们可以使用网格搜索一次性把最优的超参数组合列出来,skearn中超参数网格搜索方法grid Serach
  • svm 网格搜索

    2016-03-09 15:43:07
    SVM参数优化 网格搜索
  • 为了提高煤矿主扇风机故障诊断的准确性,将网格搜索法和支持向量机(SVM)应用到主扇风机的故障诊断中。首先,建立主扇风机运行故障的知识库,并将采集到的主扇风机振动信号进行小波消澡和归一化;然后,设计了网格搜索参数...
  • 搜索算法用于寻找从开始状态到目标状态的优化路径。 尽管存在一些缺点,但使用该算法可以解决大多数搜索问题。 D、D星、AD星是该算法的一些修改版本
  • 三 对半网格搜索HalvingSearchCV 基本原理 在讲解随机网格搜索之前,我们梳理了决定枚举网格搜索运算速度的因子: 1 参数空间的大小:参数空间越大,需要建模的次数越多 2 数据量的大小:数据量越大,每次建模时...

    三 对半网格搜索HalvingSearchCV

    • 基本原理

    在讲解随机网格搜索之前,我们梳理了决定枚举网格搜索运算速度的因子:

    1 参数空间的大小:参数空间越大,需要建模的次数越多
    2 数据量的大小:数据量越大,每次建模时需要的算力和时间越多

    面对枚举网格搜索过慢的问题,sklearn中呈现了两种优化方式:其一是调整搜索空间,其二是调整每次训练的数据。调整搜索空间的方法就是随机网格搜索,而调整每次训练数据的方法就是对半网格搜索。

    假设现在存在数据集𝐷,我们从数据集𝐷中随机抽样出一个子集𝑑。如果一组参数在整个数据集𝐷上表现较差,那大概率这组参数在数据集的子集𝑑上表现也不会太好。反之,如果一组参数在子集𝑑d上表现不好,我们也不会信任这组参数在全数据集𝐷上的表现。参数在子集与全数据集上反馈出的表现一致,如果这一假设成立,那在网格搜索中,比起每次都使用全部数据来验证一组参数,或许我们可以考虑只带入训练数据的子集来对超参数进行筛选,这样可以极大程度地加速我们的运算。

    但在现实数据中,这一假设要成立是有条件的,即任意子集的分布都与全数据集D的分布类似。当子集的分布越接近全数据集的分布,同一组参数在子集与全数据集上的表现越有可能一致。根据之前在随机网格搜索中得出的结论,我们知道子集越大、其分布越接近全数据集的分布,但是大子集又会导致更长的训练时间,因此为了整体训练效率,我们不可能无限地增大子集。这就出现了一个矛盾:大子集上的结果更可靠,但大子集计算更缓慢。对半网格搜索算法设计了一个精妙的流程,可以很好的权衡子集的大小与计算效率问题,我们来看具体的流程:

    1、首先从全数据集中无放回随机抽样出一个很小的子集𝑑0,并在𝑑0上验证全部参数组合的性能。根据𝑑0上的验证结果,淘汰评分排在后1/2的那一半参数组合

    2、然后,从全数据集中再无放回抽样出一个比𝑑0大一倍的子集𝑑1,并在𝑑1上验证剩下的那一半参数组合的性能。根据𝑑1上的验证结果,淘汰评分排在后1/2的参数组合

    3、再从全数据集中无放回抽样出一个比𝑑1大一倍的子集𝑑2,并在𝑑2上验证剩下1/4的参数组合的性能。根据𝑑2上的验证结果,淘汰评分排在后1/2的参数组合……

    持续循环。如果使用S代表首次迭代时子集的样本量,C代表全部参数组合数,则在迭代过程中,用于验证参数的数据子集是越来越大的,而需要被验证的参数组合数量是越来越少的:

    备选参数组合只剩下一组,或剩余可用的数据不足,循环就会停下,具体地来说,当(1/n)*C <= 1或者nS > 总体样本量,搜索就会停止。在实际应用时,哪一种停止条件会先被触发,需要看实际样本量及参数空间地大小。同时,每次迭代时增加的样本量、以及每次迭代时不断减少的参数组合都是可以自由设定的。

    在这种模式下,只有在不同的子集上不断获得优秀结果的参数组合能够被留存到迭代的后期,最终选择出的参数组合一定是在所有子集上都表现优秀的参数组合。这样一个参数组合在全数据上表现优异的可能性是非常大的,同时也可能展现出比网格/随机搜索得出的参数更大的泛化能力。

    • 对半网格搜索的局限性

    然而这个过程当中会存在一个问题:子集越大时,子集与全数据集D的分布会越相似,但整个对半搜索算法在开头的时候,就用最小的子集筛掉了最多的参数组合。如果最初的子集与全数据集的分布差异巨大的化,在对半搜索开头的前几次迭代中,就可能筛掉许多对全数据集D有效的参数,因此对半网格搜索最初的子集一定不能太小

    在对半网格搜索过程中,子集的样本量时呈指数级增长:

    n = 10
    for i in range(15):
        print(i,n*3**i)
    #0 10
    #1 30
    #2 90
    #3 270
    #4 810
    #5 2430
    #6 7290
    #7 21870
    #8 65610
    #9 196830
    #10 590490
    #11 1771470
    #12 5314410
    #13 15943230
    #14 47829690

    在初始子集样本量为10的前提下,7、8次迭代就会消耗掉2500+数据资源。在初始子集一定不能太小、且对半搜索的抽样是不放回抽样的大前提下,整体数据的样本量必须要很大从经验来看,对半网格搜索在小型数据集上的表现往往不如随机网格搜索与普通网格搜索,事实上,如果我们在Kaggle房价数据集上使用对半网格搜索,会发现其搜索结果还不如枚举网格搜索、且搜索时间长于之前我们尝试过的任何一种搜索方式。但在大型数据集上(比如,样本量过w的数据集上),对半网格搜索则展现出运算速度和精度上的巨大优势。

    因此在对半网格搜索实现时,我们使用一组拓展的房价数据集,有2w9条样本。

    data2 = pd.read_csv(r"D:\Pythonwork\2021ML\PART 2 Ensembles\datasets\House Price\big_train.csv",index_col=0)
    X = data2.iloc[:,:-1]
    y = data2.iloc[:,-1]
    X.shape
    #(29062, 80)
    y.describe()
    #count     29062.000000
    #mean     182798.864703
    #std       72379.404452
    #min       34900.000000
    #25%      139000.000000
    #50%      169092.000000
    #75%      203009.750000
    #max      755000.000000
    #Name: SalePrice, dtype: float64
    X.head()

    • 对半网格搜索的实现

    在sklearn当中,我们可以使用HalvingGridSearchCV类来实现对半网格搜索。Halving搜索是sklearn 1.0.1版本才新增的功能,因此现在该功能还处于实验阶段,在导入该类的时候需要同时导入用以开启对半网格搜索的辅助功能enable_halving_search_cv。当且仅当该功能被导入时,HalvingGridSearchCV才能够被导入和使用。

    import re
    import sklearn
    import numpy as np
    import pandas as pd
    import matplotlib as mlp
    import matplotlib.pyplot as plt
    import time
    from sklearn.ensemble import RandomForestRegressor as RFR
    from sklearn.experimental import enable_halving_search_cv
    from sklearn.model_selection import KFold, HalvingGridSearchCV, cross_validate, RandomizedSearchCV

    对半网格搜索的类如下所示:

    class sklearn.model_selection.HalvingGridSearchCV(estimator, param_grid, *, factor=3, resource='n_samples', max_resources='auto', min_resources='exhaust', aggressive_elimination=False, cv=5, scoring=None, refit=True, error_score=nan, return_train_score=True, random_state=None, n_jobs=None, verbose=0)

    全部参数如下所示:

    • factor

    每轮迭代中新增的样本量的比例,同时也是每轮迭代后留下的参数组合的比例。例如,当factor=2时,下一轮迭代的样本量会是上一轮的2倍,每次迭代后有1/2的参数组合被留下。如果factor=3时,下一轮迭代的样本量会是上一轮的3倍,每次迭代后有1/3的参数组合被留下。该参数通常取3时效果比较好。

    • resource

    设置每轮迭代中增加的验证资源的类型,输入为字符串。默认是样本量,输入为"n_samples",也可以是任意集成算法当中输入正整数的弱分类器,例如"n_estimators"或者"n_iteration"。

    • min_resource

    首次迭代时,用于验证参数组合的样本量r0。可以输入正整数,或两种字符串"smallest" ,"exhaust"。
    输入正整数n,表示首次迭代时使用n个样本。
    输入"smallest",则根据规则计算r0:

    当资源类型是样本量时,对回归类算法,r0 = 交叉验证折数n_splits * 2
    当资源类型是样本量时,对分类算法,r0 = 类别数量n_classes_ * 交叉验证折数n_splits * 2
    当资源类型不是样本量时,等于1

    输入"exhaust",则根据迭代最后一轮的最大可用资源倒退r0。例如,factor=2, 样本量为1000时,一共迭代3次时,则最后一轮迭代的最大可用资源为1000,倒数第二轮为500,倒数第三轮(第一轮)为250。此时r0 = 250。"exhaust"模式下最有可能得到好的结果,不过计算量会略大,计算时间会略长。

    现在,我们依然使用网格搜索最初的,空间大小为1536的参数空间:

    param_grid_simple = {"criterion": ["squared_error","poisson"]
                         , 'n_estimators': [*range(20,100,5)]
                         , 'max_depth': [*range(10,25,2)]
                         , "max_features": ["log2","sqrt",16,32,64,"auto"]
                         , "min_impurity_decrease": [*np.arange(0,5,10)]
                        }
    
    count_space(param_grid_simple)
    #1536
    
    X.shape
    #(29062, 80)

    哪一种停止条件会被触发?

    #2.9w个样本在factor=2, min_resource = 100的情况下可以迭代多久?
    for i in range(100):
        if 100*2**i > 29062:
            break
        print(i+1,100*2**i)
    #1 100
    #2 200
    #3 400
    #4 800
    #5 1600
    #6 3200
    #7 6400
    #8 12800
    #9 25600
    
    #1536种参数组合在factor=2的情况下可以迭代多久?
    for i in range(100):
        if 1536//2**i < 1:
            break
        print(i+1,int(1536//2**i+1)) #向上取整
    #1 1537
    #2 769
    #3 385
    #4 193
    #5 97
    #6 49
    #7 25
    #8 13
    #9 7
    #10 4
    #11 2

    不难发现,当factor=2的时候,数据集不足的条件会先被触发,最多只能迭代9次。也就是说,最终我们将在7组参数中选择表现最好的一组参数,而不会一直让搜索持续直到找出唯一最优的参数。如果我们无论如何都希望能够找到唯一最后的参数,那我们可以使用下面的参数:

    • aggressive_elimination

    输入布尔值,默认False。当数据总样本量较小,不足以支撑循环直到只剩下最后一组备选参数时,可以打开该参数。

    参数设置为True时,会重复使用首次迭代时的样本量,直到剩下的数据足以支撑样本量的增加直到只剩下最后一组备选参数
    参数设置为False时,以全部样本被用完作为搜索结束的指标

    对于对半网格搜索应用来说,最困难的部分就是决定搜索本身复杂的参数组合。在调参时,如果我们希望参数空间中的备选组合都能够被充分验证,则迭代次数不能太少(例如,只迭代3次),因此factor不能太大。但如果factor太小,又会加大迭代次数,同时拉长整个搜索的运行时间。同时,迭代次数还会影响我们最终能够使用的数据量,以及迭代完毕之后我们还需进一步验证的参数组合数量,两者都不能太少。因此,我们一般在使用对半网格搜索时,需考虑以下三个点:

    1、min_resources的值不能太小,且在全部迭代过程结束之前,我们希望使用尽量多的数据
    2、迭代完毕之后,剩余的验证参数组合不能太多,10以下最佳,如果无法实现,则30以下也可以接受
    3、迭代次数不能太多,否则时间可能会太长

    factor = 1.5
    n_samples = X.shape[0]
    min_resources = 500
    space = 1536
    
    for i in range(100):
        if (min_resources*factor**i > n_samples) or (space/factor**i < 1):
            break
        print(i+1,"本轮迭代样本:{}".format(min_resources*factor**i)
              ,"本轮验证参数组合:{}".format(space//factor**i + 1))
    # 1 本轮迭代样本:500.0 本轮验证参数组合:1537.0
    # 2 本轮迭代样本:750.0 本轮验证参数组合:1025.0
    # 3 本轮迭代样本:1125.0 本轮验证参数组合:683.0
    # 4 本轮迭代样本:1687.5 本轮验证参数组合:456.0
    # 5 本轮迭代样本:2531.25 本轮验证参数组合:304.0
    # 6 本轮迭代样本:3796.875 本轮验证参数组合:203.0
    # 7 本轮迭代样本:5695.3125 本轮验证参数组合:135.0
    # 8 本轮迭代样本:8542.96875 本轮验证参数组合:90.0
    # 9 本轮迭代样本:12814.453125 本轮验证参数组合:60.0
    # 10 本轮迭代样本:19221.6796875 本轮验证参数组合:40.0
    # 11 本轮迭代样本:28832.51953125 本轮验证参数组合:27.0
    
    #建立回归器、交叉验证
    reg = RFR(random_state=1412,verbose=True,n_jobs=-1)
    cv = KFold(n_splits=5,shuffle=True,random_state=1412)
    
    #定义对半搜索
    search = HalvingGridSearchCV(estimator=reg
                                ,param_grid=param_grid_simple
                                ,factor=1.5
                                ,min_resources=500
                                ,scoring = "neg_mean_squared_error"
                                ,verbose = True
                                ,random_state=1412
                                ,cv = cv
                                ,n_jobs=-1)
    #训练对半搜索评估器
    #=====【TIME WARNING: 30~50min】=====#
    start = time.time()
    search.fit(X,y)
    end = time.time() - start
    print(end/60)
    # n_iterations: 11
    # n_required_iterations: 19
    # n_possible_iterations: 11
    # min_resources_: 500
    # max_resources_: 29062
    # aggressive_elimination: False
    # factor: 1.5
    # ----------
    # iter: 0
    # n_candidates: 1536
    # n_resources: 500
    # Fitting 5 folds for each of 1536 candidates, totalling 7680 fits
    # ----------
    # iter: 1
    # n_candidates: 1024
    # n_resources: 750
    # Fitting 5 folds for each of 1024 candidates, totalling 5120 fits
    # ----------
    # iter: 2
    # n_candidates: 683
    # n_resources: 1125
    # Fitting 5 folds for each of 683 candidates, totalling 3415 fits
    # ----------
    # iter: 3
    # n_candidates: 456
    # n_resources: 1687
    # Fitting 5 folds for each of 456 candidates, totalling 2280 fits
    # ----------
    # iter: 4
    # n_candidates: 304
    # n_resources: 2531
    # Fitting 5 folds for each of 304 candidates, totalling 1520 fits
    # ----------
    # iter: 5
    # n_candidates: 203
    # n_resources: 3796
    # Fitting 5 folds for each of 203 candidates, totalling 1015 fits
    # ----------
    # iter: 6
    # n_candidates: 136
    # n_resources: 5695
    # Fitting 5 folds for each of 136 candidates, totalling 680 fits
    # ----------
    # iter: 7
    # n_candidates: 91
    # n_resources: 8542
    # Fitting 5 folds for each of 91 candidates, totalling 455 fits
    # ----------
    # iter: 8
    # n_candidates: 61
    # n_resources: 12814
    # Fitting 5 folds for each of 61 candidates, totalling 305 fits
    # ----------
    # iter: 9
    # n_candidates: 41
    # n_resources: 19221
    # Fitting 5 folds for each of 41 candidates, totalling 205 fits
    # ----------
    # iter: 10
    # n_candidates: 28
    # n_resources: 28832
    # Fitting 5 folds for each of 28 candidates, totalling 140 fits
    # [Parallel(n_jobs=-1)]: Using backend ThreadingBackend with 16 concurrent workers.
    # [Parallel(n_jobs=-1)]: Done  18 tasks      | elapsed:    0.4s
    # 25.638246742884316
    # [Parallel(n_jobs=-1)]: Done  90 out of  90 | elapsed:    1.2s finished
    
    #查看最佳评估器
    search.best_estimator_
    #RandomForestRegressor(max_depth=22, max_features=16, min_impurity_decrease=0,
    #                      n_estimators=90, n_jobs=-1, random_state=1412,
    #                      verbose=True)
    
    #查看最佳评估器
    abs(search.best_score_)**0.5
    #1068.281607238587
    
    #验证最佳参数组合的效力
    rebuild_on_best_param(search.best_estimator_)
    #训练RMSE:475.740
    #测试RMSE:1082.916

    以随机网格搜索作为对比,我们来看看随机网格搜索的结果:

    param_grid_simple = {"criterion": ["squared_error","poisson"]
                         , 'n_estimators': [*range(20,100,5)]
                         , 'max_depth': [*range(10,25,2)]
                         , "max_features": ["log2","sqrt",16,32,64,"auto"]
                         , "min_impurity_decrease": [*np.arange(0,5,10)]
                        }
    
    reg = RFR(random_state=1412,verbose=True,n_jobs=-1)
    cv = KFold(n_splits=5,shuffle=True,random_state=1412)
    
    #定义随机搜索
    search = RandomizedSearchCV(estimator=reg
                                ,param_distributions=param_grid_simple
                                ,n_iter = 800 #使用全域空间的一半作为子空间
                                ,scoring = "neg_mean_squared_error"
                                ,verbose = True
                                ,random_state=1412
                                ,cv = cv
                                ,n_jobs=-1)
    
    #训练随机搜索评估器
    #=====【TIME WARNING: 1个半小时~2小时】=====#
    start = time.time()
    search.fit(X,y)
    end = time.time()-start
    print(end/60)
    #103.20144965251286
    
    #查看最佳评估器
    search.best_estimator_
    #RandomForestRegressor(max_depth=24, max_features=16, min_impurity_decrease=0,
    #                      n_estimators=85, n_jobs=-1, random_state=1412,
    #                      verbose=True)
    #查看最终评估指标
    abs(search.best_score_)**0.5
    #1055.5552571413887
    #验证最佳参数组合的效力
    rebuild_on_best_param(search.best_estimator_)
    #训练RMSE:465.198
    #测试RMSE:1054.359

    可以看到,随机网格搜索的结果略微占优,但能够尝试的参数组合只有800个,且耗费的时间是对半搜索的4倍(1小时45分钟)。对于对半搜索,我们可以继续精细化调整整体的参数空间,进一步寻找更优的参数,但面对上万样本量的数据集,随机搜索的运算速度不足以支撑精细化调参,就更别提网格搜索了。之后,我们会给大家更详细地讲解更快速、更高效的优化方法。 

    展开全文
  • 一种改进的网格搜索法在基于PCA和SVM人脸识别技术中的应用,张龙,马敏,近年来,PCA和SVM算法因其在人脸识别中表现出的良好识别率而倍受关注。PCA通过特征提取能够达到降维的目的,SVM作为统计模式识别领域
  • 采用的是美国西储大学轴承数据中心的滚动轴承数据,贝叶斯优化后的准确率高达99%,也包含了和遗传算法以及网格搜索优化支持向量机的对比!希望可以帮助到大家!!!给两个积分意思一下就行了
  • 网格搜索实际上就是暴力搜索:首先为想要调参的参数设定一组候选值,然后网格搜索会穷举各种参数组合,根据设定的评分机制找到最好的那一组设置。
  • 它源于需要解决由澳大利亚的一位寻宝者提出的网格难题。 (查看寻宝网站上的 GC2YWE1 Minimax 了解更多详细信息,或者如果您不知道什么是寻宝:-) 该谜题要求您找出从 10 x 10 数字网格中选取的元素总和的最大值和...
  • 网格搜索、随机搜索机器学习实战

    千次阅读 2022-04-02 16:07:44
    网格搜索 随机搜索网格搜索随机搜索 网格搜索 class sklearn.model_selection.GridSearchCV( estimator :考虑优化的估计器 param_grid : dict or list of dictionaries,希望进行搜索的参数阵 scoring = None : ...

    网格搜索 随机搜索

    网格搜索

    class sklearn.model_selection.GridSearchCV(

    estimator :考虑优化的估计器

    param_grid : dict or list of dictionaries,希望进行搜索的参数阵

    scoring = None : string/callable/list/tuple/dict/None,模型评分方法

    fit_params = None, n_jobs = 1, cv = None

    iid = True :数据是否在各fold间均匀分布,此时将直接最小化总样本的损失函数refit = True :是否使用发现的最佳参数重新拟合估计器

    verbose = 0, pre_dispatch = '2*n_jobs ', error_score = 'raise’return_train_score = True :是否返回训练集的评分

    )

    GridSearchCV类的属性:

    cv_results_ :字典格式的参数列表,可被直接转换为pandas数据框
    
    best_estimator_ :网格搜索得出的最佳模型
    
    best_score_ :最佳模型的平均交互验证得分
    
    best_params_ : dict,最佳模型的参数设定
    
    best_index_ : int,最佳模型对应的索引值
    
    scorer_ : function or a dict,用于选择最佳模型的评分函数
    
    n_splits_ : int,交叉验证的拆分数
    

    GridSearchCV类的方法:

      decision_function ( *args,**kwargs) :调用筛选出的最佳模型并返回预测结果其余标准API接函数
    

    decision_function返回数据点属于每个类别的判定系数,若为正数,则代表该点属于这一类,负数则表示该点不属于这一类。判定系数的绝对值越大,判断的可信度越高。

    from sklearn import svm
    from sklearn import datasets
    from sklearn.model_selection import GridSearchCV
    import pandas as pd 
    
    iris = datasets.load_iris()
    parameters = {'kernel':('linear','rbf'),'C':[1.10]} #实例化
    svc = svm.SVC(probability = True)
    clf = GridSearchCV(svc,parameters)
    clf.fit(iris.data,iris.target)
    
    GridSearchCV(cv='warn', error_score='raise-deprecating',
                 estimator=SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
                               decision_function_shape='ovr', degree=3,
                               gamma='auto_deprecated', kernel='rbf', max_iter=-1,
                               probability=True, random_state=None, shrinking=True,
                               tol=0.001, verbose=False),
                 iid='warn', n_jobs=None,
                 param_grid={'C': [1.1], 'kernel': ('linear', 'rbf')},
                 pre_dispatch='2*n_jobs', refit=True, return_train_score=False,
                 scoring=None, verbose=0)
    
    from sklearn.svm import SVC
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yySWMov6-1648886837786)(attachment:image.png)]

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    #显示所有拟合模型的参数设定
    pd.DataFrame(clf.cv_results_)
    
    mean_fit_timestd_fit_timemean_score_timestd_score_timeparam_Cparam_kernelparamssplit0_test_scoresplit1_test_scoresplit2_test_scoremean_test_scorestd_test_scorerank_test_score
    00.0013410.0004850.0000000.000001.1linear{'C': 1.1, 'kernel': 'linear'}1.0000000.9607841.0000000.9866670.0185771
    10.0053180.0054210.0003330.000471.1rbf{'C': 1.1, 'kernel': 'rbf'}0.9803920.9607840.9791670.9733330.0090212
    clf.best_params_
    
    {'C': 1.1, 'kernel': 'linear'}
    
    print(clf.decision_function(iris.data))#网格搜索
    
    [[ 2.24627744  1.29829892 -0.30632837]
     [ 2.23781119  1.29693571 -0.30471538]
     [ 2.24548583  1.29718879 -0.30559412]
     [ 2.23591041  1.29589056 -0.30389728]
     [ 2.24795778  1.29822418 -0.3064484 ]
     [ 2.23752685  1.29735806 -0.30495212]
     [ 2.2434869   1.29624146 -0.30483534]
     [ 2.24100113  1.29748846 -0.30534443]
     [ 2.23661182  1.2953947  -0.30365738]
     [ 2.2375786   1.2973143  -0.30492944]
     [ 2.24558626  1.29895555 -0.30665596]
     [ 2.23718064  1.29655761 -0.3044249 ]
     [ 2.23997815  1.29729146 -0.30513039]
     [ 2.2512266   1.29724082 -0.30622266]
     [ 2.25842469  1.3013034  -0.30927775]
     [ 2.25245732  1.29965175 -0.30772804]
     [ 2.25194914  1.29891281 -0.3072508 ]
     [ 2.24452273  1.29771579 -0.30581239]
     [ 2.23723948  1.29851098 -0.30565066]
     [ 2.24582594  1.29783236 -0.30600783]
     [ 2.23172213  1.29768867 -0.30467686]
     [ 2.24234659  1.29705619 -0.30520883]
     [ 2.25994866  1.29879541 -0.30806837]
     [ 2.22220568  1.29476653 -0.30201257]
     [ 2.22238071  1.29523835 -0.30233811]
     [ 2.22837826  1.29635472 -0.30354531]
     [ 2.23246711  1.29580915 -0.30353915]
     [ 2.24249366  1.29815377 -0.30588644]
     [ 2.24452963  1.29837334 -0.30620727]
     [ 2.23329426  1.2959152  -0.30367832]
     [ 2.23097932  1.29600008 -0.30353221]
     [ 2.23636238  1.29729451 -0.30481098]
     [ 2.25330507  1.29966903 -0.30782355]
     [ 2.2557716   1.30030318 -0.30843809]
     [ 2.23545141  1.29669764 -0.30435806]
     [ 2.2485707   1.29833029 -0.30657146]
     [ 2.2491945   1.29959712 -0.30737741]
     [ 2.24969301  1.29855531 -0.30681499]
     [ 2.24251854  1.29603049 -0.30461341]
     [ 2.24086415  1.29773868 -0.30548479]
     [ 2.24814273  1.29786457 -0.3062567 ]
     [ 2.22578517  1.29425389 -0.30197265]
     [ 2.24585572  1.29640343 -0.30517211]
     [ 2.22992334  1.29464894 -0.30258346]
     [ 2.22639242  1.29551952 -0.3028421 ]
     [ 2.23584715  1.29603506 -0.30398092]
     [ 2.24398491  1.29802466 -0.30594642]
     [ 2.24190045  1.29650998 -0.30483816]
     [ 2.24570962  1.29872219 -0.30652718]
     [ 2.24310378  1.29771639 -0.30567798]
     [-0.25888157  2.27043006  0.84961887]
     [-0.25420288  2.26613432  0.85736765]
     [-0.26566202  2.26422889  1.03089525]
     [-0.24725457  2.26389816  0.83953777]
     [-0.26167944  2.26301954  0.97285293]
     [-0.2558817   2.26139866  0.91727953]
     [-0.25960377  2.26047526  0.98289875]
     [-0.19807268  2.27437013  0.7462427 ]
     [-0.25819096  2.26876747  0.85971716]
     [-0.23803641  2.26291864  0.81574102]
     [-0.22433167  2.27078106  0.76857795]
     [-0.24705163  2.26470632  0.8338466 ]
     [-0.24425962  2.27327002  0.78539706]
     [-0.26147994  2.26048024  1.01994941]
     [-0.21600922  2.27333011  0.75641414]
     [-0.25140742  2.2712808   0.81140066]
     [-0.2559883   2.25665492  0.98796188]
     [-0.23905423  2.273164    0.77761803]
     [-0.26533223  2.25720279  1.11452981]
     [-0.23621673  2.27128811  0.78004053]
     [-0.26495855  2.24680537  1.16854301]
     [-0.23955415  2.2718155   0.78305262]
     [-0.27060306  2.25321773  1.1785179 ]
     [-0.26019837  2.26448894  0.92626119]
     [-0.24921993  2.27097946  0.8065506 ]
     [-0.25268911  2.26997762  0.82331433]
     [-0.26531537  2.26507325  1.00569519]
     [-0.27032769  2.25456052  1.17143878]
     [-0.25759465  2.26029055  0.95342037]
     [-0.20874231  2.27830251  0.74273904]
     [-0.23361723  2.27122032  0.77690547]
     [-0.22625653  2.27409475  0.76152715]
     [-0.23467384  2.27203226  0.77563407]
     [-0.27318245  1.24299275  2.21645134]
     [-0.25579586  2.25427719  1.025428  ]
     [-0.25255831  2.26139138  0.88790408]
     [-0.2609764   2.26533568  0.92399971]
     [-0.25977858  2.26537697  0.90938447]
     [-0.23921988  2.26768065  0.79813843]
     [-0.24402523  2.26517928  0.82109608]
     [-0.2540305   2.26200534  0.89343164]
     [-0.25783181  2.26278911  0.92107182]
     [-0.24081212  2.27029624  0.79080786]
     [-0.20208621  2.27458063  0.74730352]
     [-0.2479946   2.26442341  0.83926823]
     [-0.24139608  2.26915346  0.7964656 ]
     [-0.24494709  2.26657115  0.81671407]
     [-0.24899229  2.26941618  0.81397179]
     [-0.16817711  2.27765932  0.73375002]
     [-0.24293044  2.26735753  0.80760147]
     [-0.28707384  1.14947354  2.28119096]
     [-0.27544166  1.22551722  2.24241259]
     [-0.28572654  1.21950229  2.26763227]
     [-0.28075419  1.22722381  2.253935  ]
     [-0.28496263  1.19919165  2.27167675]
     [-0.29221928  1.20120343  2.28271138]
     [-0.26350515  1.23390222  2.19566155]
     [-0.28872304  1.22449799  2.27171205]
     [-0.28536738  1.22270759  2.26580515]
     [-0.28702396  1.1962758   2.27552215]
     [-0.27295679  1.24123017  2.21846124]
     [-0.27867286  1.23154175  2.24615515]
     [-0.28099808  1.22753736  2.25431583]
     [-0.27600114  1.21779044  2.24849707]
     [-0.27838341  1.19196788  2.26253449]
     [-0.27824419  1.21747936  2.25346649]
     [-0.27892215  1.23592175  2.24334747]
     [-0.29050259  1.20935777  2.27863355]
     [-0.29632366  1.14630194  2.29280364]
     [-0.27446017  1.24383688  2.21985224]
     [-0.28353826  1.21366733  2.26542492]
     [-0.27210994  1.22438478  2.23485951]
     [-0.29332401  1.2025653   2.28418614]
     [-0.2716128   1.24523345  2.20596604]
     [-0.28175043  1.22264441  2.25843786]
     [-0.28427267  1.23661991  2.25666445]
     [-0.26887359  1.24715529  2.1886087 ]
     [-0.2689827   1.24534071  2.19396581]
     [-0.28314739  1.20961778  2.26596079]
     [-0.28185127  1.24735998  2.24067838]
     [-0.28776392  1.22705696  2.26896304]
     [-0.2869051   1.23657142  2.26293051]
     [-0.28371257  1.20202648  2.26897129]
     [-0.27174181  1.25176897  2.18997946]
     [-0.27988353  1.23805115  2.2441591 ]
     [-0.2888502   1.21427543  2.27478929]
     [-0.28160162  1.19629383  2.2668145 ]
     [-0.27824449  1.23534175  2.24198858]
     [-0.26693842  1.24624323  2.18133534]
     [-0.27913621  1.23429921  2.24525582]
     [-0.28339523  1.2030499   2.26818344]
     [-0.27624857  1.23436839  2.23730158]
     [-0.27544166  1.22551722  2.24241259]
     [-0.28569412  1.20057856  2.27257418]
     [-0.28405792  1.19376775  2.27133323]
     [-0.27826174  1.22537803  2.24926502]
     [-0.27556832  1.23623495  2.23346001]
     [-0.27601105  1.23598869  2.23502853]
     [-0.2782753   1.21132467  2.25621161]
     [-0.27247876  1.23666418  2.22329881]]
    

    随机搜索

    在不明确可能的参数候选值时,可以在指定的参数值分布中进行取样,实现对参数的随机搜索。class sklearn.model_selection.RandomizedSearchCV(

    estimator :
    
    param_distributions : dict,希望进行搜索的参数字典
    
    n_iter = 10 : int,考虑抽取出的参数组合数,该参数用于控制计算总量
    
    scoring = None, fit _params = None, n_jobs = 1, iid = True
    
    refit = True :使用整个数据集重新fit搜索到的最佳参数组合模型
    
    cv = None, verbose =0 
    
    pre_dispatch = '2*n_jobs ', random_state = Noneerror_score = 'raise',
    
    return_train_score = True
    
    )
    

    RandomizedSearchCV类的属性(和GridSearchCV类相同):

    cv_results_ :字典格式的参数列表,可被直接转换为pandas数据框
    
    best_estimator_ : 网格搜索得出的最佳模型
    
    best_score_ :最佳模型的平均交互验证得分
    
    best_params_ : dict,最佳模型的参数设定
    
    best_index_ : int,最佳模型对应的索引值
    
    scorer_ : function or a dict,用于选择最佳模型的评分函数
    
    n_splits_ : int,交叉验证的拆分数
    

    RandomizedSearchCV类的方法(和GridSearchCV类相同)︰

    decision_function (*args,**kwargs) :调用最佳模型,并返回预测结果其余标准API接函数
    
    import scipy.stats as stats
    from sklearn import datasets
    from sklearn.model_selection import RandomizedSearchCV
    import pandas as pd
    from sklearn.svm import SVC
    
    #导入数据集并设定参数
    iris = datasets.load_iris()
    parameters2 = {"kernel":('linear','rbf'),
                 'C':stats.expon(scale=100),
                 'gamma':stats.expon(scale=1),
                 'class_weight':('balanced',None)}
    
    svc = SVC()
    
    clf = RandomizedSearchCV(svc,parameters2)
    clf.fit(iris.data,iris.target)
    pd.DataFrame(clf.cv_results_)
    
    mean_fit_timestd_fit_timemean_score_timestd_score_timeparam_Cparam_class_weightparam_gammaparam_kernelparamssplit0_test_scoresplit1_test_scoresplit2_test_scoremean_test_scorestd_test_scorerank_test_score
    00.0009988.142963e-040.0003440.000486133.412balanced1.61514rbf{'C': 133.41183918245417, 'class_weight': 'bal...1.0000000.9411760.9583330.9666670.0249186
    10.0000000.000000e+000.0006530.00046215.8825None1.69397linear{'C': 15.88249498314624, 'class_weight': None,...1.0000000.9215691.0000000.9733330.0371541
    20.0006654.710309e-040.0003330.00047037.7037balanced0.079273linear{'C': 37.703742462767295, 'class_weight': 'bal...1.0000000.9215691.0000000.9733330.0371541
    30.0009974.052337e-070.0003330.00047125.3494balanced0.951097rbf{'C': 25.34942982674127, 'class_weight': 'bala...0.9803920.9411761.0000000.9733330.0244151
    40.0006764.779710e-040.0003430.000485245.106balanced0.663588linear{'C': 245.10614694204088, 'class_weight': 'bal...1.0000000.9215691.0000000.9733330.0371541
    50.0006614.685966e-040.0003370.00047622.3682None0.0174971linear{'C': 22.368243827973412, 'class_weight': None...1.0000000.9215691.0000000.9733330.0371541
    60.0003334.703588e-040.0006760.000478227.165None0.318804rbf{'C': 227.16515187404892, 'class_weight': None...0.9803920.9019611.0000000.9600000.04241110
    70.0003324.691225e-040.0000000.000000125.798None0.11144rbf{'C': 125.79773872651727, 'class_weight': None...1.0000000.9019611.0000000.9666670.0464426
    80.0000000.000000e+000.0009970.0000273.60636None2.07116linear{'C': 3.6063649298660225, 'class_weight': None...0.9803920.9215691.0000000.9666670.0333336
    90.0006654.705275e-040.0003220.00045561.6049None0.429071rbf{'C': 61.60492358027872, 'class_weight': None,...1.0000000.9019611.0000000.9666670.0464426
    clf.best_params_
    
    {'C': 15.88249498314624,
     'class_weight': None,
     'gamma': 1.693966803275749,
     'kernel': 'linear'}
    
    展开全文
  • 网络搜索方法及其扫描缩放版本,用于找到f(x,y)的最优值。
  • 二 随机网格搜索RandomSearchCV   1 随机网格搜索的基本原理   2 随机网格搜索实现   3 随机网格的理论极限 三 Halving网格搜索HalvingSearchCV   1 对半网格搜索的基本流程   2 对半网格搜索的实现   3 对半...

    目录

    一 超参数优化与枚举网格的理论极限
    二 随机网格搜索RandomSearchCV
      1 随机网格搜索的基本原理
      2 随机网格搜索实现
      3 随机网格的理论极限
    三 Halving网格搜索HalvingSearchCV
      1 对半网格搜索的基本流程
      2 对半网格搜索的实现
      3 对半随机网格搜索
    四 【加餐】AutoML前沿进展
      1 自动化第三方框架
      2 AutoML三大成熟研究领域
      3 AutoML的新兴研究

    一 超参数优化与枚举网格的理论极限

    • 超参数优化HPO(HyperParameter Optimization)

    每一个机器学习算法都会有超参数,而超参数的设置很大程度上影响了算法实际的使用效果,因此调参是机器学习算法工程师最为基础和重要的任务。现代机器学习与深度学习算法的超参数量众多,不仅实现方法异常灵活、算法性能也受到更多的参数的复合影响,因此当人工智能浪潮来临时,可以自动选择超参数的超参数优化HPO领域也迎来了新一轮爆发。

    在算法的世界中,我们渴望一切流程最终都走向完美自动化,专门研究机器学习自动化的学科被称为AutoML,而超参数自动优化是AutoML中最成熟、最深入、也是最知名的方向。理论上来说,当算力与数据足够时,HPO的性能一定是超过人类的。HPO能够降低人为工作量,并且HPO得出的结果比认为搜索的复现可能性更高,所以HPO可以极大程度提升科学研究的复现性和公平性。当代超参数优化算法主要可以分为:

    基于网格的各类搜索(Grid)
    基于贝叶斯优化的各类优化算法(Baysian)
    基于梯度的各类优化(Gradient-based)
    基于种群的各类优化(进化算法,遗传算法等)

    其中,各类网格搜索方法与基于贝叶斯的优化方法是最为盛行的,贝叶斯优化方法甚至可以被称为是当代超参数优化中的SOTA模型。这些模型对于复杂集成算法的调整有极大的作用与意义。

    • 网格搜索的理论极限与缺点

    在所有超参数优化的算法当中,枚举网格搜索是最为基础和经典的方法。在搜索开始之前,我们需要人工将每个超参数的备选值一一列出,多个不同超参数的不同取值之间排列组合,最终将组成一个参数空间(parameter space)。枚举网格搜索算法会将这个参数空间当中所有的参数组合带入模型进行训练,最终选出泛化能力最强的组合作为模型的最终超参数。

    对网格搜索而言,如果参数空间中的某一个点指向了损失函数真正的最小值,那枚举网格搜索时一定能够捕捉到该最小值以及对应的参数(相对的,假如参数空间中没有任意一点指向损失函数真正的最小值,那网格搜索就一定无法找到最小值对应的参数组合)。

    参数空间越大、越密,参数空间中的组合刚好覆盖损失函数最小值点的可能性就会越大。这是说,极端情况下,当参数空间穷尽了所有可能的取值时,网格搜索一定能够找到损失函数的最小值所对应的最优参数组合,且该参数组合的泛化能力一定是强于人工调参的。

    但是,参数空间越大,网格搜索所需的算力和时间也会越大,当参数维度上升时,网格搜索所需的计算量更是程指数级上升的。以随机森林为例:

    只有1个参数n_estimators,备选范围是[50,100,150,200,250,300],需要建模6次。
    增加参数max_depth,且备选范围是[2,3,4,5,6],需要建模30次。
    增加参数min_sample_split,且备选范围为[2,3,4,5],需要建模120次。

    同时,参数优化的目标是找出令模型泛化能力最强的组合,因此需要交叉验证来体现模型的泛化能力,假设交叉验证次数为5,则三个参数就需要建模600次。在面对超参数众多、且超参数取值可能无限的人工神经网络、融合模型、集成模型时,伴随着数据和模型的复杂度提升,网格搜索所需要的时间会急剧增加,完成一次枚举网格搜索可能需要耗费几天几夜。考虑到后续实践过程中,算法和数据都将更加复杂,而建模过程中超参数调优是模型训练的必备环节,因此,我们急需寻找到一种更加高效的超参数搜索方法。在本节课中,我们将介绍三种基于网格进行改进的超参数优化方法,并将他们的结果与网格搜索进行时间/空间/效果上的对比。

    • 建立benchmark:随机森林中枚举网格搜索的结果
    from sklearn.ensemble import RandomForestRegressor as RFR
    from sklearn.model_selection import cross_validate, KFold, GridSearchCV
    data = pd.read_csv(r"D:\Pythonwork\2021ML\PART 2 Ensembles\datasets\House Price\train_encode.csv",index_col=0)
    
    X = data.iloc[:,:-1]
    y = data.iloc[:,-1]
    
    X.shape
    #(1460, 80)
    X.head()

    y.describe() #RMSE
    #count      1460.000000
    #mean     180921.195890
    #std       79442.502883
    #min       34900.000000
    #25%      129975.000000
    #50%      163000.000000
    #75%      214000.000000
    #max      755000.000000
    #Name: SalePrice, dtype: float64
    
    #参数空间
    param_grid_simple = {"criterion": ["squared_error","poisson"]
                         , 'n_estimators': [*range(20,100,5)]
                         , 'max_depth': [*range(10,25,2)]
                         , "max_features": ["log2","sqrt",16,32,64,"auto"]
                         , "min_impurity_decrease": [*np.arange(0,5,10)]
                        }
    
    #参数空间大小计算
    2 * len([*range(20,100,5)]) * len([*range(10,25,2)]) * len(["log2","sqrt",16,32,64,"auto"]) * len([*np.arange(0,5,10)])
    #1536
    
    #直接使用循环计算
    no_option = 1
    for i in param_grid_simple:
        no_option *= len(param_grid_simple[i])
    no_option
    #1536
    
    #模型,交叉验证,网格搜索
    reg = RFR(random_state=1412,verbose=True,n_jobs=-1)
    cv = KFold(n_splits=5,shuffle=True,random_state=1412)
    search = GridSearchCV(estimator=reg
                         ,param_grid=param_grid_simple
                         ,scoring = "neg_mean_squared_error"
                         ,verbose = True
                         ,cv = cv
                         ,n_jobs=-1)
    
    #=====【TIME WARNING: 7mins】=====#
    start = time.time()
    search.fit(X,y)
    print(time.time() - start)
    #Fitting 5 folds for each of 1536 candidates, totalling 7680 fits
    #381.6039867401123
    
    381.6039/60
    #6.3600650000000005
    
    search.best_estimator_
    #RandomForestRegressor(max_depth=23, max_features=16, min_impurity_decrease=0,
    #                      n_estimators=85, n_jobs=-1, random_state=1412,
    #                      verbose=True)
    
    abs(search.best_score_)**0.5
    #29179.698261599166
    
    #按最优参数重建模型,查看效果
    ad_reg = RFR(n_estimators=85, max_depth=23, max_features=16, random_state=1412)
    cv = KFold(n_splits=5,shuffle=True,random_state=1412)
    result_post_adjusted = cross_validate(ad_reg,X,y,cv=cv,scoring="neg_mean_squared_error"
                              ,return_train_score=True
                              ,verbose=True
                              ,n_jobs=-1)
    def RMSE(cvresult,key):
        return (abs(cvresult[key])**0.5).mean()
    RMSE(result_post_adjusted,"train_score")
    #11000.81099038192
    RMSE(result_post_adjusted,"test_score")
    #28572.070208366855
    

    #打包成函数供后续使用
    #评估指标RMSE
    def RMSE(cvresult,key):
        return (abs(cvresult[key])**0.5).mean()
    
    #计算参数空间大小
    def count_space(param):
        no_option = 1
        for i in param_grid_simple:
            no_option *= len(param_grid_simple[i])
        print(no_option)
        
    #在最优参数上进行重新建模验证结果
    def rebuild_on_best_param(ad_reg):
        cv = KFold(n_splits=5,shuffle=True,random_state=1412)
        result_post_adjusted = cross_validate(ad_reg,X,y,cv=cv,scoring="neg_mean_squared_error"
                                              ,return_train_score=True
                                              ,verbose=True
                                              ,n_jobs=-1)
        print("训练RMSE:{:.3f}".format(RMSE(result_post_adjusted,"train_score")))
        print("测试RMSE:{:.3f}".format(RMSE(result_post_adjusted,"test_score")))

    二 随机网格搜索RandomizedSearchCV

    • 基本原理

    在讲解网格搜索时我们提到,伴随着数据和模型的复杂度提升,网格搜索所需要的时间急剧增加。以随机森林算法为例,如果使用过万的数据,搜索时间则会立刻上升好几个小时。因此,我们急需寻找到一种更加高效的超参数搜索方法。

    首先,当所使用的算法确定时,决定枚举网格搜索运算速度的因子一共有两个:

    1 参数空间的大小:参数空间越大,需要建模的次数越多
    2 数据量的大小:数据量越大,每次建模时需要的算力和时间越多

    因此,sklearn中的网格搜索优化方法主要包括两类,其一是调整搜索空间,其二是调整每次训练的数据。其中,调整参数空间的具体方法,是放弃原本的搜索中必须使用的全域超参数空间,改为挑选出部分参数组合,构造超参数子空间,并只在子空间中进行搜索。

    以下图的二维空间为例,在这个n_estimators与max_depth共同组成的参数空间中,n_estimators的取值假设为[50,100,150,200,250,300],max_depth的取值假设为[2,3,4,5,6],则枚举网格搜索必须对30种参数组合都进行搜索。当我们调整搜索空间,我们可以只抽样出橙色的参数组合作为“子空间”,并只对橙色参数组合进行搜索。如此一来,整体搜索所需的计算量就大大下降了,原本需要30次建模,现在只需要8次建模。

    fig, [ax1, ax2] = plt.subplots(1,2,dpi=300)
    n_e_list = [*range(50,350,50)]
    m_d_list = [*range(2,7)]
    comb = pd.DataFrame([(n_estimators, max_depth) for n_estimators in n_e_list for max_depth in m_d_list])
    
    ax1.scatter(comb.iloc[:,0],comb.iloc[:,1],cmap="Blues")
    ax1.set_xticks([*range(50,350,50)])
    ax1.set_yticks([*range(2,7)])
    ax1.set_xlabel("n_estimators")
    ax1.set_ylabel("max_depth")
    ax1.set_title("GridSearch")
    
    ax2.scatter(comb.iloc[:,0],comb.iloc[:,1],cmap="Blues")
    ax2.scatter([50,250,200,200,300,100,150,150],[4,2,6,3,2,3,2,5],cmap="red",s=20,linewidths=5)
    ax2.set_xticks([*range(50,350,50)])
    ax2.set_yticks([*range(2,7)])
    ax2.set_xlabel("n_estimators")
    ax2.set_ylabel("max_depth")
    ax2.set_title("RandomSearch");

    在sklearn中,随机抽取参数子空间并在子空间中进行搜索的方法叫做随机网格搜索RandomizedSearchCV。由于搜索空间的缩小,需要枚举和对比的参数组的数量也对应减少,整体搜索耗时也将随之减少,因此:

    当设置相同的全域空间时,随机搜索的运算速度比枚举网格搜索很多。

    当设置相同的训练次数时,随机搜索可以覆盖的空间比枚举网格搜索很多。

    同时,绝妙的是,随机网格搜索得出的最小损失与枚举网格搜索得出的最小损失很接近

    可以说,是提升了运算速度,又没有过多地伤害搜索的精度。

    不过,需要注意的是,随机网格搜索在实际运行时,并不是先抽样出子空间,再对子空间进行搜索,而是仿佛“循环迭代”一般,在这一次迭代中随机抽取1组参数进行建模,下一次迭代再随机抽取1组参数进行建模,由于这种随机抽样是不放回的,因此不会出现两次抽中同一组参数的问题。我们可以控制随机网格搜索的迭代次数,来控制整体被抽出的参数子空间的大小,这种做法往往被称为“赋予随机网格搜索固定的计算量,当全部计算量被消耗完毕之后,随机网格搜索就停止”。

    • 随机网格搜索的实现
    from sklearn.model_selection import RandomizedSearchCV
    

    class sklearn.model_selection.RandomizedSearchCV(estimator, param_distributions, *, n_iter=10, scoring=None, n_jobs=None, refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', random_state=None, error_score=nan, return_train_score=False)

    全部参数解读如下,其中加粗的是随机网格搜索独有的参数:

    随机网格搜索可以输入连续的参数,普通网格搜索不能输入连续的参数。 

    我们依然借用之前在网格搜索上见过的X和y,以及随机森林回归器,来实现随机网格搜索:

    X.shape
    #(1460, 80)
    
    X.head()

    y.describe()
    #count      1460.000000
    #mean     180921.195890
    #std       79442.502883
    #min       34900.000000
    #25%      129975.000000
    #50%      163000.000000
    #75%      214000.000000
    #max      755000.000000
    #Name: SalePrice, dtype: float64
    • 相同的全域参数空间
    #创造参数空间 - 使用与网格搜索时完全一致的空间,以便于对比
    param_grid_simple = {"criterion": ["squared_error","poisson"]
                         , 'n_estimators': [*range(20,100,5)]
                         , 'max_depth': [*range(10,25,2)]
                         , "max_features": ["log2","sqrt",16,32,64,"auto"]
                         , "min_impurity_decrease": [*np.arange(0,5,10)]
                        }
    
    #建立回归器、交叉验证
    reg = RFR(random_state=1412,verbose=True,n_jobs=-1)
    cv = KFold(n_splits=5,shuffle=True,random_state=1412)
    
    #计算全域参数空间大小,这是我们能够抽样的最大值
    count_space(param_grid_simple)
    #1536
    
    #定义随机搜索
    search = RandomizedSearchCV(estimator=reg
                                ,param_distributions=param_grid_simple
                                ,n_iter = 800 #子空间的大小是全域空间的一半左右
                                ,scoring = "neg_mean_squared_error"
                                ,verbose = True
                                ,cv = cv
                                ,random_state=1412
                                ,n_jobs=-1
                               )
    
    #训练随机搜索评估器
    #=====【TIME WARNING: 5~10min】=====#
    start = time.time()
    search.fit(X,y)
    print(time.time() - start)
    #Fitting 5 folds for each of 800 candidates, totalling 4000 fits
    #170.16785073280334
    
    170.1678/60
    #2.83613
    
    #查看模型结果
    search.best_estimator_
    #RandomForestRegressor(max_depth=24, max_features=16, min_impurity_decrease=0,
    #                      n_estimators=85, n_jobs=-1, random_state=1412,
    #                      verbose=True)
    
    abs(search.best_score_)**0.5
    #29251.284326350575
    
    #根据最优参数重建模型
    ad_reg = RFR(max_depth=24, max_features=16, min_impurity_decrease=0,
                          n_estimators=85, n_jobs=-1, random_state=1412,
                          verbose=True)
    rebuild_on_best_param(ad_reg)
    #训练RMSE:11031.299
    #测试RMSE:28639.969

    很明显,在相同参数空间、相同模型的情况下,随机网格搜索的运算速度是普通网格搜索的一半,当然,这与子空间是全域空间的一半有很大的联系。由于随机搜索只是降低搜索的次数,并非影响搜索过程本身,因此其运行时间基本就等于n_iter/全域空间组合数 * 网格搜索的运行时间。

    • 随机网格搜索的理论极限

    虽然通过缩小子空间可以提升搜索的速度,但是随机网格搜索的精度看起来并没有削减太多,随机网格搜索可以得到和网格搜索一样好的结果吗?它也像网格搜索一样,可以得到最优的参数组合吗?为什么缩小参数空间之后,随机网格搜索的结果还与网格搜索一致?

    理论上来说,枚举网格搜索的上限和随机网格搜索的上限哪个高?

    从直觉上来说,我们很难回答这些问题,但我们可以从数学的随机过程的角度来理解这个问题。在机器学习算法当中,有非常多通过随机来提升运算速度(比如Kmeans,随机挑选样本构建簇心,小批量随机梯度下降,通过随机来减少每次迭代需要的样本)、或通过随机来提升模型效果的操作(比如随机森林,比如极度随机树)。两种随机背后的原理完全不同,而随机网格搜索属于前者,这一类机器学习方法总是伴随着“从某个全数据集/全域中进行抽样”的操作,而这种操作能够有效的根本原因在于:

    • 抽样出的子空间可以一定程度上反馈出全域空间的分布,且子空间相对越大(含有的参数组合数越多),子空间的分布越接近全域空间的分布
       
    • 当全域空间本身足够密集时,很小的子空间也能获得与全域空间相似的分布
       
    • 如果全域空间包括了理论上的损失函数最小值,那一个与全域空间分布高度相似的子空间很可能也包括损失函数的最小值,或包括非常接近最小值的一系列次小值

    上述数学事实听起来比较抽象,但其实我们可以通过绘制图像来直观地呈现这些事实。许多在数学上比较抽象的概念都可以被可视化。在这里,我们借助matplotlib工具库mplot3d中的一组默认数据。

    from mpl_toolkits.mplot3d import axes3d
    p1, p2, MSE = axes3d.get_test_data(0.05)
    #自动获取数据的功能get_test_data,可以自动生成复合某一分布的数据
    #我们现在假设这一组数据中有两个参数,p1与p2,两个参数组成的参数组合对应着损失函数值MSE
    #参数0.05是指参数空间中,点与点之间的距离
    #因此该数字越小,取出来的样本越多
    
    len(p1) #参数1的取值有120个
    #120
    len(p2) #参数2的取值也有120个
    #120

    请问现在参数空间当中一共有多少个参数组合?120*120=14400种组合,所以参数空间中一共有14400个点。

    MSE.shape #损失函数值,总共14400个点
    #(120, 120)
    
    #绘制P1与P2的参数空间 - 这是一个呈现出14400个点的密集空间
    plt.figure(dpi=300)
    plt.scatter(p1,p2,s=0.2)
    plt.xticks(fontsize=9)
    plt.yticks(fontsize=9);

    #参数与损失共同构建的函数
    p1, p2, MSE = axes3d.get_test_data(0.05)
    plt.figure(dpi=300)
    ax = plt.axes(projection="3d")
    ax.plot_wireframe(p1,p2,MSE,rstride=2,cstride=2,linewidth=0.5)
    ax.view_init(2, -15)
    ax.zaxis.set_tick_params(labelsize=7)
    ax.xaxis.set_tick_params(labelsize=7)
    ax.yaxis.set_tick_params(labelsize=7);

    np.min(MSE) #整个参数空间中,可获得的MSE最小值是-73.39
    #-73.39620971601681
    
    #现在,我们从该空间上抽取子空间
    import numpy as np
    MSE.shape
    #(120, 120)
    #我们从空间中抽取n个组合,n越大子空间越大
    #现在总共有14400个组合
    #对被抽中的点来说,损失函数的值就是MSE,对没有抽中的点来说,损失函数值是空值
    #因此,我们只需要找出没有抽中的点,并让它的损失函数值MSE为空就可以了
    
    n = 100
    #从0~14400中生成(14400-n)个随机数,形成没有被抽到子空间中的点的索引
    unsampled = np.random.randint(0,14400,14400-n)
    
    p1, p2, MSE = axes3d.get_test_data(0.05)
    
    #拉平MSE,并将所有没抽中的点的损失函数变为空值
    MSE = MSE.ravel()
    MSE[unsampled] = np.nan
    MSE = MSE.reshape((120,120))
    #设置完毕空值后,记得把MSE恢复成原来的结构,否则绘图报错
    
    #参数与损失共同构建的函数
    plt.figure(dpi=300)
    ax = plt.axes(projection="3d")
    ax.view_init(2, -15)
    ax.plot_wireframe(p1,p2,MSE,rstride=2,cstride=2,linewidth=0.5)
    ax.zaxis.set_tick_params(labelsize=7)
    ax.xaxis.set_tick_params(labelsize=7)
    ax.yaxis.set_tick_params(labelsize=7);
    
    #求出当前损失函数上的最小值
    #注意此时因为MSE中含有了空值,因此要先排除空值影响,否则min函数会返回空值
    MSE = MSE.ravel().tolist()
    MSE = [x for x in MSE if str(x) != 'nan']
    print(np.min(MSE))
    #-73.24243733589367

    我们可以在图像上验证如下事实:

    • 抽样出的子空间可以一定程度上反馈出全域空间的分布,且子空间相对越大(含有的参数组合数越多),子空间的分布越接近全域空间的分布
       
    • 当全域空间本身足够密集时,很小的子空间也能获得与全域空间相似的分布
       
    • 如果全域空间包括了理论上的损失函数最小值,那一个与全域空间分布高度相似的子空间很可能也包括损失函数的最小值,或包括非常接近最小值的一系列次小值

    因此,只要子空间足够大,随机网格搜索的效果一定是高度逼近枚举网格搜索的。在全域参数空间固定时,随机网格搜索可以在效率与精度之间做权衡。子空间越大,精度越高,子空间越小,效率越高。

    • 更大/更密集的全域空间

    不过,由于随机网格搜索计算更快,所以在相同计算资源的前提下,我们可以对随机网格搜索使用更大的全域空间,因此随机搜索可能得到比网格搜索更好的效果:

    #创造参数空间 - 让整体参数空间变得更密
    param_grid_simple = {'n_estimators': [*range(80,100,1)]
                         , 'max_depth': [*range(10,25,1)]
                         , "max_features": [*range(10,20,1)]
                         , "min_impurity_decrease": [*np.arange(0,5,10)]
                        }
    #计算全域参数空间大小,这是我们能够抽样的最大值
    count_space(param_grid_simple)
    #3000
    
    #建立回归器、交叉验证
    reg = RFR(random_state=1412,verbose=True,n_jobs=-1)
    cv = KFold(n_splits=5,shuffle=True,random_state=1412)
    
    #定义随机搜索
    search = RandomizedSearchCV(estimator=reg
                                ,param_distributions=param_grid_simple
                                ,n_iter = 1536 #使用与枚举网格搜索类似的拟合次数
                                ,scoring = "neg_mean_squared_error"
                                ,verbose = True
                                ,cv = cv
                                ,random_state=1412
                                ,n_jobs=-1)
    #训练随机搜索评估器
    #=====【TIME WARNING: 5~10min】=====#
    start = time.time()
    search.fit(X,y)
    end = time.time() - start
    print(end/60)
    #Fitting 5 folds for each of 1536 candidates, totalling 7680 fits
    #3.8464645385742187
    
    
    #查看最佳评估器
    search.best_estimator_
    #RandomForestRegressor(max_depth=22, max_features=14, min_impurity_decrease=0,
    #                      n_estimators=89, n_jobs=-1, random_state=1412,
    #                      verbose=True)
    
    #查看最终评估指标
    abs(search.best_score_)**0.5
    #29012.90569846546
    
    rebuild_on_best_param(search.best_estimator_)
    #训练RMSE:11208.818
    #测试RMSE:28346.673

    可以发现,当全域参数空间增大之后,随即网格搜索可以使用与小空间上的网格搜索相似或更少的时间,来探索更密集/更大的空间,从而获得更好的结果。除了可以容忍更大的参数空间之外,随机网格搜索还可以接受连续性变量作为参数空间的输入。

    • 连续型的参数空间

    对于网格搜索来说,参数空间中的点是分布均匀、间隔一致的,因为网格搜索无法从某种“分布”中提取数据,只能使用组合好的参数组合点,而随机搜索却可以接受“分布”作为输入。如上图所示,对于网格搜索来说,损失函数的最低点很不幸的、位于两组参数之间,在这种情况下,枚举网格搜索是100%不可能找到最小值的。但对于随机网格搜索来说,由于是一段分布上随机选择参数点,因此在同样的参数空间中,取到更好的值的可能性更大。

    import scipy #使用scipy来帮助我们建立分布
    scipy.stats.uniform(loc=1,scale=100)
    #<scipy.stats._distn_infrastructure.rv_frozen at 0x137a147d7c0>

    uniform是均匀分布,默认生成[0,1]之间的数字,可以使用loc来调整起点,scale来调整终点。我们还可以选择其他的分布,比如指数分布expon, gamma分布, 或者是randint。注意scipy这里并不是像np.linspace()一样生成一段离散的数字,而是直接生成一个分布对象。并且,我们并没有在分布对象中指定尺寸,也就是说,在这段分布上究竟要取几个随机的参数备选值,是由随机搜索自己决定的。理论上来说,我们给出的n_iter越大,任意参数的分布上可能被取到的点就越多。因此,当参数空间中包含某个分布的时候,我们无法估计全域参数空间的大小。

    在之前调整随机森林的时候,我们给出的所有参数都是只能接纳正整数的参数,因此在这里我们可以使用scipy.stats.randint,不过randint并不是严格意义上的连续分布。

    严格来说,连续型搜索更适用于学习率,C,alpha这样的参数(无上限,以浮点数为主),随机森林的参数中最接近这个定义的是min_impurity_decrease,表示决策树在分枝是可以容忍的最小的不纯度下降量。我们借着这个参数,使用均匀分布来进行搜索试试看。

    param_grid_simple = {'n_estimators': [*range(80,100,1)]
                         , 'max_depth': [*range(10,25,1)]
                         , "max_features": [*range(10,20,1)]
                         , "min_impurity_decrease": scipy.stats.uniform(0,50)
                        }
    
    #建立回归器、交叉验证
    reg = RFR(random_state=1412,verbose=True,n_jobs=12)
    cv = KFold(n_splits=5,shuffle=True,random_state=1412)
    
    #定义随机搜索
    search = RandomizedSearchCV(estimator=reg
                                ,param_distributions=param_grid_simple
                                ,n_iter = 1536 #还是使用1536这个搜索次数
                                ,scoring = "neg_mean_squared_error"
                                ,verbose = True
                                ,cv = cv
                                ,random_state=1412
                                ,n_jobs=12)
    
    #训练随机搜索评估器
    #=====【TIME WARNING: 5~10min】=====#
    start = time.time()
    search.fit(X,y)
    end = time.time() - start
    print(end/60)
    #Fitting 5 folds for each of 1536 candidates, totalling 7680 fits
    #3.921058924992879
    
    #查看最佳评估器
    search.best_estimator_
    #RandomForestRegressor(max_depth=22, max_features=14,
    #                      min_impurity_decrease=20.070367229896224, n_estimators=98,
    #                      n_jobs=12, random_state=1412, verbose=True)
    
    #查看最终评估指标
    abs(search.best_score_)**0.5
    #29148.381610182565
    
    rebuild_on_best_param(search.best_estimator_)
    #训练RMSE:11184.428
    #测试RMSE:28495.682

    在本次搜索当中,由于我们之前已经知道最好的可能的min_impurity_decrease的值为0,因此强行向更大的数拓展搜索空间可能会导致模型效果下降。不过在随机森林当中,min_impurity_decrease是唯一可以使用分布进行搜索的参数,因此在这里我们就容忍了这部分表现上升。

    理论上来说,当枚举网格搜索所使用的全域参数空间足够大/足够密集时,枚举网格搜索的最优解是随机网格搜索的上限,因此理论上随机网格搜索不会得到比枚举网格搜索更好的结果

    但现实中的问题是,由于枚举网格搜索的速度太慢,因此枚举网格搜索的全域参数空间往往无法设置得很大,也无法设置得很密集,因此网格搜索的结果很难接近理论上的最优值。当随机网格搜索将空间设置更大、更密集时,就可以捕获更广空间的分布,也自然就可能捕获到理论上的最优值了。

    展开全文
  • 网格搜索法在机器学习和深度学习中的小案例,使用Jupyter,压缩包包括: (1)data:letterdata.csv (2)Hyperparameter optimization.ipynb
  • 网格搜索尝试超参数的所有组合,因此增加了计算的时间复杂度,在数据量较大,或者模型较为复杂等等情况下,可能导致不可行的计算成本,这样网格搜索调参方法就不适用了。然而,随机搜索提供更便利的替代方案,该方法...
  • 【翻译自 : Random ... 功能优化需要选择一种算法,以有效地对搜索空间进行采样并找到一个好的或最佳的解决方案。有许多算法可供选择,尽管为哪种类型的解决方案可行或可能解决问题建立基准非常重要。这可以使用...
  • 网格搜索

    2019-07-22 15:44:39
    简书https://www.jianshu.com/p/55b9f2ea283b
  • 网格搜索 内部集成了k折交叉验证,网格搜索后可以不用单独再做k折。 普通的网格搜索 import numpy as np import pandas as pd from sklearn.model_selection import cross_val_score from sklearn.ensemble import ...
  • 提出了一种基于袋外数据估计的分类误差,利用改进的网格搜索算法对随机森林算法中的决策树数量和候选分裂属性数进行参数优化的随机森林算法。仿真结果表明,利用该方法优化得到的参数都能够使随机森林的分类效果得到...
  • GriSPy(Python中的网格搜索) GriSPy是用于快速最近邻居查找的常规网格搜索算法。 此类在规则网格中索引一组k维点,从而为最近的邻居查询提供了快速的方法。 可以为每个轴单独提供可选的周期性边界条件。 GriSPy...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 61,347
精华内容 24,538
关键字:

网格搜索