Neuraxle AutoML - Почему это ошибка?
Я экспериментирую с Neuraxle по примеру AutoML. Немодифицированный пример работает нормально. Когда я модифицирую его, чтобы включить собственные компоненты конвейера перед
ChooseOneStepOf(classifiers)
это не удается, и я не понимаю, почему.
from neuraxle.base import BaseTransformer
from neuraxle.pipeline import Pipeline
from neuraxle.hyperparams.space import HyperparameterSpace
from neuraxle.steps.numpy import NumpyRavel
from neuraxle.steps.output_handlers import OutputTransformerWrapper
from typing import List
from sklearn.preprocessing import OneHotEncoder
from neuraxle.pipeline import Pipeline
from neuraxle.union import FeatureUnion
from sklearn.impute import SimpleImputer
# sklearn classifiers, and sklearn wrapper for neuraxle
from neuraxle.steps.sklearn import SKLearnWrapper
from sklearn.tree import DecisionTreeClassifier, ExtraTreeClassifier
from sklearn.linear_model import RidgeClassifier, LogisticRegression
# neuraxle distributions
from neuraxle.hyperparams.distributions import Choice, RandInt, Boolean, LogUniform
from neuraxle.steps.flow import ChooseOneStepOf
from neuraxle.base import BaseTransformer, ForceHandleMixin
from neuraxle.metaopt.auto_ml import ValidationSplitter
from neuraxle.metaopt.callbacks import ScoringCallback
from sklearn.metrics import accuracy_score
from neuraxle.metaopt.callbacks import MetricCallback
from sklearn.metrics import f1_score, precision_score, recall_score
from neuraxle.metaopt.auto_ml import InMemoryHyperparamsRepository
from neuraxle.plotting import TrialMetricsPlottingObserver
from neuraxle.metaopt.tpe import TreeParzenEstimatorHyperparameterSelectionStrategy
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
from neuraxle.metaopt.auto_ml import AutoML
import os
classifiers: List[BaseTransformer] = [
SKLearnWrapper(DecisionTreeClassifier(), HyperparameterSpace({
'criterion': Choice(['gini', 'entropy']),
'splitter': Choice(['best', 'random']),
'min_samples_leaf': RandInt(2, 5),
'min_samples_split': RandInt(1, 3)
})).set_name('DecisionTreeClassifier'),
Pipeline([
OutputTransformerWrapper(NumpyRavel()),
SKLearnWrapper(RidgeClassifier(), HyperparameterSpace({
'alpha': Choice([(0.0, 1.0, 10.0), (0.0, 10.0, 100.0)]),
'fit_intercept': Boolean(),
'normalize': Boolean()
}))
]).set_name('RidgeClassifier'),
Pipeline([
OutputTransformerWrapper(NumpyRavel()),
SKLearnWrapper(LogisticRegression(), HyperparameterSpace({
'C': LogUniform(0.01, 10.0),
'fit_intercept': Boolean(),
'dual': Boolean(),
'penalty': Choice(['l1', 'l2']),
'max_iter': RandInt(20, 200)
}))
]).set_name('LogisticRegression')
]
class ColumnSelectTransformer(BaseTransformer, ForceHandleMixin):
def __init__(self, required_columns):
BaseTransformer.__init__(self)
ForceHandleMixin.__init__(self)
self.required_columns = required_columns
def inverse_transform(self, processed_outputs):
pass
def fit(self, X, y=None):
return self
def transform(self, X):
if not isinstance(X, pd.DataFrame):
X = pd.DataFrame(X)
return X[self.required_columns]
columns = ['BEDCERT', 'RESTOT', 'INHOSP', 'CCRC_FACIL',
'SFF', 'CHOW_LAST_12MOS', 'SPRINKLER_STATUS',
'EXP_TOTAL', 'ADJ_TOTAL']
simple_features = Pipeline([ColumnSelectTransformer(columns),
SimpleImputer(missing_values=np.nan,
strategy='mean')])
categorical_features = Pipeline([ColumnSelectTransformer(['OWNERSHIP', 'CERTIFICATION']),
OneHotEncoder(sparse=False)
])
business_features = FeatureUnion([simple_features,
categorical_features])
p: Pipeline = Pipeline([
business_features,
ChooseOneStepOf(classifiers)
])
validation_splitter = ValidationSplitter(test_size=0.20)
scoring_callback = ScoringCallback(
metric_function=accuracy_score,
name='accuracy',
higher_score_is_better=False,
print_metrics=False
)
callbacks = [
MetricCallback('f1', metric_function=f1_score, higher_score_is_better=True, print_metrics=False),
MetricCallback('precision', metric_function=precision_score, higher_score_is_better=True, print_metrics=False),
MetricCallback('recall', metric_function=recall_score, higher_score_is_better=True, print_metrics=False)
]
hyperparams_repository = InMemoryHyperparamsRepository(cache_folder='cache')
hyperparams_repository.subscribe(TrialMetricsPlottingObserver(
plotting_folder_name='metric_results',
save_plots=False,
plot_trial_on_next=False,
plot_all_trials_on_complete=True,
plot_individual_trials_on_complete=False
))
hyperparams_optimizer = TreeParzenEstimatorHyperparameterSelectionStrategy(
number_of_initial_random_step=10,
quantile_threshold=0.3,
number_good_trials_max_cap=25,
number_possible_hyperparams_candidates=100,
prior_weight=0.,
use_linear_forgetting_weights=False,
number_recent_trial_at_full_weights=25
)
tmpdir = 'cache'
if not os.path.exists(tmpdir):
os.makedirs(tmpdir)
n_trials = 10
n_epochs = 10
auto_ml = AutoML(
pipeline=p,
validation_splitter=validation_splitter,
refit_trial=True,
n_trials=n_trials,
epochs=n_epochs,
cache_folder_when_no_handle=str(tmpdir),
scoring_callback=scoring_callback,
callbacks=callbacks,
hyperparams_repository=hyperparams_repository
)
def generate_classification_data():
# data_inputs, expected_outputs = make_classification(
# n_samples=10000,
# n_repeated=0,
# n_classes=3,
# n_features=4,
# n_clusters_per_class=1,
# class_sep=1.5,
# flip_y=0,
# weights=[0.5, 0.5, 0.5]
# )
data = pd.read_csv('./ml-data/providers-train.csv', encoding='latin1')
fine_counts = data.pop('FINE_CNT')
fine_totals = data.pop('FINE_TOT')
cycle_2_score = data.pop('CYCLE_2_TOTAL_SCORE')
X_train, X_test, y_train, y_test = train_test_split(
data,
fine_counts > 1,
test_size=0.20
)
return X_train, y_train, X_test, y_test
X_train, y_train, X_test, y_test = generate_classification_data()
auto_ml = auto_ml.fit(X_train, y_train)
Output as follows:-
/ Users / simon / venvs / wqu_q4 / bin / python /Users/simon/Dev/wqu_q4/main.py новая пробная версия: {"ChooseOneStepOf": {"choice": "RidgeClassifier"}} <neuraxle.metaopt.trial.Trial объект в 0x134a469d0> испытание 1/10<neuraxle.metaopt.trial.Trial объект в 0x134a469d0><neuraxle.metaopt.trial.Trial объект в 0x134a469d0><neuraxle.metaopt.trial.Trial объект в 0x134a469d0>.Trial объект в 0x134a469d0><neuraxle.metaopt.trial.Trial объект в 0x134a469d0><neuraxle.metaopt.trial.Trial объект в 0x134a469d0><neuraxle.metaopt.trial.Trial объект в 0x134a469d0> последний Trail Файл "/Users/simon/venvs/wqu_q4/lib/python3.9/site-packages/neuraxle/metaopt/auto_ml.py", строка 785, в _fit_data_container repo_trial_split = self.trainer.execute_trial (файл "/Users/simon/venvs/wqu_q4/lib/python3.9/site-packages/neuraxle/metaopt/trial.py", строка 290, ввыйти поднять exc_val Файл "/Users/simon/venvs/wqu_q4/lib/python3.9/site-packages/neuraxle/metaopt/auto_ml.py", строка 785, в _fit_data_container repo_trial_split = self.trainer.execute Users_trial (File "/ /simon/venvs/wqu_q4/lib/python3.9/site-packages/neuraxle/metaopt/auto_ml.py ", строка 595, в execute_trial self.print_func ('оценка успеха {}:{}'. формат (файл" /Users/simon/venvs/wqu_q4/lib/python3.9/site-packages/neuraxle/metaopt/trial.py ", строка 570, на выходеRaise exc_val File "/Users/simon/venvs/wqu_q4/lib/python3.9/site-packages/neuraxle/metaopt/auto_ml.py", строка 574, в execute_trial trial_split_description = _get_trial_split_description (File "/Users / simon / venvscription (File) wqu_q4 / lib / python3.9 / site-packages / neuraxle / metaopt / auto_ml.py ", строка 876, в _get_trial_split_description json.dumps (repo_trial.hyperparams, sort_keys = True, indent = 4) File" / usr / local / Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/init.py ", строка 234, в дампах возвращает cls (Файл" /usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/encoder.py ", строка 201, в файле encode chunks = list(chunks) File" /usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/encoder. py ", строка 431, в _iterencode yield from _iterencode_dict (o, _current_indent_level) File" /usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json /encoder.py ", строка 405, в _iterencode_dict yield from chunks File" /usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/encoder .py ", строка 438, в _iterencode o = _default (o) File" /usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9 / json / encoder.py ", строка 179, по умолчанию вызывает TypeError(f'Object типа {o.класс . имя} 'TypeError: объект типа типа не сериализуемый JSON Во время обработки вышеуказанного исключения произошло другое исключение: Traceback (последний вызов последним): файл "/Users/simon/Dev/wqu_q4/main.py", строка 210, в файле auto_ml =auto_ml.fit(X_train, y_train) "/Users/simon/venvs/wqu_q4/lib/python3.9/site-packages/neuraxle/base.py", строка 3475, в соответствии с new_self = self.handle_fit (data_container, context) Файл "/Users/simon/venvs/wqu_q4/lib/python3.9/site-packages/neuraxle/base.py", строка 980, в handle_fit new_self = self._fit_data_container (data_container, context) File "/Users / simon / venvs / wqu_q4 / lib / python3.9 / site-packages / neuraxle / metaopt / auto_ml.py ", строка 802, в _fit_data_container repo_trial_split = repo_trial_split, UnboundLocalError: локальная переменная 'repo_trial_split'на которую ссылались до присвоения Процесс завершился с кодом выхода 1
1 ответ
Несколько примечаний, которые могут помочь вам с вашей текущей проблемой:
«UnboundLocalError: локальная переменная 'repo_trial_split', на которую ссылается до назначения» - это ошибка, которая возникает, когда что-то выходит из строя в конвейере в цикле AutoML. Вы должны зарегистрировать настоящую ошибку где-то над той, которую вы разместили здесь. Кроме того, Neuraxle версии 0.5.7 (которая еще не выпущена, но доступна на github) исправляет это, добавляя аргумент с именем continue_loop_on_error, который вы должны установить в False.
Кажется, вы используете ForceHandleMixin для своего экземпляра ColumnSelectTransformer. Это здорово, потому что я считаю, что AutoML использует дескрипторы, а не типичный интерфейс fit/fit_transform/transform. Использование ForceHandleMixin означает, что вы должны определить следующие функции _fit_data_container, _transform_data_container и _fit_transform_data_container, а не fit/fit_transform/transform.
Вероятно, вам нужно написать класс Neuraxle, чтобы обернуть scikit SimpleImputer.
Надеюсь, это тебе поможет. Не стесняйтесь размещать здесь обновления, как только вы внесете эти изменения, и я буду рад вам помочь. Вы также можете опубликовать сообщение в Slack Neuraxle, и я могу быстрее ответить там.
Ваше здоровье!
ps С другой стороны, я сделаю релиз 0.5.7 в ближайшие несколько дней.