为分组数据生成具有特定长度的RNN的序列/批次

时间:2018-10-01 15:46:58

标签: python pandas numpy tensorflow keras

当我希望将不同组中的数据传递到RNN时,问题就出现了-大多数示例都假定时间序列优美,但是在添加组时,我们不能简单地在数据框上进行浏览,而是需要在组更改时跳转,以便数据来自组内。

这些小组是不同的人,所以我想保持自己的顺序。例如。用户浏览网站,然后我们收集综合浏览量数据。或者可能是不同的股票及其相关的价格变动。

import pandas as pd
data = {
    'group_id': [1,1,1,1,2,2],
    'timestep': [1,2,3,4,1,2],
    'x': [6,5,4,3,2,1],
    'y': [0,1,1,1,0,1]
}
df = pd.DataFrame(data=data)


   group_id  timestep  x  y
0         1         1  6  0
1         1         2  5  1
2         1         3  4  1
3         1         4  3  1
4         2         1  2  0
5         2         2  1  1

假设我们要使用2个样本的批次大小,每个样本将具有3个时间步长。 RNNSequence.__len__ = 3(以下)批次,但这是不可能的,因为我们最多只能从第1组(即1批次)中获得2个样品。第二组只有两个时间步长,因此不可能进行迭代。

from keras.utils import Sequence

class RNNSequence(Sequence):

    def __init__(self, x_set, y_set, batch_size, seq_length):
        self.x, self.y = x_set, y_set
        self.batch_size = batch_size
        self.seq_length = seq_length

    def __len__(self):
        return int(np.ceil(len(self.x) / float(self.batch_size)))

    def __getitem__(self, idx):
        # get_batch to be coded
        return get_batch(idx, self.x, self.y, self.batch_size, self.seq_length)

使用序列获取这些批次的最有效方法是什么?

我的解决方案是实际上不使用Sequence,而是使用自定义生成器,该生成器在不知道会有多少批次的情况下吐出数据。并改用fit_generator(custom_generator, max_queue_size=batch_size)。这是最有效的方法吗?这里的问题是没有改组,这可能是个问题吗?

batchsize = 2,seq_length = 3的所需输出为:

X = [ 
        [ [6], [5], [4] ], 
        [ [5], [4], [3] ] 
    ]

Y = [ 1, 1 ]

1 个答案:

答案 0 :(得分:1)

看来您不仅需要知道批次的数量,而且还能够仅给出批次号就可以输出任何批次。您可以在RNNSequence.__init__或更早的版本中创建所有样本的索引,然后从中组装批次。然后,您可以在__getitem__中相应地输出批次。

此快速而肮脏的伪代码应说明样本索引的概念。如果需要,您可以决定使用pandas或numpy等函数。

# Pseuducode for generating indexes for where samples start.
seq_len = 3
sample_start_ids = []
for group_id, group in enumerate(groups):
    for timestep_id, timestep in enumerate(group_timesteps):
        # Only add as sample if it is the first
        # timestep in the group or if a full sample fits.
        if timestep == 1 or timestep <= len(group_timesteps) - seq_len+1:
            sample_start_ids.append((group_id, timestep_id))

num_samples = len(sample_start_ids)

# Group the samples into batches of appropriate size.
pass

num_batches = len(your_batches)