不平衡的面板数据:如何使用时间序列拆分交叉验证?

4

我目前正在处理一份庞大的不平衡数据集,并想知道是否可以使用sklearn中的Time Series Splits Cross-Validation将我的训练样本分成几个“折叠”。我希望每个折叠只包含特定时间段内的截面观察。

如先前所述,我正在处理一个利用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
TimeSeriesSplitKFold的一种变种,可以确保每个连续折叠中索引值按升序排列。正如文档中所述:

在每个划分中,测试索引必须高于之前... [还要] 注意,与标准交叉验证方法不同,连续的训练集是之前训练集的超集。

请注意,KFoldTimeSeriesSplit返回的是索引。您已经拥有了所需的索引。docs 一个问题是,在 MultiIndex 中访问 DateTimeIndex 切片过于困难和复杂。请参见这里, 这里这里。由于此时您正在提取数据,因此重置索引并进行切片似乎是可接受的。特别是由于重置索引不会在原地进行。

最后,我建议将类似 datetime 的索引转换为实际的 datetime 数据类型。

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)]

谢谢您的回答。我有一个小问题:如何与网格搜索结合使用,以便在3个折叠中选择评估出的“最佳”参数? - Rik
我猜你最终会使用GridSearchcv参数和/或PredefinedSplit来完成,但这似乎超出了问题的范围。如果你遇到麻烦,可以考虑发布一个新问题。 - Charles Landau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接