Несбалансированные данные панели: как использовать перекрестную проверку разделений временных рядов? - PullRequest
2 голосов
/ 29 мая 2019

В настоящее время я работаю с большим несбалансированным набором данных, и мне было интересно, можно ли использовать перекрестную проверку разделений временного ряда из sklearn, чтобы разбить мой тренировочный образец на несколько «сгибов».Я хочу, чтобы в каждом сгибе были только наблюдения в разрезе в течение определенного периода времени.

Как уже упоминалось ранее, я работаю с несбалансированным набором данных панели, который использует мультииндексирование от Pandas.Вот воспроизводимый пример для обеспечения некоторой дополнительной интуиции:

arrays = [np.array(['A', 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'D', 'D']),
           np.array(['2000-01', '2000-02', '2000-03', '1999-12', '2000-01', 
          '2000-01', '2000-02', '1999-12', '2000-01', '2000-02', '2000-03'])]

s = pd.DataFrame(np.random.randn(11, 4), index=arrays)

, который выглядит следующим образом: enter image description here

Например, я хотел бы изначально иметь всеединицы поперечного сечения в 1999-12 годах в качестве учебной выборки и все единицы поперечного сечения в 2000-01 годах в качестве проверки.Далее, я хочу, чтобы все поперечные единицы в 1999-12 и 2000-01 гг. Были учебными, а все поперечные единицы в 2000-02 гг. - проверочными, и так далее.Возможно ли это с помощью функции TimeSeriesSplit или мне нужно искать где-нибудь еще?

1 Ответ

1 голос
/ 29 мая 2019

TimeSeriesSplit - это вариация KFold, которая обеспечивает восходящие значения индекса для каждого последующего сгиба.Как отмечено в документах:

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

документы

Также помните, что KFold и TimeSeriesSplit возвращают индексы .У вас уже есть нужный индекс.

Одна из проблем заключается в том, что доступ к срезу DateTimeIndex в MultiIndex слишком сложен и сложен.См. здесь , здесь и здесь .Так как вы все равно извлекаете данные на этом этапе, сброс индекса и среза кажется приемлемым.Тем более что сброс индекса не происходит на месте.

Наконец, я рекомендую привести этот подобный дате и времени индекс к фактическому типу данных даты и времени.

import pandas as pd
import numpy as np
import datetime
arrays = [np.array(['A', 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'D', 'D']),
           np.array(['2000-01', '2000-02', '2000-03', '1999-12', '2000-01', 
          '2000-01', '2000-02', '1999-12', '2000-01', '2000-02', '2000-03'])]

# Cast as datetime
arrays[1] = pd.to_datetime(arrays[1])


df = pd.DataFrame(np.random.randn(11, 4), index=arrays)
df.index.sort_values()


folds = df.reset_index() # df still has its multindex after this

# You can tack an .iloc[:, 2:] to the end of these lines for just the values
# Use your predefined conditions to access the datetimes
fold1 = folds[folds["level_1"] <=datetime.datetime(2000, 1, 1)]
fold2 = folds[folds["level_1"] == datetime.datetime(2000, 2, 1)]
fold3 = folds[folds["level_1"] == datetime.datetime(2000, 3, 1)]
...