Evalml: BalancedClassificationDataCVSplit производит разные разделения каждый раз, когда вызывается.

Созданный на 16 мар. 2021  ·  3Комментарии  ·  Источник: alteryx/evalml

Репро

import joblib
from evalml.demos import load_fraud
from evalml.preprocessing.data_splitters import BalancedClassificationDataCVSplit

splitter = BalancedClassificationDataCVSplit(n_splits=3, random_seed=0, shuffle=True)

X, y = load_fraud(5000)
X = X.to_dataframe()
y = y.to_series().astype("int")

for train, test in splitter.split(X, y):
    print((joblib.hash(train), joblib.hash(test)))

# Output
('75f1b95d7ce307ac6c793055330969aa', '8c89fe1a592c50a700b6d5cbb02dba8b')
('f8c849bbfbed37c13f66c5c742e237cb', '9c4879fb550fded8be9ac03e95a1bf95')
('cdc21f0d6bbf45459c9695258f7f04dc', '5b575765bbe176e732b8eb4dc1bf2822')

for train, test in splitter.split(X, y):
    print((joblib.hash(train), joblib.hash(test)))

# Output
('bf462b82af243c552ac48acad2dfd748', '8c89fe1a592c50a700b6d5cbb02dba8b')
('b8341b536c63c7957c099b05e315f49c', '9c4879fb550fded8be9ac03e95a1bf95')
('780e74673b601790037fc0b17dde56fe', '5b575765bbe176e732b8eb4dc1bf2822')

for train, test in splitter.split(X, y):
    print((joblib.hash(train), joblib.hash(test)

# Output
('385f6c538568ad3a33cf84f61d94144c', '8c89fe1a592c50a700b6d5cbb02dba8b')
('8db65d0a3bdf87ae0f135b9766a260dd', '9c4879fb550fded8be9ac03e95a1bf95')
('2a7293fc1308b8a572091d7c76d20205', '5b575765bbe176e732b8eb4dc1bf2822')

Это отличается от поведения разделителя sklearn:

from sklearn.model_selection import StratifiedKFold

kfold = StratifiedKFold(n_splits=3, random_state=0, shuffle=True)

for train, test in kfold.split(X, y):
    print((joblib.hash(train), joblib.hash(test)))

#Output
('6c30ee6a11803927024354405389506a', '8c89fe1a592c50a700b6d5cbb02dba8b')
('df0a70e2e6ca783f12461e8c82a26ad4', '9c4879fb550fded8be9ac03e95a1bf95')
('2898e4b3d3621b436641016499f4aafb', '5b575765bbe176e732b8eb4dc1bf2822')

for train, test in kfold.split(X, y):
    print((joblib.hash(train), joblib.hash(test)))

# Output
('6c30ee6a11803927024354405389506a', '8c89fe1a592c50a700b6d5cbb02dba8b')
('df0a70e2e6ca783f12461e8c82a26ad4', '9c4879fb550fded8be9ac03e95a1bf95')
('2898e4b3d3621b436641016499f4aafb', '5b575765bbe176e732b8eb4dc1bf2822')

Думаю, это проблематично по двум причинам:

  1. Поскольку BalancedClassificationDataCVSplit является разделителем по умолчанию в automl, это означает, что наши конвейеры оцениваются на разных разделах.
  2. Поскольку split изменяет состояние разделителя данных, это означает, что у нас будут разные результаты между последовательными и параллельными механизмами.

Все 3 Комментарий

Спасибо за указание на это.

Лично меня такое поведение не беспокоит. Если каждый раз, когда мы инициализируемся определенным семенем, после этого момента мы получаем ту же последовательность вывода, все в порядке. Я был бы обеспокоен, если бы мы не уважали случайное семя; но проблема не в этом.

Моя рекомендация: ничего не делать. Таким образом, закрытие.

@freddyaboulton, если вы не согласны с таким поведением, давайте разберемся, я имею в виду поговорить 😅

@dsherry Я думаю, что это стоит изменить по двум причинам:

  1. Это вносит различия в автоматический поиск, поскольку разные конвейеры оцениваются на разных данных. Это делает таблицу рейтингов несколько вводящей в заблуждение, поскольку оценки не рассчитываются на основе одних и тех же данных.
  2. Плохо для параллельного автоматического поиска

    Позвольте мне подробнее остановиться на 2. При текущем поведении ожидается, что последовательный механизм будет изменять состояние разделителя данных во время поиска. В параллельном evalml мы обрабатываем разделитель данных и отправляем его работникам для вычисления разделения. Поскольку рабочие получают копию разделителя, они не изменяют состояние исходного разделителя данных.

Это приводит к различию в поведении последовательного и параллельного движков, потому что разбиения не будут совпадать в зависимости от порядка оценки конвейера! Это означает, что одна и та же комбинация конвейера / параметра будет давать разные результаты в последовательном механизме и параллельном механизме, и я думаю, что это нежелательно.

На мой взгляд, пункт 1 является достаточной причиной, чтобы исправить это, потому что все наши конвейеры должны оцениваться на одних и тех же данных, если мы хотим иметь возможность их значимого сравнения. Но по мере того, как мы движемся к параллельному evalml, я думаю, важно убедиться, что изменение глобального состояния не является частью нашего ожидаемого поведения.

План продвижения вперед:

  1. Исправьте эту проблему, изменив BalancedClassificationDataCVSplit
  2. В долгосрочной перспективе мы хотели бы написать тесты, которые проверяют, что мы не передаем разные расщепления в разные конвейеры в автоматическом поиске.

Всем спасибо за обсуждение!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги