带有时间序列特征一维数据 如何生成lstm的三维输入数据(batch_size ,sequence,feuture) 对一维销量数据进行销量预测,python pytorch
实例 参考 如何为LSTM重新构建输入数据(Keras)-CSDN博客
方法1 batch_size=1, sequence 用list[pos1,len]
数据集如下(永久有效)
链接:https://pan.baidu.com/s/1VGWpGuNM4PUVzoULaCUyGA
提取码:zxt1
数据十分简单,就只有日期,以及对应的销量。
目标
一维度的带有时间序列特征的数据,变成三维数据
实现方法
(batch_size ,sequence,feuture)batch_size 是批次的意思,
举例说明:某工厂生成月饼,每个周算有个批次,每次生成的东西基本都是一样的。
batch_size 这里为1,所以,只要扩充形状即可,不需要转换
sequence 句子长度
举例说明 : 月饼盒子里面有几个月饼, 月饼的数量
这里sequece ,句子长度 可以认为设定,比如2,也可以10
利用 python list[pos1:len]
代码部分
def create_dataset(list, look_back):
#这里的look_back与timestep相同
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = list[i:(i+look_back)]
b = list[i + look_back]
dataX.append(a)
dataY.append(b )
return numpy.array(list),numpy.array(dataY)
#训练数据太少 look_back并不能过大
look_back = 1
trainX,trainY = create_dataset(trainlist,look_back)
testX,testY = create_dataset(testlist,look_back)
trainX = numpy.reshape(trainX, (trainX.shape[0], trainX.shape[1], 1))
testX = numpy.reshape(testX, (testX.shape[0], testX.shape[1] ,1 ))
dataframe = pd.read_csv(r"D:\桌面文件夹哦\数据统计\悠度数据\2特征.CSV", usecols=[1], engine='python', skipfooter=3)
dataset = dataframe.values
# 将整型变为float
dataset = dataset.astype('float32')
#归一化
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
train_size = int(len(dataset) * 0.80)
trainlist = dataset[:train_size]
testlist = dataset[train_size:]
===========================================================
另一个方法 pad_sequences程序包
keras
import numpy as np
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 假设 list 是你的一维数组
list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 确定序列长度
sequence_length = 3
# 创建数据集
sequences = [list[i:i+sequence_length] for i in range(len(list) - sequence_length + 1)]
print(sequences)
# 填充序列以确保它们具有相同的长度
padded_sequences = pad_sequences(sequences, padding='post', dtype='float32')
# 现在 padded_sequences 可以作为 LSTM 的输入
# 它的形状将是 (样本数, 时间步长, 特征数)
# 在这个例子中,特征数是 1,因为我们的原始数据是一维的
print(padded_sequences.shape)
print(padded_sequences)
pytorch
在PyTorch中,`pad_sequence`是一个非常有用的函数,它可以用来对不同长度的序列进行填充,使得它们具有相同的长度,从而可以被打包(packed)或批处理(batched)输入到RNN、LSTM或GRU等循环神经网络模型中。这个函数的使用方法如下:
```python
from torch.nn.utils.rnn import pad_sequence
# 假设我们有三个不同长度的序列
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5])
c = torch.tensor([6])
# 使用pad_sequence进行填充,使得所有序列长度相同
padded_seqs = pad_sequence([a, b, c], batch_first=True, padding_value=0)
print(padded_seqs)
```
`pad_sequence`函数接受一个序列的列表作为输入,并且可以指定`batch_first`参数来决定输出张量的第一个维度是批次大小还是序列长度。`padding_value`参数用于指定填充值,默认为0。填充后的张量可以作为RNN层的输入。
如果你需要将填充后的序列再次转换为可变长度的序列,可以使用`pad_packed_sequence`函数,它是`pack_padded_sequence`的逆操作。例如:
```python
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
# 假设seq是一个填充后的序列张量,lens是每个序列的实际长度列表
packed_seqs = pack_padded_sequence(seq, lens, batch_first=True, enforce_sorted=False)
# ... 在这里将packed_seqs输入到RNN中 ...
# 将打包的序列解压回填充的序列
seq_unpacked, lens_unpacked = pad_packed_sequence(packed_seqs, batch_first=True)
```
在这里,`seq`是填充后的序列张量,`lens`是每个序列的实际长度列表。`pack_padded_sequence`函数会根据序列的实际长度来打包序列,而`pad_packed_sequence`函数则将打包的序列解压回填充的序列。
这些操作对于处理可变长度的序列数据非常重要,尤其是在自然语言处理和时间序列分析等场景中。通过使用这些函数,我们可以确保模型能够正确地处理不同长度的输入序列。
注意 整数和浮点数的区别
在Python中,`[ 1. 2. 3.]` 和 `[1, 2, 3]` 这两个列表看起来相似,但实际上它们在类型和用途上有一些关键的区别:
1. **浮点数与整数**:
- `[ 1. 2. 3.]`:这个列表中的元素是浮点数(float)。浮点数可以表示有小数部分的数字,例如1.0, 2.0, 3.0。
- `[1, 2, 3]`:这个列表中的元素是整数(int)。整数只能表示没有小数部分的数字,例如1, 2, 3。
2. **内存占用**:
- 浮点数通常占用更多的内存空间(通常是4字节或8字节,取决于系统和Python的实现),因为它们需要存储更多的信息(整数部分、小数部分和指数部分)。
- 整数占用的内存通常较少(通常是4字节或8字节,取决于整数的大小)。
3. **运算精度**:
- 浮点数在进行运算时可能会有精度损失,因为它们使用二进制格式表示,而某些十进制小数在二进制中无法精确表示。
- 整数在运算时不会有精度损失,因为它们可以直接用二进制表示。
4. **使用场景**:
- 浮点数通常用于需要表示小数的场景,如科学计算、金融计算等。
- 整数通常用于不需要小数的场景,如计数、索引等。
5. **Python中的表示**:
- 在Python中,即使在列表中,浮点数和整数也会保持它们的类型。例如,`[ 1. 2. 3.]` 中的元素类型是 `float`,而 `[1, 2, 3]` 中的元素类型是 `int`。
6. **转换**:
- 你可以使用 `float()` 函数将整数转换为浮点数,例如 `float([1, 2, 3])` 会得到 `[1.0, 2.0, 3.0]`。
- 你可以使用 `int()` 函数将浮点数转换为整数,但请注意,这会丢失小数部分,例如 `int([1.9, 2.1, 3.5])` 会得到 `[1, 2, 3]`。
总结来说,`[ 1. 2. 3.]` 和 `[1, 2, 3]` 主要区别在于它们元素的数据类型:一个是浮点数,另一个是整数。这会影响它们的内存占用、运算精度和适用场景。
第三个方法 ,pad_sequences 结合dataloader pytorch
**`pack_sequence`**:
这个函数用于将不等长的序列列表打包成一个`PackedSequence`对象,不涉及填充。它用于序列长度已经相同,但仍然需要打包的情况。这在处理序列数据时非常有用,尤其是当你想要有效地传递序列数据到RNN时。
```python
packed_input = pack_sequence(padded_seqs, enforce_sorted=False)
```
- `padded_seqs`:一个`nn.ModuleList`或序列张量的列表,所有序列长度必须相同。
- `enforce_sorted`:一个布尔值,指示序列是否已经根据长度降序排列。
您提供的代码示例是一个自定义的 `collate_fn` 函数,它用于 PyTorch 的 `DataLoader`。这个函数的目的是将数据集中的一批数据(一个批次)转换为适合模型训练的格式。下面是对这个 `collate_fn` 函数的详细解释:
```python
def collate_fn(batch):
# `batch` 是一个列表,其中包含了多个元组(或其他形式的数据结构),每个元组代表一个数据点。
# 假设每个元组的第一个元素是序列数据,第二个元素是该序列的长度。
# `zip(*batch)` 会将 `batch` 中的元组按照位置拆开,例如,如果 `batch` 是 `[(seq1, len1), (seq2, len2), ...]`,
# 那么 `zip(*batch)` 将会是 `(iter([seq1, seq2, ...]), iter([len1, len2, ...]))`。
sequences, lengths = zip(*batch)
# 将长度列表转换为 PyTorch 张量
lengths = torch.tensor(lengths)
# 使用 `pad_sequence` 函数对序列进行填充,使得所有序列长度相同。
# `batch_first=True` 表示返回的填充后的张量的第一个维度是批次大小。
padded_seqs = pad_sequence(sequences, batch_first=True)
# 返回填充后的序列和对应的长度张量
return padded_seqs, lengths
```
然后,这个 `collate_fn` 函数被用作 `DataLoader` 的参数:
```python
loader = DataLoader(dataset, batch_size=32, collate_fn=collate_fn)
```
- `dataset` 是一个 PyTorch 数据集对象,它应该实现了 `__len__` 和 `__getitem__` 方法。
- `batch_size=32` 表示每个批次包含 32 个数据点。
- `collate_fn=collate_fn` 指定了自定义的 `collate_fn` 函数,用于处理每个批次的数据。
当 `DataLoader` 迭代数据集时,它会调用 `collate_fn` 来处理每个批次的数据。这样,模型就可以接收到格式一致的输入,即使原始数据中的序列长度不同。
在训练循环中,你可以通过迭代 `loader` 来获取处理好的批次数据:
```python
for batch in loader:
padded_seqs, lengths = batch
# 现在可以将 padded_seqs 和 lengths 用作模型的输入
# ...
```
请注意,`collate_fn` 函数需要能够处理你的具体数据格式。上面的代码只是一个示例,你可能需要根据你的数据集和模型的具体需求来调整它。
4. **`pad`**: