aimclub / FEDOT

Automated modeling and machine learning framework FEDOT
https://fedot.readthedocs.io
BSD 3-Clause "New" or "Revised" License
632 stars 86 forks source link

Usability feature: add check for consistency between model & task #947

Closed aPovidlo closed 1 year ago

aPovidlo commented 1 year ago

Output of 'logit' is 2-dim array and it cause error while trying get metrics.

Error message:

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm 2021.3.1\plugins\python\helpers\pydev\pydevd.py", line 1483, in _exec
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm 2021.3.1\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/Users/andre/Documents/GitHub/FEDOT/temp.py", line 197, in <module>
    repeat_logit_prediction()
  File "C:/Users/andre/Documents/GitHub/FEDOT/temp.py", line 191, in repeat_logit_prediction
    metrics_result = model.get_metrics(metric_names=['rmse', 'mae', 'r2'])
  File "C:\Users\andre\Documents\GitHub\FEDOT\fedot\api\main.py", line 380, in get_metrics
    metric_value = abs(metric_cls.metric(reference=real,
  File "C:\Users\andre\Documents\GitHub\FEDOT\fedot\core\composer\metrics.py", line 150, in metric
    return mean_squared_error(y_true=reference.target,
  File "C:\Users\andre\Documents\GitHub\FEDOT\venv\lib\site-packages\sklearn\metrics\_regression.py", line 442, in mean_squared_error
    y_type, y_true, y_pred, multioutput = _check_reg_targets(
  File "C:\Users\andre\Documents\GitHub\FEDOT\venv\lib\site-packages\sklearn\metrics\_regression.py", line 111, in _check_reg_targets
    raise ValueError(
ValueError: y_true and y_pred have different number of output (1!=136)

Script for repeating the bug:

data_path = f'{fedot_project_root()}/cases/data/cholesterol/cholesterol.csv'

data = InputData.from_csv(data_path,
                          task=Task(TaskTypesEnum.regression))

train, test = train_test_data_setup(data)
problem = 'regression'

model = Fedot(
    problem=problem,
    metric='mae',
    logging_level=logging.DEBUG,
)

model.fit(features=train, predefined_model='logit')

prediction = model.predict(features=test)
valer1435 commented 1 year ago

problem = 'regression'

И

model.fit(features=train, predefined_model='logit')

Так и должно быть?

gkirgizov commented 1 year ago

Кажется, не хватает строчки metris = model.get_metrics(test.target)

gkirgizov commented 1 year ago

Действительно, а что ожидается получить от logit при регрессии? Классификация тоже не подходит, тк данные под регрессию. logit выдает вероятности для int-ов из колонки target -- потому 136-размерный массив.

Кажется, что все в порядке. Разве что можно как-нибудь ловить несоответствие модели и задачи. И разве это уже где-то не проверятся?

aPovidlo commented 1 year ago

Действительно, а что ожидается получить от logit при регрессии? Классификация тоже не подходит, тк данные под регрессию. logit выдает вероятности для int-ов из колонки target -- потому 136-размерный массив.

Кажется, что все в порядке. Разве что можно как-нибудь ловить несоответствие модели и задачи. И разве это уже где-то не проверятся?

Да, в режиме "вижу цель, не вижу преград" решил натравить logit на регрессию, а федот меня пропустил испугавшись моего порыва. Возможно, стоит добавить проверку несоответствия моделей и задачи.

nicl-nno commented 1 year ago

Тогда это явно не блокер для примеров, поэтому можно и потом порешать.

gkirgizov commented 1 year ago

Добавлю тогда проверку несоответствия моделей и задачи. Для user-friendliness.

А еще, в ходе investigation я обнаружил такую потенциальную проблему. Если в тестовую и тренировочную выборки случайно попадают разные количества target классов (что становится более вероятным при небольших выборках, большом количестве классов и их несбалансированности), то train_data.num_classes != test_data.num_classes, что ведет к ошибке несоответствия размерностей в модели при валидации. Нужно как-то иначе считать data.num_classes.