0
点赞
收藏
分享

微信扫一扫

【机器学习】如何使用随机网格搜索,以缩短网格搜索速度?

ITWYY 2022-03-11 阅读 30
  • 索引

    🔣 函数及参数

    🔑 公式

    🗣 案例

    📌 名词解释

    📖 摘抄

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

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

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

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

    🗣 案例:全域参数空间VS部分参数空间(示意图)

    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 连续型参数空间

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

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

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

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

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

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

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

    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
    
举报

相关推荐

0 条评论