Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/ShiroDima/MetaTune
Browse files Browse the repository at this point in the history
  • Loading branch information
Shiroiii committed May 28, 2023
2 parents 72c2e92 + 41e2699 commit cd5c270
Show file tree
Hide file tree
Showing 24 changed files with 1,568 additions and 177 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test_models.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Test Models

on:
pull_request:
types: [opened, reopened]
types: [opened, reopened, edited]
branches:
- 'main'
push:
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
**/__pycache__/
temp.py
.gitignore
.pytest_cache
.pytest_cache
metatune/
assets/
24 changes: 24 additions & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from .tune_classifier import *
from .tune_regressor import *
from typing import Iterable


__all__: Iterable[str] = [
"baseline.mixin",
"tests.test_tuners",
"tests.utils",
"ensemble_classifier",
"linear_model_classifier",
"mlp_classifier",
"naive_bayes_classifier",
"neighbor_classifier",
"svc",
"tree_classifier"
"ensemble_regressor",
"linear_model_regressor",
"mlp_regressor",
"neighbor_regressor",
"svr",
"tree_regressor",
"utils.module_utils",
]
8 changes: 7 additions & 1 deletion baseline/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
from .mixin import *
from baseline.mixin import *
from typing import Iterable


__all__: Iterable[str] = [
"SampleClassMixin"
]
27 changes: 20 additions & 7 deletions baseline/mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@

@dataclass
class SampleClassMixin:

def _is_space_type(self, space: Iterable, type: Callable) -> bool:
return all(list(map(lambda x: isinstance(x, type), space)))

def is_valid_int_space(self, space: Iterable) -> bool:
return self._is_space_type(space, int) and len(space) == 2

def is_valid_float_space(self, space: Iterable) -> bool:
return self._is_space_type(space, float) and len(space) == 2

def is_valid_categorical_space(self, space: Iterable) -> bool:
return (not self.is_valid_float_space(space)) and (not self.is_valid_float_space(space))

def _sample_params(self, trial: Optional[Trial]=None) -> Dict[str, Any]:
if trial is None: raise ValueError("Method should be called in an optuna trial study")

Expand All @@ -24,24 +37,24 @@ def _evaluate_params(self, model_class: Callable, params: Dict[str, Any]):

def _random_classification_set(self, is_multitask: bool=False) -> Tuple[Iterable]:
if not is_multitask:
return np.random.randn(10, 5), np.random.randint(0, 2, size=(10))
return np.abs(np.random.randn(25, 5)), np.random.randint(0, 2, size=(25))

else:
return np.random.randn(10, 5), np.random.randint(0, 2, size=(10, 2))
return np.abs(np.random.randn(25, 5)), np.random.randint(0, 2, size=(25, 2))

def _random_regression_set(self, is_multitask: bool=False) -> Tuple[Iterable]:
if not is_multitask:
return np.random.randn(10, 5), np.random.randn(10)
return np.abs(np.random.randn(25, 5)), np.abs(np.random.randn(25)) + 1e-4

else:
return np.random.randn(10, 5), np.random.randn(10, 2)
return np.abs(np.random.randn(25, 5)), np.abs(np.random.randn(25, 2)) + 1e-4

def _evaluate_sampled_model(
self,
task: str,
model_class: Callable,
params: Dict[str, Any],
is_mulktitask: bool=False) -> Any:
is_multitask: bool=False) -> Any:

valid_tasks: Iterable[str] = ["regression", "classification"]
assert task in valid_tasks, (
Expand All @@ -51,9 +64,9 @@ def _evaluate_sampled_model(
self._evaluate_params(model_class, params)

if task == "regression":
X, y = self._random_regression_set(is_mulktitask)
X, y = self._random_regression_set(is_multitask)
else:
X, y = self._random_classification_set(is_mulktitask)
X, y = self._random_classification_set(is_multitask)

try:
model_class(**params).fit(X, y)
Expand Down
117 changes: 117 additions & 0 deletions tests/test_tuners.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,120 @@ class TestRadiusNeighborClassifier(BaseTest):
class TestRadiusNeighborRegressor(BaseTest):
model: SampleClassMixin = tune_regressor.RadiusNeighborRegressorTuner()
task: str = "regression"
class TestNuSVC(BaseTest):
model: SampleClassMixin = tune_classifier.NuSVCTuner()
task: str = "classification"


class TestNuSVR(BaseTest):
model: SampleClassMixin = tune_regressor.NuSVRTuner()
task: str = "regression"


class TestPerceptron(BaseTest):
model: SampleClassMixin = tune_classifier.PerceptronTuner()
task: str = "classification"


class TestPassiveAggressiveClassifier(BaseTest):
model: SampleClassMixin = tune_classifier.PassiveAggressiveClassifierTuner()
task: str = "classification"


class TestPassiveAggressiveRegressorTuner(BaseTest):
model: SampleClassMixin = tune_regressor.PassiveAggressiveRegressorTuner()
task: str = "regression"


class TestSGDClassifier(BaseTest):
model: SampleClassMixin = tune_classifier.SGDClassifierTuner()
task: str = "classification"


class TestSGDRegressorTuner(BaseTest):
model: SampleClassMixin = tune_regressor.SGDRegressorTuner()
task: str = "regression"


class TestMLPClassifierTuner(BaseTest):
model: SampleClassMixin = tune_classifier.MLPClassifierTuner()
task: str = "classification"
n_trials: int = 10


class TestMLPRegressorTuner(BaseTest):
model: SampleClassMixin = tune_regressor.MLPRegressorTuner()
task: str = "regression"
n_trials: int = 10


class TestHistGradientBoostingClassifier(BaseTest):
model: SampleClassMixin = tune_classifier.HistGradientBoostingClassifierTuner()
task: str = "classification"


class TestHistGradientBoostingRegressor(BaseTest):
model: SampleClassMixin = tune_regressor.HistGradientBoostingRegressorTuner()
task: str = "regression"

class TestLars(BaseTest):
model: SampleClassMixin = tune_regressor.LarsTuner()
task: str = "regression"


class TestLassoLars(BaseTest):
model: SampleClassMixin = tune_regressor.LassoLarsTuner()
task: str = "regression"


class TestLassoLarsIC(BaseTest):
model: SampleClassMixin = tune_regressor.LassoLarsICTuner()
task: str = "regression"

class TestBayesianRidge(BaseTest):
model: SampleClassMixin = tune_regressor.BayesianRidgeTuner()
task: str = "regression"

class TestGaussianNBClassifier(BaseTest):
model: SampleClassMixin = tune_classifier.GaussianNBTuner()
task: str = "classification"

class TestBernoulliNBClassifier(BaseTest):
model: SampleClassMixin = tune_classifier.BernoulliNBTuner()
task: str = "classification"

class TestMultinomialNBClassifier(BaseTest):
model: SampleClassMixin = tune_classifier.MultinomialNBTuner()
task: str = "classification"

class TestComplementNBClassifier(BaseTest):
model: SampleClassMixin = tune_classifier.ComplementNBTuner()
task: str = "classification"

class TestCategoricalNBTuner(BaseTest):
model: SampleClassMixin = tune_classifier.CategoricalNBTuner()
task: str = "classification"

class TestTweedieRegressor(BaseTest):
model: SampleClassMixin = tune_regressor.TweedieRegressorTuner()
task: str = "regression"


class TestOrthogonalMatchingPursuit(BaseTest):
model: SampleClassMixin = tune_regressor.OrthogonalMatchingPursuitTuner()
task: str = "regression"


class TestPoissonRegressor(BaseTest):
model: SampleClassMixin = tune_regressor.PoissonRegressorTuner()
task: str = "regression"


class TestGammaRegressor(BaseTest):
model: SampleClassMixin = tune_regressor.GammaRegressorTuner()
task: str = "regression"


class TestQuantileRegressor(BaseTest):
model: SampleClassMixin = tune_regressor.QuantileRegressorTuner()
task: str = "regression"
16 changes: 11 additions & 5 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import optuna
import sklearn
import optuna, sklearn
import numpy as np
from sklearn import datasets
from sklearn.preprocessing import MinMaxScaler
from optuna.trial import Trial
from baseline.mixin import SampleClassMixin
from tune_classifier import classifier_tuner_model_class_dict
from tune_regressor import regressor_tuner_model_class_dict



# load sample datasets
# regression
REG_X, REG_y = datasets.load_diabetes(return_X_y=True)
REG_X = MinMaxScaler().fit_transform(REG_X)
REG_y = ((REG_y - REG_y.min()) / (REG_y.max() - REG_y.min())) + 1e-4
REG_DATA = sklearn.model_selection.train_test_split(REG_X, REG_y, random_state=0)

# classification
CLS_X, CLS_y = datasets.load_iris(return_X_y=True)
CLS_X = MinMaxScaler().fit_transform(CLS_X)
CLS_DATA = sklearn.model_selection.train_test_split(CLS_X, CLS_y, random_state=0)

#multi-task regression
MULTITASK_REG_X, MULTITASK_REG_y = np.random.randn(200, 20), np.random.randn(200, 5)
MULTITASK_REG_X = MinMaxScaler().fit_transform(MULTITASK_REG_X)
MULTITASK_REG_y = MinMaxScaler().fit_transform(MULTITASK_REG_y)
MULTITASK_DATA = sklearn.model_selection.train_test_split(MULTITASK_REG_X, MULTITASK_REG_y, random_state=0)


Expand Down Expand Up @@ -51,6 +55,7 @@ def objective(trial: Trial):
class BaseTest:
model: SampleClassMixin = None
task: str = None
n_trials: int = 20

def test_dict_mapping(self):
if self.task == "classification":
Expand All @@ -61,14 +66,15 @@ def test_dict_mapping(self):

else: assert False

def test_methods(self):
def test_methods_and_attrs(self):
assert hasattr(self.model, "_sample_params")
assert hasattr(self.model, "sample_model")
assert hasattr(self.model, "model") and self.model.model is None

def test_study(self):
try:
study = optuna.create_study() # Create a new study.
study.optimize(objective_factory(self.model, task=self.task), n_trials=20)
study.optimize(objective_factory(self.model, task=self.task), n_trials=self.n_trials)
best = study.best_params
except:
best = None
Expand Down
42 changes: 37 additions & 5 deletions tune_classifier/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,53 @@
from utils.module_utils import get_entities, get_tuner_model_dict
from utils.module_utils import get_tuner_entities, get_tuner_model_dict
from tune_classifier.svc import *
from tune_classifier.tree_classifier import *
from tune_classifier.linear_model_classifier import *
from tune_classifier.ensemble_classifier import *
from tune_classifier.naive_bayes_classifier import *
from tune_classifier.neighbor_classifier import *
from typing import Iterable, Tuple, Dict, Generator, Callable
from tune_classifier.mlp_classifier import *
from typing import Iterable, Dict, Generator, Callable

__all__: Iterable[str] = [

__modules__: Iterable[str] = [
"tune_classifier.svc",
"tune_classifier.tree_classifier",
"tune_classifier.linear_model_classifier",
"tune_classifier.ensemble_classifier",
"tune_classifier.naive_bayes_classifier",
"tune_classifier.neighbor_classifier",
"tune_classifier.mlp_classifier",
]

classifier_tuning_entities: Generator = (i for i in sum(list(map(get_entities, __all__)), []))
classifier_tuning_entities: Generator = (i for i in sum(list(map(get_tuner_entities, __modules__)), []))

classifier_tuner_model_class_dict: Dict[str, Callable] = {
k:v for _dict in map(get_tuner_model_dict, __all__) for k, v in _dict.items()
k:v for _dict in map(get_tuner_model_dict, __modules__) for k, v in _dict.items()
}

__all__: Iterable[str] = [
"classifier_tuning_entities",
"classifier_tuner_model_class_dict",
"SVCTuner",
"LinearSVCTuner",
"NuSVCTuner",
"DecisionTreeClassifierTuner",
"ExtraTreeClassifierTuner",
"LogisticRegressionTuner",
"PerceptronTuner",
"PassiveAggressiveClassifierTuner",
"SGDClassifierTuner",
"RandomForestClassifierTuner",
"ExtraTreesClassifierTuner",
"AdaBoostClassifierTuner",
"GradientBoostingClassifierTuner",
"BaggingClassifierTuner",
"HistGradientBoostingClassifierTuner",
"GaussianNBTuner",
"BernoulliNBTuner",
"MultinomialNBTuner",
"ComplementNBTuner",
"CategoricalNBTuner",
"KNeighborsClassifierTuner",
"MLPClassifierTuner",
]
Loading

0 comments on commit cd5c270

Please sign in to comment.