{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Copyright (c) 2020-2021 Microsoft Corporation. All rights reserved. \n", "\n", "Licensed under the MIT License.\n", "\n", "# Tune LightGBM with FLAML Library\n", "\n", "\n", "## 1. Introduction\n", "\n", "FLAML is a Python library (https://github.com/microsoft/FLAML) designed to automatically produce accurate machine learning models \n", "with low computational cost. It is fast and cheap. The simple and lightweight design makes it easy \n", "to use and extend, such as adding new learners. FLAML can \n", "- serve as an economical AutoML engine,\n", "- be used as a fast hyperparameter tuning tool, or \n", "- be embedded in self-tuning software that requires low latency & resource in repetitive\n", " tuning tasks.\n", "\n", "In this notebook, we demonstrate how to use FLAML library to tune hyperparameters of LightGBM with a regression example.\n", "\n", "FLAML requires `Python>=3.6`. To run this notebook example, please install flaml with the `notebook` option:\n", "```bash\n", "pip install flaml[notebook]\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install flaml[notebook];" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 2. Regression Example\n", "### Load data and preprocess\n", "\n", "Download [houses dataset](https://www.openml.org/d/537) from OpenML. The task is to predict median price of the house in the region based on demographic composition and a state of housing market in the region." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "slideshow": { "slide_type": "subslide" }, "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": "load dataset from./openml_ds537.pkl\nDataset name:houses\nX_train.shape: (15480, 8), y_train.shape: (15480,);\nX_test.shape: (5160, 8), y_test.shape: (5160,)\n" } ], "source": [ "from flaml.data import load_openml_dataset\n", "X_train, X_test, y_train, y_test = load_openml_dataset(dataset_id=537, data_dir='./')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Run FLAML\n", "In the FLAML automl run configuration, users can specify the task type, time budget, error metric, learner list, whether to subsample, resampling strategy type, and so on. All these arguments have default values which will be used if users do not provide them. " ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "slideshow": { "slide_type": "slide" }, "tags": [] }, "outputs": [], "source": [ "''' import AutoML class from flaml package '''\n", "from flaml import AutoML\n", "automl = AutoML()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "settings = {\n", " \"time_budget\": 120, # total running time in seconds\n", " \"metric\": 'r2', # primary metrics for regression can be chosen from: ['mae','mse','r2']\n", " \"estimator_list\": ['lgbm'], # list of ML learners; we tune lightgbm in this example\n", " \"task\": 'regression', # task type \n", " \"log_file_name\": 'houses_experiment.log', # flaml log file\n", "}" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "slideshow": { "slide_type": "slide" }, "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stderr", "text": "[flaml.automl: 04-09 19:57:58] {890} INFO - Evaluation method: cv\n[flaml.automl: 04-09 19:57:58] {606} INFO - Using RepeatedKFold\n[flaml.automl: 04-09 19:57:58] {911} INFO - Minimizing error metric: 1-r2\n[flaml.automl: 04-09 19:57:58] {930} INFO - List of ML learners in AutoML Run: ['lgbm']\n[flaml.automl: 04-09 19:57:58] {994} INFO - iteration 0, current learner lgbm\n[flaml.automl: 04-09 19:57:58] {1147} INFO - at 0.2s,\tbest lgbm's error=0.7383,\tbest lgbm's error=0.7383\n[flaml.automl: 04-09 19:57:58] {994} INFO - iteration 1, current learner lgbm\n[flaml.automl: 04-09 19:57:58] {1147} INFO - at 0.3s,\tbest lgbm's error=0.7383,\tbest lgbm's error=0.7383\n[flaml.automl: 04-09 19:57:58] {994} INFO - iteration 2, current learner lgbm\n[flaml.automl: 04-09 19:57:59] {1147} INFO - at 0.3s,\tbest lgbm's error=0.3888,\tbest lgbm's error=0.3888\n[flaml.automl: 04-09 19:57:59] {994} INFO - iteration 3, current learner lgbm\n[flaml.automl: 04-09 19:57:59] {1147} INFO - at 0.4s,\tbest lgbm's error=0.3888,\tbest lgbm's error=0.3888\n[flaml.automl: 04-09 19:57:59] {994} INFO - iteration 4, current learner lgbm\n[flaml.automl: 04-09 19:57:59] {1147} INFO - at 0.6s,\tbest lgbm's error=0.2657,\tbest lgbm's error=0.2657\n[flaml.automl: 04-09 19:57:59] {994} INFO - iteration 5, current learner lgbm\n[flaml.automl: 04-09 19:57:59] {1147} INFO - at 0.8s,\tbest lgbm's error=0.2256,\tbest lgbm's error=0.2256\n[flaml.automl: 04-09 19:57:59] {994} INFO - iteration 6, current learner lgbm\n[flaml.automl: 04-09 19:57:59] {1147} INFO - at 0.9s,\tbest lgbm's error=0.2256,\tbest lgbm's error=0.2256\n[flaml.automl: 04-09 19:57:59] {994} INFO - iteration 7, current learner lgbm\n[flaml.automl: 04-09 19:57:59] {1147} INFO - at 1.1s,\tbest lgbm's error=0.2256,\tbest lgbm's error=0.2256\n[flaml.automl: 04-09 19:57:59] {994} INFO - iteration 8, current learner lgbm\n[flaml.automl: 04-09 19:57:59] {1147} INFO - at 1.2s,\tbest lgbm's error=0.2256,\tbest lgbm's error=0.2256\n[flaml.automl: 04-09 19:57:59] {994} INFO - iteration 9, current learner lgbm\n[flaml.automl: 04-09 19:58:00] {1147} INFO - at 1.4s,\tbest lgbm's error=0.2256,\tbest lgbm's error=0.2256\n[flaml.automl: 04-09 19:58:00] {994} INFO - iteration 10, current learner lgbm\n[flaml.automl: 04-09 19:58:00] {1147} INFO - at 1.5s,\tbest lgbm's error=0.2256,\tbest lgbm's error=0.2256\n[flaml.automl: 04-09 19:58:00] {994} INFO - iteration 11, current learner lgbm\n[flaml.automl: 04-09 19:58:00] {1147} INFO - at 2.0s,\tbest lgbm's error=0.2099,\tbest lgbm's error=0.2099\n[flaml.automl: 04-09 19:58:00] {994} INFO - iteration 12, current learner lgbm\n[flaml.automl: 04-09 19:58:01] {1147} INFO - at 2.9s,\tbest lgbm's error=0.2099,\tbest lgbm's error=0.2099\n[flaml.automl: 04-09 19:58:01] {994} INFO - iteration 13, current learner lgbm\n[flaml.automl: 04-09 19:58:01] {1147} INFO - at 3.0s,\tbest lgbm's error=0.2099,\tbest lgbm's error=0.2099\n[flaml.automl: 04-09 19:58:01] {994} INFO - iteration 14, current learner lgbm\n[flaml.automl: 04-09 19:58:03] {1147} INFO - at 4.7s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:03] {994} INFO - iteration 15, current learner lgbm\n[flaml.automl: 04-09 19:58:04] {1147} INFO - at 5.3s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:04] {994} INFO - iteration 16, current learner lgbm\n[flaml.automl: 04-09 19:58:13] {1147} INFO - at 14.6s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:13] {994} INFO - iteration 17, current learner lgbm\n[flaml.automl: 04-09 19:58:14] {1147} INFO - at 15.4s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:14] {994} INFO - iteration 18, current learner lgbm\n[flaml.automl: 04-09 19:58:18] {1147} INFO - at 20.0s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:18] {994} INFO - iteration 19, current learner lgbm\n[flaml.automl: 04-09 19:58:19] {1147} INFO - at 20.7s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:19] {994} INFO - iteration 20, current learner lgbm\n[flaml.automl: 04-09 19:58:20] {1147} INFO - at 21.9s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:20] {994} INFO - iteration 21, current learner lgbm\n[flaml.automl: 04-09 19:58:20] {1147} INFO - at 22.3s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:20] {994} INFO - iteration 22, current learner lgbm\n[flaml.automl: 04-09 19:58:25] {1147} INFO - at 27.2s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:25] {994} INFO - iteration 23, current learner lgbm\n[flaml.automl: 04-09 19:58:28] {1147} INFO - at 29.6s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:28] {994} INFO - iteration 24, current learner lgbm\n[flaml.automl: 04-09 19:58:29] {1147} INFO - at 30.7s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:29] {994} INFO - iteration 25, current learner lgbm\n[flaml.automl: 04-09 19:58:30] {1147} INFO - at 31.7s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:30] {994} INFO - iteration 26, current learner lgbm\n[flaml.automl: 04-09 19:58:32] {1147} INFO - at 34.1s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:32] {994} INFO - iteration 27, current learner lgbm\n[flaml.automl: 04-09 19:58:33] {1147} INFO - at 34.6s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:33] {994} INFO - iteration 28, current learner lgbm\n[flaml.automl: 04-09 19:58:35] {1147} INFO - at 36.4s,\tbest lgbm's error=0.1644,\tbest lgbm's error=0.1644\n[flaml.automl: 04-09 19:58:35] {994} INFO - iteration 29, current learner lgbm\n[flaml.automl: 04-09 19:58:42] {1147} INFO - at 44.3s,\tbest lgbm's error=0.1604,\tbest lgbm's error=0.1604\n[flaml.automl: 04-09 19:58:42] {994} INFO - iteration 30, current learner lgbm\n[flaml.automl: 04-09 19:58:43] {1147} INFO - at 44.9s,\tbest lgbm's error=0.1604,\tbest lgbm's error=0.1604\n[flaml.automl: 04-09 19:58:43] {994} INFO - iteration 31, current learner lgbm\n[flaml.automl: 04-09 19:59:01] {1147} INFO - at 62.5s,\tbest lgbm's error=0.1604,\tbest lgbm's error=0.1604\n[flaml.automl: 04-09 19:59:01] {994} INFO - iteration 32, current learner lgbm\n[flaml.automl: 04-09 19:59:06] {1147} INFO - at 68.0s,\tbest lgbm's error=0.1604,\tbest lgbm's error=0.1604\n[flaml.automl: 04-09 19:59:06] {994} INFO - iteration 33, current learner lgbm\n[flaml.automl: 04-09 19:59:07] {1147} INFO - at 68.8s,\tbest lgbm's error=0.1604,\tbest lgbm's error=0.1604\n[flaml.automl: 04-09 19:59:07] {994} INFO - iteration 34, current learner lgbm\n[flaml.automl: 04-09 19:59:57] {1147} INFO - at 118.9s,\tbest lgbm's error=0.1604,\tbest lgbm's error=0.1604\n[flaml.automl: 04-09 19:59:57] {1187} INFO - selected model: LGBMRegressor(colsample_bytree=0.7586723794764185,\n learning_rate=0.10418050364992694, max_bin=127,\n min_child_samples=21, n_estimators=95, num_leaves=254,\n objective='regression', reg_alpha=0.09228337080759572,\n reg_lambda=0.46673178167010676, subsample=0.9097941662911945)\n[flaml.automl: 04-09 19:59:57] {944} INFO - fit succeeded\n" } ], "source": [ "'''The main flaml automl API'''\n", "automl.fit(X_train=X_train, y_train=y_train, **settings)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Best model and metric" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "slideshow": { "slide_type": "slide" }, "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": "Best hyperparmeter config:{'n_estimators': 95.0, 'num_leaves': 254.0, 'min_child_samples': 21.0, 'learning_rate': 0.10418050364992694, 'subsample': 0.9097941662911945, 'log_max_bin': 7.0, 'colsample_bytree': 0.7586723794764185, 'reg_alpha': 0.09228337080759572, 'reg_lambda': 0.46673178167010676}\nBest r2 on validation data: 0.8396\nTraining duration of best run: 7.868 s\n" } ], "source": [ "''' retrieve best config'''\n", "print('Best hyperparmeter config:', automl.best_config)\n", "print('Best r2 on validation data: {0:.4g}'.format(1-automl.best_loss))\n", "print('Training duration of best run: {0:.4g} s'.format(automl.best_config_train_time))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "LGBMRegressor(colsample_bytree=0.7586723794764185,\n learning_rate=0.10418050364992694, max_bin=127,\n min_child_samples=21, n_estimators=95, num_leaves=254,\n objective='regression', reg_alpha=0.09228337080759572,\n reg_lambda=0.46673178167010676, subsample=0.9097941662911945)" }, "metadata": {}, "execution_count": 9 } ], "source": [ "automl.model" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "''' pickle and save the automl object '''\n", "import pickle\n", "with open('automl.pkl', 'wb') as f:\n", " pickle.dump(automl, f, pickle.HIGHEST_PROTOCOL)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "slideshow": { "slide_type": "slide" }, "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": "Predicted labels[150367.25556214 263353.37798151 136897.76625025 ... 190606.68038356\n 237816.02972335 263063.11183796]\nTrue labels[136900. 241300. 200700. ... 160900. 227300. 265600.]\n" } ], "source": [ "''' compute predictions of testing dataset ''' \n", "y_pred = automl.predict(X_test)\n", "print('Predicted labels', y_pred)\n", "print('True labels', y_test)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "slideshow": { "slide_type": "slide" }, "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": "r2=0.8500929784828137\nmse=1981546944.5284543\nmae=29485.579651356835\n" } ], "source": [ "''' compute different metric values on testing dataset'''\n", "from flaml.ml import sklearn_metric_loss_score\n", "print('r2', '=', 1 - sklearn_metric_loss_score('r2', y_pred, y_test))\n", "print('mse', '=', sklearn_metric_loss_score('mse', y_pred, y_test))\n", "print('mae', '=', sklearn_metric_loss_score('mae', y_pred, y_test))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "slideshow": { "slide_type": "subslide" }, "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": "{'Current Learner': 'lgbm', 'Current Sample': 15480, 'Current Hyper-parameters': {'n_estimators': 4, 'num_leaves': 4, 'min_child_samples': 20, 'learning_rate': 0.1, 'subsample': 1.0, 'log_max_bin': 8, 'colsample_bytree': 1.0, 'reg_alpha': 0.0009765625, 'reg_lambda': 1.0}, 'Best Learner': 'lgbm', 'Best Hyper-parameters': {'n_estimators': 4, 'num_leaves': 4, 'min_child_samples': 20, 'learning_rate': 0.1, 'subsample': 1.0, 'log_max_bin': 8, 'colsample_bytree': 1.0, 'reg_alpha': 0.0009765625, 'reg_lambda': 1.0}}\n{'Current Learner': 'lgbm', 'Current Sample': 15480, 'Current Hyper-parameters': {'n_estimators': 4.0, 'num_leaves': 4.0, 'min_child_samples': 25.0, 'learning_rate': 1.0, 'subsample': 0.8513627344387318, 'log_max_bin': 10.0, 'colsample_bytree': 0.9684145930669938, 'reg_alpha': 0.001831177697321707, 'reg_lambda': 0.2790165919053839}, 'Best Learner': 'lgbm', 'Best Hyper-parameters': {'n_estimators': 4.0, 'num_leaves': 4.0, 'min_child_samples': 25.0, 'learning_rate': 1.0, 'subsample': 0.8513627344387318, 'log_max_bin': 10.0, 'colsample_bytree': 0.9684145930669938, 'reg_alpha': 0.001831177697321707, 'reg_lambda': 0.2790165919053839}}\n{'Current Learner': 'lgbm', 'Current Sample': 15480, 'Current Hyper-parameters': {'n_estimators': 20.0, 'num_leaves': 4.0, 'min_child_samples': 48.0, 'learning_rate': 1.0, 'subsample': 0.9814787163243813, 'log_max_bin': 10.0, 'colsample_bytree': 0.9534346594834143, 'reg_alpha': 0.002208534076096185, 'reg_lambda': 0.5460627024738886}, 'Best Learner': 'lgbm', 'Best Hyper-parameters': {'n_estimators': 20.0, 'num_leaves': 4.0, 'min_child_samples': 48.0, 'learning_rate': 1.0, 'subsample': 0.9814787163243813, 'log_max_bin': 10.0, 'colsample_bytree': 0.9534346594834143, 'reg_alpha': 0.002208534076096185, 'reg_lambda': 0.5460627024738886}}\n{'Current Learner': 'lgbm', 'Current Sample': 15480, 'Current Hyper-parameters': {'n_estimators': 11.0, 'num_leaves': 15.0, 'min_child_samples': 42.0, 'learning_rate': 0.4743416464891248, 'subsample': 0.9233328006239466, 'log_max_bin': 10.0, 'colsample_bytree': 1.0, 'reg_alpha': 0.034996420228767956, 'reg_lambda': 0.6169079461473814}, 'Best Learner': 'lgbm', 'Best Hyper-parameters': {'n_estimators': 11.0, 'num_leaves': 15.0, 'min_child_samples': 42.0, 'learning_rate': 0.4743416464891248, 'subsample': 0.9233328006239466, 'log_max_bin': 10.0, 'colsample_bytree': 1.0, 'reg_alpha': 0.034996420228767956, 'reg_lambda': 0.6169079461473814}}\n{'Current Learner': 'lgbm', 'Current Sample': 15480, 'Current Hyper-parameters': {'n_estimators': 22.0, 'num_leaves': 44.0, 'min_child_samples': 33.0, 'learning_rate': 0.7277554644304967, 'subsample': 0.8890322269681047, 'log_max_bin': 9.0, 'colsample_bytree': 0.8917187085424868, 'reg_alpha': 0.3477637978466495, 'reg_lambda': 0.24655709710146537}, 'Best Learner': 'lgbm', 'Best Hyper-parameters': {'n_estimators': 22.0, 'num_leaves': 44.0, 'min_child_samples': 33.0, 'learning_rate': 0.7277554644304967, 'subsample': 0.8890322269681047, 'log_max_bin': 9.0, 'colsample_bytree': 0.8917187085424868, 'reg_alpha': 0.3477637978466495, 'reg_lambda': 0.24655709710146537}}\n{'Current Learner': 'lgbm', 'Current Sample': 15480, 'Current Hyper-parameters': {'n_estimators': 60.0, 'num_leaves': 72.0, 'min_child_samples': 37.0, 'learning_rate': 0.23811059538783155, 'subsample': 1.0, 'log_max_bin': 8.0, 'colsample_bytree': 0.9162072323824675, 'reg_alpha': 0.7017839907881602, 'reg_lambda': 0.23027329389914142}, 'Best Learner': 'lgbm', 'Best Hyper-parameters': {'n_estimators': 60.0, 'num_leaves': 72.0, 'min_child_samples': 37.0, 'learning_rate': 0.23811059538783155, 'subsample': 1.0, 'log_max_bin': 8.0, 'colsample_bytree': 0.9162072323824675, 'reg_alpha': 0.7017839907881602, 'reg_lambda': 0.23027329389914142}}\n{'Current Learner': 'lgbm', 'Current Sample': 15480, 'Current Hyper-parameters': {'n_estimators': 95.0, 'num_leaves': 254.0, 'min_child_samples': 21.0, 'learning_rate': 0.10418050364992694, 'subsample': 0.9097941662911945, 'log_max_bin': 7.0, 'colsample_bytree': 0.7586723794764185, 'reg_alpha': 0.09228337080759572, 'reg_lambda': 0.46673178167010676}, 'Best Learner': 'lgbm', 'Best Hyper-parameters': {'n_estimators': 95.0, 'num_leaves': 254.0, 'min_child_samples': 21.0, 'learning_rate': 0.10418050364992694, 'subsample': 0.9097941662911945, 'log_max_bin': 7.0, 'colsample_bytree': 0.7586723794764185, 'reg_alpha': 0.09228337080759572, 'reg_lambda': 0.46673178167010676}}\n" } ], "source": [ "from flaml.data import get_output_from_log\n", "time_history, best_valid_loss_history, valid_loss_history, config_history, train_loss_history = \\\n", " get_output_from_log(filename=settings['log_file_name'], time_budget=60)\n", "\n", "for config in config_history:\n", " print(config)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "output_type": "display_data", "data": { "text/plain": "
", "image/svg+xml": "\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", "image/png": "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\n" }, "metadata": { "needs_background": "light" } } ], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "plt.title('Learning Curve')\n", "plt.xlabel('Wall Clock Time (s)')\n", "plt.ylabel('Validation r2')\n", "plt.scatter(time_history, 1 - np.array(valid_loss_history))\n", "plt.step(time_history, 1 - np.array(best_valid_loss_history), where='post')\n", "plt.show()" ] }, { "source": [ "## 3. Comparison with alternatives\n", "\n", "### FLAML's accuracy" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": 15, "metadata": { "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": "flaml r2=0.8500929784828137\n" } ], "source": [ "print('flaml r2', '=', 1 - sklearn_metric_loss_score('r2', y_pred, y_test))" ] }, { "source": [ "### Default LightGBM" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "from lightgbm import LGBMRegressor\n", "lgbm = LGBMRegressor()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": "LGBMRegressor()" }, "metadata": {}, "execution_count": 17 } ], "source": [ "lgbm.fit(X_train, y_train)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": "default lgbm r2=0.8296179648694404\n" } ], "source": [ "y_pred = lgbm.predict(X_test)\n", "from flaml.ml import sklearn_metric_loss_score\n", "print('default lgbm r2', '=', 1 - sklearn_metric_loss_score('r2', y_pred, y_test))" ] }, { "source": [ "### Optuna LightGBM Tuner" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [], "source": [ "# !pip install optuna==2.5.0;" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [], "source": [ "from sklearn.model_selection import train_test_split\n", "train_x, val_x, train_y, val_y = train_test_split(X_train, y_train, test_size=0.1)\n", "import optuna.integration.lightgbm as lgb\n", "dtrain = lgb.Dataset(train_x, label=train_y)\n", "dval = lgb.Dataset(val_x, label=val_y)\n", "params = {\n", " \"objective\": \"regression\",\n", " \"metric\": \"regression\",\n", " \"verbosity\": -1,\n", "}\n" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stderr", "text": "\u001b[32m[I 2021-04-09 19:56:13,788]\u001b[0m A new study created in memory with name: no-name-be796674-63fe-4736-9436-82e0a952f36b\u001b[0m\nfeature_fraction, val_score: 2001137767.143790: 14%|#4 | 1/7 [00:02<00:13, 2.30s/it]\u001b[32m[I 2021-04-09 19:56:16,095]\u001b[0m Trial 0 finished with value: 2001137767.14379 and parameters: {'feature_fraction': 0.7}. Best is trial 0 with value: 2001137767.14379.\u001b[0m\nfeature_fraction, val_score: 2001137767.143790: 29%|##8 | 2/7 [00:04<00:11, 2.24s/it]\u001b[32m[I 2021-04-09 19:56:18,289]\u001b[0m Trial 1 finished with value: 2009099143.533758 and parameters: {'feature_fraction': 0.6}. Best is trial 0 with value: 2001137767.14379.\u001b[0m\nfeature_fraction, val_score: 2001137767.143790: 43%|####2 | 3/7 [00:06<00:09, 2.27s/it]\u001b[32m[I 2021-04-09 19:56:20,588]\u001b[0m Trial 2 finished with value: 2001137767.14379 and parameters: {'feature_fraction': 0.8}. Best is trial 0 with value: 2001137767.14379.\u001b[0m\nfeature_fraction, val_score: 2001137767.143790: 57%|#####7 | 4/7 [00:09<00:07, 2.38s/it]\u001b[32m[I 2021-04-09 19:56:23,148]\u001b[0m Trial 3 finished with value: 2017941196.0559783 and parameters: {'feature_fraction': 1.0}. Best is trial 0 with value: 2001137767.14379.\u001b[0m\nfeature_fraction, val_score: 1977065482.707781: 71%|#######1 | 5/7 [00:11<00:04, 2.27s/it]\u001b[32m[I 2021-04-09 19:56:25,222]\u001b[0m Trial 4 finished with value: 1977065482.7077813 and parameters: {'feature_fraction': 0.5}. Best is trial 4 with value: 1977065482.7077813.\u001b[0m\nfeature_fraction, val_score: 1977065482.707781: 71%|#######1 | 5/7 [00:11<00:04, 2.27s/it]" } ], "source": [ "%%time\n", "model = lgb.train(params, dtrain, valid_sets=[dtrain, dval], verbose_eval=10000) \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "y_pred = model.predict(X_test)\n", "from flaml.ml import sklearn_metric_loss_score\n", "print('Optuna LightGBM Tuner r2', '=', 1 - sklearn_metric_loss_score('r2', y_pred, y_test))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Add a customized LightGBM learner in FLAML\n", "The native API of LightGBM allows one to specify a custom objective function in the model constructor. You can easily enable it by adding a customized LightGBM learner in FLAML. In the following example, we show how to add such a customized LightGBM learner with a custom objective function." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create a customized LightGBM learner with a custom objective function" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "\n", "import numpy as np \n", "\n", "''' define your customized objective function '''\n", "def my_loss_obj(y_true, y_pred):\n", " c = 0.5\n", " residual = y_pred - y_true\n", " grad = c * residual /(np.abs(residual) + c)\n", " hess = c ** 2 / (np.abs(residual) + c) ** 2\n", " # rmse grad and hess\n", " grad_rmse = residual\n", " hess_rmse = 1.0\n", " \n", " # mae grad and hess\n", " grad_mae = np.array(residual)\n", " grad_mae[grad_mae > 0] = 1.\n", " grad_mae[grad_mae <= 0] = -1.\n", " hess_mae = 1.0\n", "\n", " coef = [0.4, 0.3, 0.3]\n", " return coef[0] * grad + coef[1] * grad_rmse + coef[2] * grad_mae, \\\n", " coef[0] * hess + coef[1] * hess_rmse + coef[2] * hess_mae\n", "\n", "\n", "from flaml.model import LGBMEstimator\n", "\n", "''' create a customized LightGBM learner class with your objective function '''\n", "class MyLGBM(LGBMEstimator):\n", " '''LGBMEstimator with my_loss_obj as the objective function\n", " '''\n", "\n", " def __init__(self, **params):\n", " super().__init__(objective=my_loss_obj, **params)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Add the customized learner in FLAML" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stderr", "text": "[flaml.automl: 04-09 21:16:36] {890} INFO - Evaluation method: cv\n[flaml.automl: 04-09 21:16:36] {606} INFO - Using RepeatedKFold\n[flaml.automl: 04-09 21:16:36] {911} INFO - Minimizing error metric: 1-r2\n[flaml.automl: 04-09 21:16:36] {930} INFO - List of ML learners in AutoML Run: ['my_lgbm']\n[flaml.automl: 04-09 21:16:36] {994} INFO - iteration 0, current learner my_lgbm\n[flaml.automl: 04-09 21:16:37] {1147} INFO - at 0.2s,\tbest my_lgbm's error=2.9883,\tbest my_lgbm's error=2.9883\n[flaml.automl: 04-09 21:16:37] {994} INFO - iteration 1, current learner my_lgbm\n[flaml.automl: 04-09 21:16:37] {1147} INFO - at 0.3s,\tbest my_lgbm's error=2.9883,\tbest my_lgbm's error=2.9883\n[flaml.automl: 04-09 21:16:37] {994} INFO - iteration 2, current learner my_lgbm\n[flaml.automl: 04-09 21:16:37] {1147} INFO - at 0.4s,\tbest my_lgbm's error=0.4472,\tbest my_lgbm's error=0.4472\n[flaml.automl: 04-09 21:16:37] {994} INFO - iteration 3, current learner my_lgbm\n[flaml.automl: 04-09 21:16:37] {1147} INFO - at 0.5s,\tbest my_lgbm's error=0.4472,\tbest my_lgbm's error=0.4472\n[flaml.automl: 04-09 21:16:37] {994} INFO - iteration 4, current learner my_lgbm\n[flaml.automl: 04-09 21:16:37] {1147} INFO - at 0.7s,\tbest my_lgbm's error=0.2682,\tbest my_lgbm's error=0.2682\n[flaml.automl: 04-09 21:16:37] {994} INFO - iteration 5, current learner my_lgbm\n[flaml.automl: 04-09 21:16:37] {1147} INFO - at 0.9s,\tbest my_lgbm's error=0.2682,\tbest my_lgbm's error=0.2682\n[flaml.automl: 04-09 21:16:37] {994} INFO - iteration 6, current learner my_lgbm\n[flaml.automl: 04-09 21:16:37] {1147} INFO - at 1.1s,\tbest my_lgbm's error=0.2682,\tbest my_lgbm's error=0.2682\n[flaml.automl: 04-09 21:16:37] {994} INFO - iteration 7, current learner my_lgbm\n[flaml.automl: 04-09 21:16:38] {1147} INFO - at 1.3s,\tbest my_lgbm's error=0.2256,\tbest my_lgbm's error=0.2256\n[flaml.automl: 04-09 21:16:38] {994} INFO - iteration 8, current learner my_lgbm\n[flaml.automl: 04-09 21:16:38] {1147} INFO - at 1.5s,\tbest my_lgbm's error=0.2256,\tbest my_lgbm's error=0.2256\n[flaml.automl: 04-09 21:16:38] {994} INFO - iteration 9, current learner my_lgbm\n[flaml.automl: 04-09 21:16:38] {1147} INFO - at 1.6s,\tbest my_lgbm's error=0.2256,\tbest my_lgbm's error=0.2256\n[flaml.automl: 04-09 21:16:38] {994} INFO - iteration 10, current learner my_lgbm\n[flaml.automl: 04-09 21:16:38] {1147} INFO - at 1.8s,\tbest my_lgbm's error=0.2256,\tbest my_lgbm's error=0.2256\n[flaml.automl: 04-09 21:16:38] {994} INFO - iteration 11, current learner my_lgbm\n[flaml.automl: 04-09 21:16:39] {1147} INFO - at 2.3s,\tbest my_lgbm's error=0.1866,\tbest my_lgbm's error=0.1866\n[flaml.automl: 04-09 21:16:39] {994} INFO - iteration 12, current learner my_lgbm\n[flaml.automl: 04-09 21:16:39] {1147} INFO - at 2.9s,\tbest my_lgbm's error=0.1866,\tbest my_lgbm's error=0.1866\n[flaml.automl: 04-09 21:16:39] {994} INFO - iteration 13, current learner my_lgbm\n[flaml.automl: 04-09 21:16:39] {1147} INFO - at 3.1s,\tbest my_lgbm's error=0.1866,\tbest my_lgbm's error=0.1866\n[flaml.automl: 04-09 21:16:39] {994} INFO - iteration 14, current learner my_lgbm\n[flaml.automl: 04-09 21:16:41] {1147} INFO - at 5.0s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:16:41] {994} INFO - iteration 15, current learner my_lgbm\n[flaml.automl: 04-09 21:16:42] {1147} INFO - at 5.6s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:16:42] {994} INFO - iteration 16, current learner my_lgbm\n[flaml.automl: 04-09 21:16:48] {1147} INFO - at 11.9s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:16:48] {994} INFO - iteration 17, current learner my_lgbm\n[flaml.automl: 04-09 21:16:49] {1147} INFO - at 13.1s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:16:49] {994} INFO - iteration 18, current learner my_lgbm\n[flaml.automl: 04-09 21:16:54] {1147} INFO - at 17.7s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:16:54] {994} INFO - iteration 19, current learner my_lgbm\n[flaml.automl: 04-09 21:16:55] {1147} INFO - at 18.3s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:16:55] {994} INFO - iteration 20, current learner my_lgbm\n[flaml.automl: 04-09 21:16:57] {1147} INFO - at 20.2s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:16:57] {994} INFO - iteration 21, current learner my_lgbm\n[flaml.automl: 04-09 21:16:57] {1147} INFO - at 20.5s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:16:57] {994} INFO - iteration 22, current learner my_lgbm\n[flaml.automl: 04-09 21:17:00] {1147} INFO - at 23.9s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:00] {994} INFO - iteration 23, current learner my_lgbm\n[flaml.automl: 04-09 21:17:03] {1147} INFO - at 26.3s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:03] {994} INFO - iteration 24, current learner my_lgbm\n[flaml.automl: 04-09 21:17:04] {1147} INFO - at 27.2s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:04] {994} INFO - iteration 25, current learner my_lgbm\n[flaml.automl: 04-09 21:17:06] {1147} INFO - at 29.6s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:06] {994} INFO - iteration 26, current learner my_lgbm\n[flaml.automl: 04-09 21:17:07] {1147} INFO - at 31.0s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:07] {994} INFO - iteration 27, current learner my_lgbm\n[flaml.automl: 04-09 21:17:08] {1147} INFO - at 31.7s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:08] {994} INFO - iteration 28, current learner my_lgbm\n[flaml.automl: 04-09 21:17:10] {1147} INFO - at 33.3s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:10] {994} INFO - iteration 29, current learner my_lgbm\n[flaml.automl: 04-09 21:17:16] {1147} INFO - at 39.7s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:16] {994} INFO - iteration 30, current learner my_lgbm\n[flaml.automl: 04-09 21:17:16] {1147} INFO - at 40.0s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:16] {994} INFO - iteration 31, current learner my_lgbm\n[flaml.automl: 04-09 21:17:20] {1147} INFO - at 44.1s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:20] {994} INFO - iteration 32, current learner my_lgbm\n[flaml.automl: 04-09 21:17:22] {1147} INFO - at 45.4s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:22] {994} INFO - iteration 33, current learner my_lgbm\n[flaml.automl: 04-09 21:17:22] {1147} INFO - at 45.6s,\tbest my_lgbm's error=0.1639,\tbest my_lgbm's error=0.1639\n[flaml.automl: 04-09 21:17:22] {994} INFO - iteration 34, current learner my_lgbm\n[flaml.automl: 04-09 21:17:35] {1147} INFO - at 59.1s,\tbest my_lgbm's error=0.1610,\tbest my_lgbm's error=0.1610\n[flaml.automl: 04-09 21:17:35] {994} INFO - iteration 35, current learner my_lgbm\n[flaml.automl: 04-09 21:17:59] {1147} INFO - at 82.8s,\tbest my_lgbm's error=0.1610,\tbest my_lgbm's error=0.1610\n[flaml.automl: 04-09 21:17:59] {994} INFO - iteration 36, current learner my_lgbm\n[flaml.automl: 04-09 21:18:06] {1147} INFO - at 89.3s,\tbest my_lgbm's error=0.1610,\tbest my_lgbm's error=0.1610\n[flaml.automl: 04-09 21:18:06] {994} INFO - iteration 37, current learner my_lgbm\n[flaml.automl: 04-09 21:18:12] {1147} INFO - at 95.7s,\tbest my_lgbm's error=0.1610,\tbest my_lgbm's error=0.1610\n[flaml.automl: 04-09 21:18:12] {994} INFO - iteration 38, current learner my_lgbm\n[flaml.automl: 04-09 21:18:20] {1147} INFO - at 103.6s,\tbest my_lgbm's error=0.1610,\tbest my_lgbm's error=0.1610\n[flaml.automl: 04-09 21:18:20] {994} INFO - iteration 39, current learner my_lgbm\n[flaml.automl: 04-09 21:18:36] {1147} INFO - at 119.4s,\tbest my_lgbm's error=0.1610,\tbest my_lgbm's error=0.1610\n[flaml.automl: 04-09 21:18:36] {1187} INFO - selected model: LGBMRegressor(colsample_bytree=0.613734331916688,\n learning_rate=0.06283686776885493, max_bin=1023,\n min_child_samples=81, n_estimators=287, num_leaves=247,\n objective=,\n reg_alpha=0.006495889833184046, reg_lambda=0.005049036990045567,\n subsample=0.7669214501226506)\n[flaml.automl: 04-09 21:18:36] {944} INFO - fit succeeded\n" } ], "source": [ "automl = AutoML()\n", "automl.add_learner(learner_name='my_lgbm', learner_class=MyLGBM)\n", "settings = {\n", " \"time_budget\": 120, # total running time in seconds\n", " \"metric\": 'r2', # primary metrics for regression can be chosen from: ['mae','mse','r2']\n", " \"estimator_list\": ['my_lgbm',], # list of ML learners; we tune lightgbm in this example\n", " \"task\": 'regression', # task type \n", " \"log_file_name\": 'houses_experiment_my_lgbm.log', # flaml log file\n", "}\n", "automl.fit(X_train=X_train, y_train=y_train, **settings)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "tags": [] }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": "Best hyperparmeter config:{'n_estimators': 287.0, 'num_leaves': 247.0, 'min_child_samples': 81.0, 'learning_rate': 0.06283686776885493, 'subsample': 0.7669214501226506, 'log_max_bin': 10.0, 'colsample_bytree': 0.613734331916688, 'reg_alpha': 0.006495889833184046, 'reg_lambda': 0.005049036990045567}\nBest r2 on validation data: 0.839\nTraining duration of best run: 13.51 s\nPredicted labels[136183.28410995 260302.1656523 136575.03214257 ... 213737.94780122\n 248465.64921701 275744.71459095]\nTrue labels[136900. 241300. 200700. ... 160900. 227300. 265600.]\nr2=0.8449104679441721\nmse=2050051993.9844227\nmae=30061.65329294407\n" } ], "source": [ "print('Best hyperparmeter config:', automl.best_config)\n", "print('Best r2 on validation data: {0:.4g}'.format(1-automl.best_loss))\n", "print('Training duration of best run: {0:.4g} s'.format(automl.best_config_train_time))\n", "\n", "y_pred = automl.predict(X_test)\n", "print('Predicted labels', y_pred)\n", "print('True labels', y_test)\n", "\n", "from flaml.ml import sklearn_metric_loss_score\n", "print('r2', '=', 1 - sklearn_metric_loss_score('r2', y_pred, y_test))\n", "print('mse', '=', sklearn_metric_loss_score('mse', y_pred, y_test))\n", "print('mae', '=', sklearn_metric_loss_score('mae', y_pred, y_test))" ] } ], "metadata": { "kernelspec": { "name": "python37764bitbsconda5b158f6acec0414d8c5c2401992dd9e1", "display_name": "Python 3.7.7 64-bit ('bs': conda)", "metadata": { "interpreter": { "hash": "0cfea3304185a9579d09e0953576b57c8581e46e6ebc6dfeb681bc5a511f7544" } } }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.7-final" } }, "nbformat": 4, "nbformat_minor": 2 }