A Python package to provide unified interface for hierarchical hyperparameter optimization
Project description
HierTuneHub
Are you tired of babysitting hyperparameter tuning process?
Are you confused by all the hyperparameter optimization libraries out there and don't know which one to choose?
Are you struggling to translate your hierarchical search space (dependencies of different hyperparameters) into a format that can be used by different optimization libraries?
Don't worry! HierTuneHub is here to help you!
By simply defining a search space in a YAML file and black-box objective function,
you can use HierTuneHub to tune hyperparameters with popular optimization libraries including Hyperopt, Optuna, and FLAML (more to come!) with ease.
Key Features
- Search space definition in a YAML file
- Support for multiple levels of hierarchy in the search space
- Support all types of hyperparameters including continuous, integer, and categorical
- Unified interface for hyperparameter optimization libraries
- Easy-to-use API
- Support for optimization libraries including
Hyperopt,Optuna, andFLAML(more to come!)
Installation
You can install HierTuneHub using pip.
pip install hiertunehub
After installation, you can import the package in your Python code:
import hiertunehub
Usage
Search Space
First, you should define a search space in a YAML file.
- The YAML file may consist of multiple levels of hierarchy.
- If the level is defined using a list, each item in the list should be a dictionary, and each item is considered a possible choice. In the sampling process, one of the items is randomly selected.
- If the level is defined using a dictionary, all key-value pairs will be included in the sampled configuration.
- For a hyperparameter that needs to be tuned, you need to specify
range,valuesand/orsampleras a dictionary at the lowest level.- For continuous hyperparameters, you need to specify
rangeandsampler. - For categorical hyperparameters, you need to specify
values.samplermust be set tochoice, or you can omit it.
- For continuous hyperparameters, you need to specify
- For
HyperoptandOptuna, they need a unique identifier for every possible hyperparameter. Therefore, the defined search space must satisfy the following conditions:- A unique identifier key-value pair must be provided in the dictionary if it is a possible choice from a list level.
The key name must be the same across the whole file. The value must be unique across all the choices.
- Default key name is
name, or you can use other identifiers such asidorclassand passname="id"orname="class"to theSearchSpaceconstructor.
- Default key name is
- A unique character string that is not present in any other keys. It is used to concatenate the keys to form a unique identifier.
Default is
?, or you can use other characters such as!and passsep="!"to theSearchSpaceconstructor.
- A unique identifier key-value pair must be provided in the dictionary if it is a possible choice from a list level.
The key name must be the same across the whole file. The value must be unique across all the choices.
The following types of samplers are supported in HierTuneHub:
uniform: Uniform distributionloguniform: Log-uniform distributionquniform: Quantized uniform distributionqloguniform: Quantized log-uniform distributionuniformint: Uniform integer distributionquniformint: Quantized uniform integer distributionloguniformint: Log-uniform integer distributionqloguniformint: Quantized log-uniform integer distributionchoice: Categorical choices
SearchSpace class provides the following methods:
to_hyperopt: Convert the search space to a dict forHyperopt.to_optuna: Convert the search space toOptuna. You need to pass in anOptuna.Trialobject.to_flaml: Convert the search space to a dict forFLAML.
SearchSpace also provides the following class methods:
from_dict: Create aSearchSpaceobject from a dictionary resembling the YAML configuration.from_flaml: Create aSearchSpaceobject from a FLAML configuration.
Hyperparameter Tuning
After you define the search space, you can use it for hyperparameter optimization.
HierTuneHub provides a unified interface for hyperparameter optimization libraries including Hyperopt, Optuna, and FLAML.
You need to define your own objective function that takes in a sampled configuration and returns either a single score or a dictionary containing scores and other information.
You can call create_tuner function to create a Tuner class with the search space and the optimization library you want to use.
def create_tuner(
objective: Callable,
search_space: SearchSpace,
mode: str = "min",
metric: Optional[str] = None,
framework: str = "hyperopt",
framework_params: dict = None,
**kwargs
) -> Tuner:
"""
Create a tuner object based on the specified framework.
:param objective: user-defined objective function. The objective function can ouput a single float value, or a
dictionary containing the metric value and other values.
:param search_space: A SearchSpace object containing the search space for the hyperparameters.
:param mode: The optimization mode. Either 'min' or 'max'.
:param metric: If the objective function returns a dictionary, the metric key specifies the key to be used for
optimization.
:param framework: The framework to be used for optimization. Supported frameworks are "hyperopt", "optuna", and
"flaml".
:param framework_params: Additional parameters to be passed to the framework tuning function.
:param kwargs: Additional parameters to be passed to the framework tuning function.
:return: A Tuner object based on the specified framework.
"""
Tuner class provides run method to start the optimization process.
After the optimization process is finished, you can get the best hyperparameters and the best result by calling best_params and best_result properties.
You can also call trials property to get all the trials evaluated during the optimization process.
It is a list of Trial objects which contains params and result attributes corresponding to the sampled configuration and the result of objective function.
Tuner class also provides results property to get all the results evaluated during the optimization process in a list.
Note for passing additional parameters (framework_params and kwargs) to the optimization libraries:
optuna:sampler,prunerandstudy_nameare passed tooptuna.create_studyfunction. Other parameters are passed tooptuna.study.optimizefunction.
hyperopt:- all parameters are passed to
hyperopt.fminfunction.
- all parameters are passed to
FLAML:- all parameters are passed to
flaml.tune.runfunction.
- all parameters are passed to
Example
The following is an example of iris dataset classification problem.
We want to tune hyperparameters for different classifiers using unified interface provided by HierTuneHub to find the best hyperparameters that maximize the accuracy.
The search space is defined in a YAML file as follows.
It consists of four classifiers: SVC, RandomForestClassifier, GradientBoostingClassifier, and KNeighborsClassifier.
Each classifier has its own hyperparameters to be tuned.
---
estimators:
- name: "sklearn.svm.SVC" # estimator name
C: # hyperparameter name
range: [ 1.0e-10, 1.0 ] # hyperparameter range, from low to high. For scientific notation,
# 1e-10 should be written as 1.0e-10 so that YAML parser can parse it as numeric type correctly.
sampler: "loguniform" # sampler type
kernel:
- name: "linear"
- name: "poly"
degree:
range: [ 2, 5 ]
sampler: "uniformint"
gamma:
values: [ "auto", "scale" ] # categorical choices
- name: "rbf"
gamma:
values: [ "auto", "scale" ]
sampler: "loguniform"
- name: "sklearn.ensemble.RandomForestClassifier"
n_estimators:
range: [ 10, 1000 ]
sampler: "uniformint"
max_depth:
range: [ 2, 32 ]
sampler: "uniformint"
- name: "sklearn.ensemble.GradientBoostingClassifier"
n_estimators:
range: [ 10, 1000 ]
sampler: "uniformint"
max_depth:
range: [ 2, 32 ]
sampler: "uniformint"
- name: "sklearn.neighbors.KNeighborsClassifier"
n_neighbors:
range: [ 2, 10 ]
sampler: "uniformint"
The objective function is defined as follows. The function takes in a configuration dictionary and returns a dictionary containing the accuracy and the time taken to evaluate the model.
import time
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.neighbors import KNeighborsClassifier
iris = load_iris()
x, y = iris.data, iris.target
def objective(config):
config = config['estimators']
name = config.pop("name")
if name == "sklearn.svm.SVC":
c = config.pop("C")
kernel = config['kernel'].pop("name")
kernel_params = config['kernel']
model = SVC(C=c, kernel=kernel, **kernel_params)
elif name == "sklearn.ensemble.RandomForestClassifier":
model = RandomForestClassifier(**config)
elif name == "sklearn.ensemble.GradientBoostingClassifier":
model = GradientBoostingClassifier(**config)
elif name == "sklearn.neighbors.KNeighborsClassifier":
model = KNeighborsClassifier(**config)
else:
raise ValueError(f"Unknown estimator: {config['estimator']}")
t_start = time.time()
acc = cross_val_score(model, x, y, cv=5).mean()
t_end = time.time()
return {
'acc': acc,
'time': t_end - t_start
}
Now, we can load the search space, create a tuner object and run the optimization process:
from hiertunehub import SearchSpace, create_tuner
search_space = SearchSpace("example.yaml")
hyperopt_tuner = create_tuner(objective,
search_space,
mode="max",
metric="acc",
framework="hyperopt",
max_evals=10 # number of evaluation times
)
hyperopt_tuner.run()
In the end, we can get the best hyperparameters and the best result:
best_params = hyperopt_tuner.best_params
best_result = hyperopt_tuner.best_result
print(best_params)
print(best_result)
# Output (may vary):
# {'estimators': {'C': 1.9537341171427107, 'kernel': {'gamma': 'auto', 'name': 'rbf'}, 'name': 'sklearn.svm.SVC'}}
# {'acc': np.float64(0.9800000000000001), 'time': 0.012115001678466797}
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hiertunehub-0.2.2.tar.gz.
File metadata
- Download URL: hiertunehub-0.2.2.tar.gz
- Upload date:
- Size: 19.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f5da7f5836acc4cd265f06c77b9afee414f6954f76207ee00a64fbd206f46484
|
|
| MD5 |
bd1632d9119be47f17bf919743b00ea5
|
|
| BLAKE2b-256 |
b19ae18b5ddbef9ca165f6067ce90e854f91e567e590e76ed6ec192b34d7a23c
|
Provenance
The following attestation bundles were made for hiertunehub-0.2.2.tar.gz:
Publisher:
publish.yml on ItsYikunJiang/HierTuneHub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hiertunehub-0.2.2.tar.gz -
Subject digest:
f5da7f5836acc4cd265f06c77b9afee414f6954f76207ee00a64fbd206f46484 - Sigstore transparency entry: 2172966629
- Sigstore integration time:
-
Permalink:
ItsYikunJiang/HierTuneHub@881fbed4ba1e72b61cd9169c3b6a676c3890c616 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/ItsYikunJiang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@881fbed4ba1e72b61cd9169c3b6a676c3890c616 -
Trigger Event:
release
-
Statement type:
File details
Details for the file hiertunehub-0.2.2-py3-none-any.whl.
File metadata
- Download URL: hiertunehub-0.2.2-py3-none-any.whl
- Upload date:
- Size: 22.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
045bd7fe2801fba015490314fea21868cd6dde7a3574455d3641899bc1ff79cc
|
|
| MD5 |
4aac2c981ac5eaa4d0cff13ca466f587
|
|
| BLAKE2b-256 |
fb5b20325560fe596ade5be1ff15c3e378137cac4d9fa9ba7dc8822d3a155e44
|
Provenance
The following attestation bundles were made for hiertunehub-0.2.2-py3-none-any.whl:
Publisher:
publish.yml on ItsYikunJiang/HierTuneHub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hiertunehub-0.2.2-py3-none-any.whl -
Subject digest:
045bd7fe2801fba015490314fea21868cd6dde7a3574455d3641899bc1ff79cc - Sigstore transparency entry: 2172966637
- Sigstore integration time:
-
Permalink:
ItsYikunJiang/HierTuneHub@881fbed4ba1e72b61cd9169c3b6a676c3890c616 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/ItsYikunJiang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@881fbed4ba1e72b61cd9169c3b6a676c3890c616 -
Trigger Event:
release
-
Statement type: