建模领域有一个公认的观点,那就是数据决定模型的上限,而算法和参数的选择会让模型不断逼近这个上限。
在机器学习建模中,有一个重要且耗时的模块,那就是调参。
Optuna是一个用于超参数优化的开源自动化调参框架,它可以帮助建模工程师在机器学习模型训练过程中自动搜索最佳的超参数组合,从而提高模型的性能和泛化能力。
本文接下来将详细阐述Optuna的安装和使用。
什么是风控建模中的参数和超参数?
1.1 参数
1.2 超参数
什么是模型调参?
Optuna安装
应用Optuna库对车贷lgb模型调参
4.1 导入数据
4.2 看下数据基本情况
4.3 把数据集拆分成训练集和测试集
4.4 应用optuna选择模型最优参数
Optuna调参的优点和缺点
在风控建模中,参数和超参数是两个关键但不同的概念,它们在模型训练和使用过程中扮演着不同的角色。以下是对这两个概念的简要描述:
1 参数(Parameters)
定义:参数是模型内部的可学习变量,它们在模型训练过程中通过从数据中学习而得到。参数代表了模型的知识和能力,用于进行预测。
在风控建模中,模型调参是指对模型超参数的调整和选择,以优化模型的性能。
模型调参是一个关键的步骤,以下是几种常见的调参方法:
1.手动调参:指建模人员基于对数据和算法的理解,以及对目标的影响分析,手动调整特定参数的值。例如,可以调整决策树中的“最大树深度”参数,观察其对模型性能的影响。这种调参方法的优点是:时间成本低,能对症下药,快速解决问题。
2.网格搜索:通过指定一组不同的参数值,将参数空间划分成网格,遍历网格中的每个参数组合,并评估模型在不同参数组合下的性能,最终选择表现最好的参数组合作为最优参数。
3.随机搜索:与网格搜索不同,随机搜索在参数空间中随机选择一组参数组合进行评估。这种调参方法的优点是:可以更高效地搜索参数空间,特别是当参数较多时,随机搜索往往比网格搜索更具实用性。
4.贝叶斯优化:一种基于贝叶斯统计学的全局优化方法,其核心思想是通过构建一个代表目标函数的后验概率模型来指导搜索过程。这个后验概率模型不仅考虑了目标函数的历史观测值,还融入了关于目标函数形状的先验知识。通过不断更新和优化这个模型,贝叶斯优化能够在未知的目标函数空间中进行有效的探索和利用,从而快速找到最优解。
接下来详细阐述模型调参工具Optuna,如果想使用它,首先需安装optuna库,代码如下:
pip install optuna -i https://pypi.tuna.tsinghua.edu.cn/simple
显示结果:
说明已经安装成功。
或者直接运用
pip install optuna
显示结果:
也可以安装成功。
项目背景:由于公司发展车贷业务,需要判断新进来的申请人有多大的概率会逾期,根据逾期的概率和资金的松紧程度决定是否放贷。
现在有一批历史上是否违约的客户样本数据(由于数据涉及安全问题,也是职业操守要求,故此数据不是原始数据,是经过处理的)。
想根据这批历史数据训练lgb模型,通过模型得分划分样本空间。从而决定申请人是通过、转人工核验还是拒绝。
1 导入数据
用pandas库导入待建模的csv格式数据。
import os
import numpy as np
import pandas as pd
os.chdir(r'F:\公众号\105_optuna')
date = pd.read_csv('testtdmodel1.csv', encoding='gbk')
注1:数据可直接在风控建模交流群中下载使用 注2:由于数据中存在中文,如果不使用encoding对编码进行申明会报如下错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 2: invalid start byte
把endcoding的值设置为gb18030或gbk可以解决此类问题,成功导入数据。
2 看下数据基本情况
2.1 用head函数看下数据表头和前几行数据
我选择看前两行的数据,如果括号里为空默认展示前五行的数据,可以根据需要把2改为你想展示的行数。也可以用tail函数展示后几行数据。
data.head(2)
结果:
2.2 用value_counts函数观测因变量y的数据分布
在信贷中,有些客户因为忘记了还款日期、或者资金在短期内存在缺口(不是恶意不还),可能会导致几天的逾期,在催收后会及时还款。
故一般不把历史逾期不超过x天(根据公司的实际业务情况和数据分析结果得出)的客户定义为坏客户(这里的坏不是坏人的意思,纯粹指逾期超过x天的客户)。
在本文把逾期超过20天的客户标签y定义为1(坏客户),没有逾期和逾期不超过20天的客户标签y定义为0(好客户)。
data.y.value_counts()
得到结果:
本文总计样本数量为7252,其中7155个样本是好客户,97个样本是坏客户。说明0和1的分布很不均匀,我们统计一下占比:
发现0的占比达到了98.6%,1的占比不到2%。
3 把数据集拆分成训练集和测试集
接着把数据集拆分成训练集和验证集,一部分用于训练,一部分用于验证,代码如下:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(date, date.y, test_size=0.3)
x_col = date.columns[6:]
X_train_f = X_train[x_col]
X_test_f = X_test[x_col]
Xtrain_date = X_train_f.copy()
Xtrain_date['y'] = y_train
Xtest_date = X_test_f.copy()
Xtest_date['y'] = y_test
print(Xtrain_date.shape, Xtest_date.shape)
得到结果: (5076, 40) (2176, 40)
打印训练集X_train_f前几行看下,代码如下:
X_train_f.head(5)
得到结果:
4 应用optuna选择模型最优参数
首先应用准确性指标评估模型效果来寻找lgb模型的最优参数,代码如下:
import optuna
import lightgbm as lgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 定义目标函数
def objective(trial):
# 设置LightGBM的参数
params = {
'objective': 'binary', # 二分类问题
'metric': 'binary_logloss', # 评估指标
'num_leaves': trial.suggest_int('num_leaves', 2, 128), # 叶子节点数
'max_depth': trial.suggest_int('max_depth', 3, 16), # 树的最大深度
'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.3, log=True), # 学习率
'n_estimators': trial.suggest_int('n_estimators', 10, 1000), # 迭代次数
'subsample': trial.suggest_uniform('subsample', 0.5, 1.0), # 用于训练的数据的比例
'colsample_bytree': trial.suggest_uniform('colsample_bytree', 0.5, 1.0), # 用于构建树的列的比例
}
# 创建LightGBM分类器
gbm = lgb.LGBMClassifier(**params)
# 训练模型
gbm.fit(X_train_f, y_train, eval_set=[(X_test_f, y_test)], eval_metric='binary_logloss', early_stopping_rounds=10)
# 预测测试集
y_pred = gbm.predict(X_test_f)
# 计算准确率并返回
accuracy = accuracy_score(y_test, y_pred)
return 1.0 - accuracy # Optuna试图最小化目标函数,所以我们返回1减去准确率
# 创建Optuna研究
study = optuna.create_study(direction='minimize')
# 运行优化
study.optimize(objective, n_trials=100)
# 打印最佳参数
print('Best params:', study.best_params)
print('Best value (1 - accuracy):', study.best_value)
best_params = {k: int(v) if isinstance(v, float) and v.is_integer() else v for k, v in study.best_params.items()}
gbm = lgb.LGBMClassifier(**best_params)
gbm.fit(X_train_f, y_train)
y_pred = gbm.predict(X_test_f)
print(best_params)
print('Actual Accuracy:', accuracy_score(y_test, y_pred))
{'num_leaves': 64, 'max_depth': 5, 'learning_rate': 0.02634957237668736, 'n_estimators': 434, 'subsample': 0.5988681661566823, 'colsample_bytree': 0.9053285139364518}
Actual Accuracy: 0.9852941176470589
import optuna
import lightgbm as lgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_auc_score
# 定义目标函数
def objective(trial):
# 设置LightGBM的参数
params = {
'objective': 'binary', # 二分类问题
'num_leaves': trial.suggest_int('num_leaves', 2, 128), # 叶子节点数
'max_depth': trial.suggest_int('max_depth', 3, 16), # 树的最大深度
'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.3, log=True), # 学习率
'n_estimators': trial.suggest_int('n_estimators', 10, 1000), # 迭代次数
'subsample': trial.suggest_uniform('subsample', 0.5, 1.0), # 用于训练的数据的比例
'colsample_bytree': trial.suggest_uniform('colsample_bytree', 0.5, 1.0), # 用于构建树的列的比例
}
# 创建LightGBM分类器
gbm = lgb.LGBMClassifier(**params)
# 训练模型
gbm.fit(X_train_f, y_train, eval_set=[(X_test_f, y_test)], eval_metric='auc', early_stopping_rounds=10)
# 预测测试集
y_pred = gbm.predict(X_test_f)
# 计算准确率并返回
auc = roc_auc_score(y_test, y_pred)
return 1.0 - auc # Optuna试图最小化目标函数,所以我们返回1减去准确率
# 创建Optuna研究
study2 = optuna.create_study(direction='minimize')
# 运行优化
study2.optimize(objective, n_trials=100)
# 打印最佳参数
print('Best params:', study2.best_params)
print('Best value (1 - accuracy):', study2.best_value)
# 如果你想要使用最佳参数重新训练模型
best_params2 = {k: int(v) if isinstance(v, float) and v.is_integer() else v for k, v in study2.best_params.items()}
gbm2 = lgb.LGBMClassifier(**best_params2)
gbm2.fit(X_train_f, y_train)
y_pred2 = gbm2.predict(X_test_f)
print(best_params2)
print('AUC:', roc_auc_score(y_test, y_pred2))
{'num_leaves': 86, 'max_depth': 3, 'learning_rate': 0.29839108995009483, 'n_estimators': 440, 'subsample': 0.8129511383560055, 'colsample_bytree': 0.9532167533945617}
AUC: 0.4983698183511877
Optuna调参的优缺点如下:
1 优点
1:轻量级、多功能和跨平台:Optuna的依赖较少,安装简单,可以在不同的平台上运行,并且可以处理各种不同的任务。
2:自动化:Optuna能自动搜索最佳超参数组合,节省时间和精力。
3:灵活:支持多种优化算法,用户可以根据需求选择。
4:高效:Optuna采用最先进的超参数采样算法和最有效的对无望试验进行剪枝的算法,能够更快地找到最优解,并且避免了浪费资源在无效的试验上。
5:易用的并行优化:Optuna可以很容易地扩展到多个worker上进行并行优化,帮助用户更快地完成超参数搜索,并且可以根据需要增加或减少worker数量。
6.模块化:使用运行时定义的API,帮助用户编写高度模块化的代码。
7.丰富的可视化功能:Optuna提供了可视化工具,如查询优化记录、绘制学习曲线等,可以帮助用户更好地理解试验结果和选择最优的超参数组合。
Optuna支持多种优化算法,包括随机搜索、网格搜索、贝叶斯优化等,用户可以根据自己的需求选择合适的算法。
2 缺点
1:计算资源:可能需要较多的计算资源来进行大量的超参数搜素。
2:适用范围:可能对于某些特定类型的模型或问题,可能不如其他方法有效。
至此,optuna库介绍就分享完了,对风控建模感兴趣的小伙伴欢迎加群讨论。 【部分群限时免费进】分群讨论学习Python、玩转Python、风控建模【29.9元进】、人工智能、数据分析相关问题,还提供招聘内推信息、优秀文章、学习视频、公众号文章答疑,也可交流工作中遇到的难题。如需添加微信号19967879837,加时备注想进的群,比如风控建模。
一文囊括风控模型搭建(原理+Python实现),持续更新。。。
不同工作年限风控建模岗薪资水平如何?招聘最看重面试者什么能力?
100天精通风控建模(原理+Python实现)——第32天:集成学习是什么?在风控建模中有哪些应用?
限时免费加群
19967879837
添加微信号、手机号