склеарнское стратифицированное К-кратное CV с линейной моделью типа ElasticNetCV - PullRequest
0 голосов
/ 01 марта 2019

с использованием перекрестной проверки (CV) с sklearn довольно просто и понятно.Но реализацией по умолчанию при установке cv=5 в линейной модели CV, такой как ElasticNetCV или LassoCV, является KFold CV.По разным причинам я хотел бы использовать StratifiedKFold.Из документации кажется, что любой CV метод может быть задан с cv=.

Передача cv=KFold(5) работает, как и ожидалось, но cv=StratifiedKFold(5) вызываетОшибка:

ValueError: Поддерживаемые целевые типы: («двоичный», «мультиклассовый»).Вместо этого получил «непрерывный».

Я знаю, что могу использовать cross_val_score после подгонки, но я бы хотел передать StratifiedKFold в качестве CV непосредственно в линейную модель.

Мой минимальный рабочий пример:

from sklearn.linear_model import ElasticNetCV
from sklearn.model_selection import KFold, StratifiedKFold
import numpy as np

x = np.arange(100, dtype=np.float64).reshape(-1, 1)
y = np.arange(100) + np.random.rand(100)

# KFold default implementation:
model_default = ElasticNetCV(cv=5)
model_default.fit(x, y)  # works fine
# KFold given as cv explicitly:
model_kfexp = ElasticNetCV(cv=KFold(5))
model_kfexp.fit(x, y)  # also works fine

# StratifiedKFold given as cv explicitly:
model_skf = ElasticNetCV(cv=StratifiedKFold(5))
model_skf.fit(x, y)  # THIS RAISES THE ERROR

Есть идеи, как напрямую установить StratifiedKFold в качестве резюме?

1 Ответ

0 голосов
/ 01 марта 2019

Корень вашей проблемы - эта строка:

y = np.arange(100) + np.random.rand(100)

StratifiedKFold не может выполнить выборку из непрерывного распределения, следовательно, ваша ошибка.Попробуйте изменить эту строку, и ваш код будет успешно выполнен:

from sklearn.linear_model import ElasticNetCV
from sklearn.model_selection import KFold, StratifiedKFold
import numpy as np

x = np.arange(100, dtype=np.float64).reshape(-1, 1)
y = np.random.choice([0,1], size=100)

# KFold default implementation:
model_default = ElasticNetCV(cv=5)
model_default.fit(x, y)  # works fine
# KFold given as cv explicitly:
model_kfexp = ElasticNetCV(cv=KFold(5))
model_kfexp.fit(x, y)  # also works fine

# StratifiedKFold given as cv explicitly:
model_skf = ElasticNetCV(cv=StratifiedKFold(5))
model_skf.fit(x, y)  # no ERROR

NOTE

Если вы производите выборку на непрерывных данных, используйте KFold.Если ваша цель категорична, вы можете использовать KFold и StratifiedKFold, в зависимости от ваших потребностей.

ПРИМЕЧАНИЕ 2

Если вы настаиваете на эмулируя стратифицированную выборку на непрерывных данных, вы можете применить pandas.cut к вашим данным, затем выполнить стратифицированную выборку на этих данных и, наконец, передать полученный генератор (train_id, test_id) в cv параметр:

x = np.arange(100, dtype=np.float64).reshape(-1, 1)
y = np.arange(100) + np.random.rand(100)

y_cat = pd.cut(y, 10, labels=range(10))
skf_gen = StratifiedKFold(5).split(x, y_cat)

model_skf = ElasticNetCV(cv=skf_gen)
model_skf.fit(x, y)  # no ERROR
...