Skip to content

Latest commit

 

History

History
269 lines (176 loc) · 9.33 KB

hyperparameter-tuning-python.md

File metadata and controls

269 lines (176 loc) · 9.33 KB

如何在 3 个简单步骤中对任何 Python 脚本进行超参数调优

原文:www.kdnuggets.com/2020/04/hyperparameter-tuning-python.html

评论

作者:Jakub Czakon,Neptune.ai

Python

你写了一个训练和评估机器学习模型的 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 相关工作


更多相关主题