百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

调整超参数决定模型是“金子”还是“垃圾”

toyiye 2024-06-21 12:27 11 浏览 0 评论

数据清洗以后,你也许会困惑应该从哪里开始建模。一般情况下它的下一步应该是特征选择,但特征工程和模型训练是相互影响的。好的特征选择可以使模型得到好的效果,而不同的模型又对数据有不同的要求。

因此,特征工程和模型训练是两个不可分割的部分。由于模型的选择会对特征的选择造成影响,因此,在特征工程开始前,至少应该尝试训练一些可能的模型,查看当前的特征是否适合可能的模型。如下图是建模流程的循环,特征工程和训练模型是两个动态过程。

通过特征工程,选择可能的重要特征。通过参数调整,尝试训练可能的模型,从中选择最佳的模型并调试参数。

除了特征工程以外,超参数的选择也十分重要,它决定你的模型是“金子”还是“垃圾”,以及模型是否处于最优的表现并得到好的结果。本文着重介绍三种超参数调节的方法,分别为:手动调节(manual tuning),网格搜索(grid search),随机搜索(randomized search),贝叶斯搜索(Bayesian Search)。 详见链接。

图片来源:https://towardsdatascience.com/what-is-the-best-starter-model-in-table-data-ml-lessons-from-a-high-rank-kagglers-new-book-f08b821db797

在开始介绍超参数前,首先要明确参数与超参数的区别:

参数:是模型内部的配置变量,在机器学习中生成的。

超参数:超参数是在机器学习前由用户基于以往的经验填入的实体,它不能通过机器学习自动生成,而必须由外部进行指定。

例如逻辑回归,假设y=ax+b,其中x是输入数据,sigmoid函数是$f(x) = {1 \over {1 + e^{-(ax+b)}}}$,模型的输出值为0或1。 对于任意给定的数据X,模型都会返回一个a和b与之匹配,其中的a和b就是模型的参数。由于模型的输出值是0或1,因此,决定模型何时输出为1,何时输出为0,需要外部设置一个阈值,这个阈值(threshold)即为模型的超参数。 对于模型的参数,是通过在训练模型或者机器学习中生成的,而超参数是需要外部设置,可以用过学习曲线或者网格搜索等方法进行调节,以使模型表现最佳。

1. 超参数的调整概述

在scikit-learn中提供很多不同的机器学习模型,并且提供了各模型超参数的初始值设置,这些初始值的搭配仅是针对解决某些问题的可能的最优搭配,并不是针对解决所有问题的最优搭配,因此,当使用scikit-learn中的模型进行建模时,调整超参数仍是必要的。

1.1 伴随特征工程的三个调参过程

比较常见的步骤可以如下:

  • 初始阶段:以基准参数和基准特征工程为开始,
  • 重要参数调节阶段:通过选择一些参数候选和特征工程,手动调参或者网格搜索一些重要特征 ,
  • 剩余参数调节阶段:对于其它参数和最后的特征工程,使用随机搜索。

1.2 了解模型超参数

数据科学家的工作之一就是找到模型的最佳超参数。由于每个模型的超参数都不尽相同,很难对所有模型的超参数进行概括性总结。因此,在调节超参数前,应对可能用到的模型及其超参数设置有一个全面概括的了解。下面为几个关于不同集成算法的各参数总结网站,可以收藏,以备不时之需。

(1)介绍xgboost和lightGBM超参数的网站。

(2)在Analytic Vidhya网站上也提供关于GBDT模型的超参数的丰富资料:

  • xgboost: "Complete Guide to Parameter Tuning in XGBoost with codes in Python"
  • lightgbm: "Which algorithm takes the crown: Light GBM vs XGBOOST?"

(3)XGBoost,LightGBM和CatBoost超参数的优化:

  • "An Example of Hyperparameter Optimization on XGBoost, LightGBM and CatBoost using Hyperopt"

下表展示了根据不同分级的重要性,参数不同重要性的总结:

图片来源 https://towardsdatascience.com/hyperparameter-tuning-explained-d0ebb2ba1d35

2. 四个调节超参数的基本方法

2.1 手动调节

手动参数调节更多的是基于建模者对以往经验的总结,通过修改模型的部分参数,了解模型分数对模型参数变化的敏感性。

手动调节参数的优势:

  • 应用以往构建模型的经验,选择可能的最佳模型参数。在调参过程中至少可以手动尝试调节模型参数;较为快速。

手动调节参数的劣势:

  • 缺少对模型参数与相应得分变化的宏观把握。

比如,当你发现在训练模型的时候,很多不用的特征被“味”到模型中,你可以手动增加正则参数的权重进行特征选择。手动调节参数可以让建模者快速掌握模型对参数变化的敏感度,以备后续提供更好的模型调参范围。

2.2 网格搜索

又名穷尽的网格搜索(Exhaustive Grid Search)。网格搜索方法是通过设置可能的各超参数集合,将所有集合中可能的组合作为超参数,对模型进行一次训练。n个可能的超参数组合意味着n次模型训练。最后,网格搜索的返回值是n次模型训练中模型表现最好的超参数组合。因此,网格搜索随设置的超参数个数和集合的提高,呈时间和空间的复杂性。 网格搜索的评分标准可以由用户来指定,例如准确率,精确率,召回率等。

参数设置和模型评估可以使用sklearn中的GridSearchCV进行调用。

网格搜索的优势:

  • 可以选用任何你认为可能是最佳参数范围的超参数集合进行模型训练。

网格搜索的劣势:

  • 网格搜索较为耗时,因为要运行给定的每一个超参数集。所以,如果参数集较大,则网格搜索的运行成本较高。实际上,网格搜索的参数范围是需要被限制的,即不能无限大。

以LGBMRegressor模型为例,分别设置了“max_depth”,“subsample”,“colsample_bytree”,“min_child_weight”超参数,它的评分器是“r2”,可能的组合个数是3*2*2*3=36,即需要训练36次LGBMRegressor模型,如下是代码示例:

# 导入lightgbm库 
from lightgbm import LGBMRegressor
?
# 导入网格搜索 
from sklearn.model_selection import train_test_split, GridSearchCV
?
import pandas as pd
import numpy as np
?
# 导入数据并拆分训练集 
df = pd.read_csv('test.csv',index_col=0)
y = df['Target']
X = df.drop(['Targe'],axis=1)
X_train0, X_test, y_train0, y_test = train_test_split(X,y,test_size=0.2, random_state= 2)
?
# 定义验证集比例 
r = 0.1 
trainLen = round(len(X_train0)*(1-r))
?
# 拆分训练集和验证集 
X_train = X_train0.iloc[:trainLen,:]
y_train = y_train0[:trainLen]
X_val = X_train0.iloc[trainLen:,:]
y_val = y_train0[trainLen:]
?
# 定义网格搜索参数 
gridParams = {
    'max_depth': [3, 5, 7],
    'subsample': [0.8, 1.0],
    'colsample_bytree': [0.8, 1.0],
    'min_child_weight': [0.1, 1.0, 2.0],
}
?
# 定义lightgbm网格搜索 
reg = LGBMRegressor(learning_rate=0.1, n_estimators=1000, random_state=1000)
reg_gridsearch = GridSearchCV(reg, gridParams, cv=5, scoring='r2', n_jobs=-1) 
?
# 训练模型 
reg_gridsearch.fit(X_train, y_train, early_stopping_rounds=100, eval_set=(X_val,y_val))
?
# 返回最佳参数 
reg_gridsearch.best_params_ 

代码参考:https://gist.githubusercontent.com/daydreamersjp/0e588d805be6d6b755c68fa1e8095fc4/raw/e0eb0af142db38fb3ceb48b1f37e2a22671afd0a/gistfile2019120801.py

2.3 随机搜索

随机搜索是基于网格搜索的延伸,它与网格搜索一样,需要预先指定超参数的候选集。随机搜索会随机的从参数候选集中选取参数,训练模型。随机搜索从由所有可能的超参数组合中随机抽取“组合”以训练模型,使用者可以通过设置最大迭代次数,来调节模型的运行次数。相对网格搜索而言,随机搜索的计算成本更低,结果精度相对较低,它返回一个比较general的模型可能实现的水平。随机搜索与网格搜索的返回值相同,均是各自策略下模型的最佳超参数。

随机搜索还可以设置参数的密度函数,例如:均匀分布或者正态分布。

可以在如下库中实现上述操作,如:sklearn中的RandomizedSearchCV。

随机搜索的优势:

  • 你可以通过控制参数搜索的次数,控制随机搜索的运行成本。

随机搜索的劣势:

  • 它是一种“权衡”策略,运行成本和搜索精度的“权衡”。随机搜索返回的最佳参数可能不是模型实际的最佳参数。
  • 由于设置最大搜索次数,因此,一些参数可能被遍历的次数有限。
  • 随机搜索不提供随机抽取超参数的方法。

以LGBMRegressor模型为例,分别设置了“max_depth”,“subsample”,“colsample_bytree”,“min_child_weight”,它的评分器为“r2”,最大迭代次数为20,代码示例如下:

# 导入LGBMRegressor 
from lightgbm import LGBMRegressor
?
# 导入网格搜索 
from sklearn.model_selection import train_test_split, RandomizedSearchCV
?
# 可用于声明参数分布 
import scipy.stats as stats
?
import pandas as pd
import numpy as np
?
# 导入数据集,将数据集拆分为训练/测试集 
df = pd.read_csv('test.csv',index_col=0)
y = df['Target']
X = df.drop(['Target'],axis=1)
X_train0, X_test, y_train0, y_test = train_test_split(X,y,test_size=0.2, random_state= 2)
?
# 训练集的比例 
r = 0.1 
trainLen = round(len(X_train0)*(1-r))
?
# 拆分训练集和验证集 
X_train = X_train0.iloc[:trainLen,:]
y_train = y_train0[:trainLen]
X_val = X_train0.iloc[trainLen:,:]
y_val = y_train0[trainLen:]
?
# 定义网格搜索空间 
randParams = {
    'max_depth': stats.randint(1,10), # 介于1到10的整数 
    'subsample': stats.uniform(0.6,1.0-0.6), # 介于0.6到1的值 
    'colsample_bytree': stats.uniform(0.6,1.0-0.6), # 介于0.6到1的值 
    'min_child_weight': stats.uniform(0.1,10.0-0.1), # 介于0.6到1的值  
}
?
# 定义lightgbm和网格搜索 
reg = LGBMRegressor(learning_rate=0.1, n_estimators=1000, random_state=1000)
reg_randsearch = RandomizedSearchCV(reg, randParams, cv=5, n_iter=20, scoring='r2', n_jobs=-1, random_state=2222) 
?
# 训练模型 
reg_randsearch.fit(X_train, y_train, early_stopping_rounds=100, eval_set=(X_val,y_val))
## Final l2 was l2: 0.0212662.
?
# 返回最佳参数 
reg_randsearch.best_params_ 

代码参考:https://gist.githubusercontent.com/daydreamersjp/d3e60e613f51bd223f8f153dca2ccb12/raw/8a2f28858a07e0f3e5878d2d3375780a63a80df4/gistfile2019120802.py

2.4 贝叶斯搜索

贝叶斯搜索又名贝叶斯优化。它是基于贝叶斯规则(如下图所示),贝叶斯搜索是从随机搜索开始,基于贝叶斯理论逐渐缩小搜索空间,即通过随机搜索将可能超参数的先验分布更新为后验分布。在考虑已知信息下帮助缩小“好的”超参数组合的搜索空间。 相较随机搜索而言,贝叶斯搜索会花费更多时间,但仍比网格搜索花费更多时间。原理详见如下链接。


图片来源:luminousmen

贝叶斯搜索的优势:

  • 搜索的效率较高。

贝叶斯搜索的劣势:

  • 可能会落入局布最优化陷阱。

scikit-learn不提供贝叶斯随机搜索的模块,因此,此处代码略。


(1)获取更多优质内容及精彩资讯,可前往:https://www.cda.cn/?seo

(2)了解更多数据领域的优质课程:

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码