keras.preprocessing.timeseries_dataset_from_array 较小数据集下的充分使用

场景:严格意思上不应存在这种场景,如果存在,说明数据量太小了。举个例子,假设仅有29条数据的情况下,使用LSTM模型,如果直接使用该函数进行归集数据,则会造成验证集数据的一些浪费。

1.函数介绍

可以使用此函数在序列数据上重新归集滑动窗口数据。

keras.preprocessing.timeseries_dataset_from_array(
    data,
    targets,
    sequence_length,  # 窗口大小
    sequence_stride=1, #连续输出序列之间的周期。对于步幅s,输出采样将开始索引data[i],data[i + s],data[i + 2 * s],等。
    sampling_rate=1, # 序列中连续的各个时间步之间的时间间隔。对于rate r,时间步 用于创建样本序列。 data[i], data[i + r], ... data[i + sequence_length]
    batch_size=128,  # 每批中时间序列样本的数量
    shuffle=False,
    seed=None,
    start_index=None,
    end_index=None,
)

2.官方案例

0-99的序列数据,以10个单位为滑动窗口数据,每次取数间隔2,下一集合数据跨越3个。

Example 1:
  Consider indices `[0, 1, ... 99]`.
  With `sequence_length=10,  sampling_rate=2, sequence_stride=3`,
  `shuffle=False`, the dataset will yield batches of sequences
  composed of the following indices:

```
First sequence:  [0  2  4  6  8 10 12 14 16 18]
Second sequence: [3  5  7  9 11 13 15 17 19 21]
Third sequence:  [6  8 10 12 14 16 18 20 22 24]
...
Last sequence:   [78 80 82 84 86 88 90 92 94 96]
```

In this case the last 3 data points are discarded since no full sequence
can be generated to include them (the next sequence would have started
at index 81, and thus its last step would have gone over 99).

3.LSIM案例

(29,3)的0-28的序列。

d = {'a': [i for i in range(29)], 'b': [i for i in range(29)], 'c': [i for i in range(29)]}
df = pd.DataFrame(d)
df.head(5)

 

 如果使用前3个数据集,预测下一个c列数据。训练集为前80个数据,测试集为20个数据。构建训练集的时候,因为c列数据足够多,能够完整构造数据。但是测试集中,由于要求data和targets长度需要相等,因此直接使用该函数归并会导致测试集少past-1个数据。

step = 1 # 数据的选取步频
train_split = 20
past = 3 # 使用前3个数据时间进行预测,时间窗口
future = 0 # 预测0个数据时点后的数据,就是下一个时点


features = pd.DataFrame(df.values)
features = features.astype('float64')

val_data = features.loc[train_split:]  # 测试数据

 

# 构造验证数据
label_start =past + future # 因为用前past个时点进行去测,所以要从第4个开始(即3)

# 测试值已经再尾部了,所以要腾挪出(future+1)个来
x_val = val_data[:-(future+1)][[i for i in range(3)]].values
# 由于输入的序列长度需要一样,所以需要补充y_val序列长度,补充传长度为past-(future+1)
y_val = val_data.iloc[label_start:][[2]] # 为了补空
for i in range(past-(future+1)):
    y_val.loc['n'+str(i)] = 0 

dataset_val = keras.preprocessing.timeseries_dataset_from_array(
    x_val,
    y_val,
    sequence_length=sequence_length,
    sampling_rate=step,
    batch_size=batch_size,
)

补0之后,测试数据比原来数据多past-1个,2个。

# 输出数据
for batch in dataset_val.take(1):
    inputs, targets = batch

print("val Input shape:", inputs.numpy().shape)
print("val Target shape:", targets.numpy().shape)

 

posted @ 2021-05-23 21:12  forxtz  阅读(830)  评论(0编辑  收藏  举报