2021. 6. 20. 13:31ㆍ분석 Python/구현 및 자료
pycaret에서 search_library 중에서 tune-sklearn을 사용할 때 방법을 공유한다.
특히 custom_grid를 통해서 구현된 것이 없어서 시행착오의 결과를 공유하고, 결론적으로 모든 기능을 완벽히 제공하는 것 같지는 않다 ( 21/06/20 기준)
pycaret version : 2.3.1
일단 custom_grid를 보면 format은 search_library를 기준으로 한다고 한다.
그래서 search_library를 가보니 각 방법에 따라서 링크가 걸려있다.
그래서 들어가 보니 다음과 같이 tune을 통해서 choice 하거나 loguniform을 하는 것을 알 수 있었다.
# Define the `param_dists using the SearchSpace API
# This allows the specification of sampling from discrete and
# categorical distributions (below for the `learning_rate` scheduler parameter)
from ray import tune
param_dists = {
'loss': tune.choice(['squared_hinge', 'hinge']),
'alpha': tune.loguniform(1e-4, 1e-1),
'epsilon': tune.uniform(1e-2, 1e-1),
}
hyperopt_tune_search = TuneSearchCV(SGDClassifier(),
param_distributions=param_dists,
n_trials=2,
early_stopping=True, # uses Async HyperBand if set to True
max_iters=10,
search_optimization="hyperopt"
)
hyperopt_tune_search.fit(X_train, y_train)
그래서 조금 더 자세히 알고 싶어서 ray에 들아가 보니 다음과 같은 예제가 있었다.
config = {
# Sample a float uniformly between -5.0 and -1.0
"uniform": tune.uniform(-5, -1),
# Sample a float uniformly between 3.2 and 5.4,
# rounding to increments of 0.2
"quniform": tune.quniform(3.2, 5.4, 0.2),
# Sample a float uniformly between 0.0001 and 0.01, while
# sampling in log space
"loguniform": tune.loguniform(1e-4, 1e-2),
# Sample a float uniformly between 0.0001 and 0.1, while
# sampling in log space and rounding to increments of 0.0005
"qloguniform": tune.qloguniform(1e-4, 1e-1, 5e-4),
# Sample a random float from a normal distribution with
# mean=10 and sd=2
"randn": tune.randn(10, 2),
# Sample a random float from a normal distribution with
# mean=10 and sd=2, rounding to increments of 0.2
"qrandn": tune.qrandn(10, 2, 0.2),
# Sample a integer uniformly between -9 (inclusive) and 15 (exclusive)
"randint": tune.randint(-9, 15),
# Sample a random uniformly between -21 (inclusive) and 12 (inclusive (!))
# rounding to increments of 3 (includes 12)
"qrandint": tune.qrandint(-21, 12, 3),
# Sample a integer uniformly between 1 (inclusive) and 10 (exclusive),
# while sampling in log space
"lograndint": tune.lograndint(1, 10),
# Sample a integer uniformly between 1 (inclusive) and 10 (inclusive (!)),
# while sampling in log space and rounding to increments of 2
"qlograndint": tune.qlograndint(1, 10, 2),
# Sample an option uniformly from the specified choices
"choice": tune.choice(["a", "b", "c"]),
# Sample from a random function, in this case one that
# depends on another value from the search space
"func": tune.sample_from(lambda spec: spec.config.uniform * 0.01),
# Do a grid search over these values. Every value will be sampled
# `num_samples` times (`num_samples` is the parameter you pass to `tune.run()`)
"grid": tune.grid_search([32, 64, 128])
}
그래서 실제로 테스트한 코드는 다음과 같고 아쉬운 점이 있었다.
일단 아쉬운 점 중에서 하나는 ray의 cpu 제한을 pycaret에서는 할 수가 없었다.
그래서 ray의 초기화 함수를 이용하여서 진행하였다.
from pycaret.datasets import get_data
boston = get_data('boston')
from pycaret.regression import *
exp_name = setup(data = boston, target = 'medv',silent=True,n_jobs =20)
catboost_model = create_model('catboost')
from ray import tune
import ray
catboost_param_dists = {
'iterations': tune.choice([500,100,300]),
# 'reg_lambda': tune.uniform(1, 100),
# 'bagging_temperature': tune.uniform(0, 100),
# 'colsample_bylevel': tune.uniform(0.5, 1.0),
'random_strength': tune.choice([0,0.1,0.2,1,10]), # tune.uniform(0, 100),
# 'learning_rate': tune.uniform(1e-3, 1e-1),
'max_depth' : tune.choice([5,6,7,8,9])
}
아쉬운 점 중에 하나는 모든 함수를 못쓰고, 오로지 choice만 사용 가능해 보인다.
다른 것을 하게 되면, 내부적으로 에러가 나는 것을 발생했다.
ray.init(num_cpus=20, num_gpus=2)
tuned_top1 = tune_model(catboost_model,
optimize="R2",
search_library="tune-sklearn",
search_algorithm="hyperopt",
choose_better = True ,
custom_grid = catboost_param_dists ,
early_stopping = "asha",
early_stopping_max_iters = 10,
return_tuner = False ,
n_iter=100)
ray.shutdown()
그래서 이런 식으로 진행해야지 tune-sklearn을 사용할 수 있었다.
다만 이걸 사용하고자 한 이유는 특정 범위만 주면 알아서 찾는 방법론으로써 사용하고 싶었으나, 실제로 그렇게 되지 않아서 아쉽다...
그래서 코드를 좀 뜯어보니 현재는 choice만 가능할 것 같고, 이것은 나머지 경우에도 동일한 상황일 것 같다.
수정!!! (21/06/21)
github에 issue를 제기하니, 내가 잘 못 했다는 것을 알았다.
다음과 같이 진행하면 내가 원하는 기능이 잘 작동한다는 것을 공유한다
from pycaret.distributions import (
UniformDistribution, # uniform log uniform
IntUniformDistribution, # intuniform intloguniform
DiscreteUniformDistribution, # quniform
CategoricalDistribution,
)
catboost_param_dists = {
'iterations': CategoricalDistribution([500,100,300]),
# 'reg_lambda': UniformDistribution(1, 100),
# 'bagging_temperature': UniformDistribution(0, 100),
'colsample_bylevel': UniformDistribution(0.5, 1.0),
'random_strength': CategoricalDistribution([0,0.1,0.2,1,10]), # tune.uniform(0, 100),
# 'learning_rate': UniformDistribution(1e-3, 1e-1),
'max_depth' : CategoricalDistribution([5,6,7,8,9])
}
tuned_top1 = tune_model(catboost_model,
optimize="R2",
search_library="tune-sklearn",
search_algorithm="hyperopt",
choose_better = True ,
custom_grid = catboost_param_dists ,
early_stopping = "asha",
early_stopping_max_iters = 10,
return_tuner = False ,
n_iter=100)
문서에 없고 예제에도 없으니 ㅠㅠ 알 길이 없어서 안되는 줄 알았다.
된다고 하니 다행인 것 같다 ㅠㅠ
https://github.com/ray-project/tune-sklearn/issues/213#event-4913870765
https://docs.ray.io/en/master/tune/api_docs/search_space.html
https://docs.ray.io/en/master/tune/api_docs/search_space.html
'분석 Python > 구현 및 자료' 카테고리의 다른 글
Python) Yield 에 대해서 알아보기 (0) | 2021.08.07 |
---|---|
or-tools) 제한 조건 만족하는 특정 인자에 대한 경우의 수 찾기 (0) | 2021.08.01 |
numpy에서 dict을 이용해서 값을 바꾸는 방법 (2) | 2021.06.06 |
tqdm) print대신에 tqdm을 이용해서 logging 방법 (0) | 2021.05.15 |
python3.7 이후) dataclass __post_init__ 간략하게 알아보기 (0) | 2021.04.25 |