原文:
www.kdnuggets.com/2020/04/hyperparameter-tuning-python.html
评论
作者:Jakub Czakon,Neptune.ai。
你写了一个训练和评估机器学习模型的 Python 脚本。现在,你希望自动调整超参数以提高其性能吗?
我明白了!
在这篇文章中,我将向你展示如何将你的脚本转换为一个目标函数,该函数可以使用任何超参数优化库进行优化。
只需 3 个步骤,你就可以像没有明天一样调整模型参数。
准备好了吗?
开始吧!
我猜你的 main.py 脚本大致如下:
import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import train_test_split
data = pd.read_csv('data/train.csv', nrows=10000)
X = data.drop(['ID_code', 'target'], axis=1)
y = data['target']
(X_train, X_valid,
y_train, y_valid )= train_test_split(X, y, test_size=0.2, random_state=1234)
train_data = lgb.Dataset(X_train, label=y_train)
valid_data = lgb.Dataset(X_valid, label=y_valid, reference=train_data)
params = {'objective': 'binary',
'metric': 'auc',
'learning_rate': 0.4,
'max_depth': 15,
'num_leaves': 20,
'feature_fraction': 0.8,
'subsample': 0.2}
model = lgb.train(params, train_data,
num_boost_round=300,
early_stopping_rounds=30,
valid_sets=[valid_data],
valid_names=['valid'])
score = model.best_score['valid']['auc']
print('validation AUC:', score)
将你想要调整的参数放在脚本顶部的一个字典中。通过这样做,你有效地将搜索参数与代码的其余部分解耦。
import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import train_test_split
SEARCH_PARAMS = {'learning_rate': 0.4,
'max_depth': 15,
'num_leaves': 20,
'feature_fraction': 0.8,
'subsample': 0.2}
data = pd.read_csv('../data/train.csv', nrows=10000)
X = data.drop(['ID_code', 'target'], axis=1)
y = data['target']
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=1234)
train_data = lgb.Dataset(X_train, label=y_train)
valid_data = lgb.Dataset(X_valid, label=y_valid, reference=train_data)
params = {'objective': 'binary',
'metric': 'auc',
**SEARCH_PARAMS}
model = lgb.train(params, train_data,
num_boost_round=300,
early_stopping_rounds=30,
valid_sets=[valid_data],
valid_names=['valid'])
score = model.best_score['valid']['auc']
print('validation AUC:', score)
现在,你可以将整个训练和评估逻辑放入一个 train_evaluate 函数中。这个函数接受参数作为输入,并输出验证分数。
import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import train_test_split
SEARCH_PARAMS = {'learning_rate': 0.4,
'max_depth': 15,
'num_leaves': 20,
'feature_fraction': 0.8,
'subsample': 0.2}
def train_evaluate(search_params):
data = pd.read_csv('../data/train.csv', nrows=10000)
X = data.drop(['ID_code', 'target'], axis=1)
y = data['target']
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=1234)
train_data = lgb.Dataset(X_train, label=y_train)
valid_data = lgb.Dataset(X_valid, label=y_valid, reference=train_data)
params = {'objective': 'binary',
'metric': 'auc',
**search_params}
model = lgb.train(params, train_data,
num_boost_round=300,
early_stopping_rounds=30,
valid_sets=[valid_data],
valid_names=['valid'])
score = model.best_score['valid']['auc']
return score
if __name__ == '__main__':
score = train_evaluate(SEARCH_PARAMS)
print('validation AUC:', score)
我们快到了。
现在你需要做的就是将这个 train_evaluate 函数用作你选择的黑箱优化库的目标。
我将使用 Scikit Optimize,我在另一篇文章中详细描述了它,但你可以使用任何超参数优化库。
简而言之,我:
-
定义搜索 SPACE,
-
创建需要最小化的 objective 函数,
-
通过 forest_minimize 函数运行优化。
在这个例子中,我尝试了 100 种不同的配置,从 10 组随机选择的参数集开始。
import skopt
from script_step2 import train_evaluate
SPACE = [
skopt.space.Real(0.01, 0.5, name='learning_rate', prior='log-uniform'),
skopt.space.Integer(1, 30, name='max_depth'),
skopt.space.Integer(2, 100, name='num_leaves'),
skopt.space.Real(0.1, 1.0, name='feature_fraction', prior='uniform'),
skopt.space.Real(0.1, 1.0, name='subsample', prior='uniform')]
@skopt.utils.use_named_args(SPACE)
def objective(**params):
return -1.0 * train_evaluate(params)
results = skopt.forest_minimize(objective, SPACE, n_calls=30, n_random_starts=10)
best_auc = -1.0 * results.fun
best_params = results.x
print('best result: ', best_auc)
print('best parameters: ', best_params)
就这些了。
results 对象包含关于 最佳分数 和参数 的信息。
注意:
如果你想在训练完成后可视化你的训练并保存诊断图表,那么你可以添加一个回调和一个函数调用,记录每次超参数搜索到 Neptune。只需使用这个 来自 neptune-contrib 的帮助函数 库。
import neptune
import neptunecontrib.monitoring.skopt as sk_utils
import skopt
from script_step2 import train_evaluate
neptune.init('jakub-czakon/blog-hpo')
neptune.create_experiment('hpo-on-any-script', upload_source_files=['*.py'])
SPACE = [
skopt.space.Real(0.01, 0.5, name='learning_rate', prior='log-uniform'),
skopt.space.Integer(1, 30, name='max_depth'),
skopt.space.Integer(2, 100, name='num_leaves'),
skopt.space.Real(0.1, 1.0, name='feature_fraction', prior='uniform'),
skopt.space.Real(0.1, 1.0, name='subsample', prior='uniform')]
@skopt.utils.use_named_args(SPACE)
def objective(**params):
return -1.0 * train_evaluate(params)
monitor = sk_utils.NeptuneMonitor()
results = skopt.forest_minimize(objective, SPACE, n_calls=100, n_random_starts=10, callback=[monitor])
sk_utils.log_results(results)
neptune.stop()
现在,当你运行参数扫描时,你会看到以下内容:
查看 skopt 超参数扫描实验 ,包含所有代码、图表和结果。
在这篇文章中,你已经学会了如何在仅仅 3 个步骤中优化几乎任何 Python 脚本的超参数。
希望通过这些知识,您能以更少的努力构建更好的机器学习模型。
祝学习愉快!
原文。转载已获许可。
相关:
1. 谷歌网络安全证书 - 快速进入网络安全职业轨道。
2. 谷歌数据分析专业证书 - 提升您的数据分析技能
3. 谷歌 IT 支持专业证书 - 支持您的组织进行 IT 相关工作