如何在Python中扩展LSTM网络的数据

2017年07月12日 由 yuxiangyu 发表 902001 0
您的序列预测问题的数据可能需要在训练神经网络时进行缩放,例如LSTM递归神经网络

当网络适合具有一定范围值(例如10s到100s的数量)的非标度数据时,大量的输入可能会降低网络的学习和收敛速度,并且在某些情况下可能会阻止网络有效学习问题。

在本教程中,您将发现如何归一化和标准化序列预测数据,以及如何确定哪些用于输入和输出变量。

完成本教程后,您将知道:

  • 如何在Python中归一化和标准化序列数据。

  • 如何为输入和输出变量选择适当的缩放比例。

  • 缩放序列数据的实际问题。


让我们开始吧。

如何在Python中扩展LSTM网络的数据

如何在Python 照片中为长时间内存网络量化数据(版权所有Mathias Appel)



教程概述


本教程分为4部分; 他们是:

  1. 缩放系列数据

  2. 缩放输入变量

  3. 缩放输出变量

  4. 缩放时的实际注意事项


在Python中缩放系列数据


您可能需要考虑的系列有两种缩放方式:归一化和标准化。

这些都可以使用scikit-learn库来实现。

归一化序列数据


归一化是从原始范围重新缩放数据,所以所有值都在0和1的范围内。

归一化要求您知道或能够准确地估计最小和最大可观察值。您可能可以从可用数据估计这些值。如果您的时间序列正在上升或下降,估计这些预期值可能很困难,并且归一化可能不是您的问题使用最好的方法。

一个值的归一化如下:
y = (x - min) / (max - min)

其中最小值和最大值与归一化的值x相关。

例如,对于数据集,我们可以将最小和最大可观察值的估计值设置为30和-10。我们可以对任何值进行归一化,如18.8,如下所示:
y = (x - min) / (max - min)
y = (18.8 - (-10)) / (30 - (-10))
y = 28.8 / 40
y = 0.72

您可以看到,如果提供的值超出最小值和最大值的范围,则结果值不会在0和1的范围内。您可以在进行预测之前检查这些观察结果,或者从数据集删除它们,或者将它们限制到预定义的最大值或最小值。

您可以使用scikit学习对象MinMaxScaler对数据集进行归一化。

MinMaxScaler和其他缩放技术的良好练习使用方法如下:

  • 使用可用的训练数据调整刻度。对于归一化,这意味着训练数据将用于估计最小和最大可观察值。这通过调用fit()函数来完成。

  • 将缩放应用于培训数据。这意味着您可以使用规范化的数据来训练您的模型。这通过调用transform()函数来完成。

  • 将缩放应用到未来的数据。这意味着您可以在将来准备要预测的新数据。


如果需要,转换可以反转。这对于将预测转换回原来的报表或绘图规模很有用。这可以通过调用inverse_transform()函数来完成。

下面是一个归一化10个量的设计序列的例子。

缩放器对象需要将数据提供为行和列的矩阵。加载的时间序列数据作为Pandas序列加载。
from pandas import Series
from sklearn.preprocessing import MinMaxScaler
# define contrived series
data = [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0]
series = Series(data)
print(series)
# prepare data for normalization
values = series.values
values = values.reshape((len(values), 1))
# train the normalization
scaler = MinMaxScaler(feature_range=(0, 1))
scaler = scaler.fit(values)
print('Min: %f, Max: %f' % (scaler.data_min_, scaler.data_max_))
# normalize the dataset and print
normalized = scaler.transform(values)
print(normalized)
# inverse transform and print
inversed = scaler.inverse_transform(normalized)
print(inversed)

运行这个示例打印序列,输出从序列中估计的最小值和最大值,打印相同的归一化序列,然后使用反向转换返回原来的值。

我们还可以看到数据集的最小值和最大值分别为10.0和100.0。
0     10.0
1 20.0
2 30.0
3 40.0
4 50.0
5 60.0
6 70.0
7 80.0
8 90.0
9 100.0

Min: 10.000000, Max: 100.000000

[[ 0. ]
[ 0.11111111]
[ 0.22222222]
[ 0.33333333]
[ 0.44444444]
[ 0.55555556]
[ 0.66666667]
[ 0.77777778]
[ 0.88888889]
[ 1. ]]

[[ 10.]
[ 20.]
[ 30.]
[ 40.]
[ 50.]
[ 60.]
[ 70.]
[ 80.]
[ 90.]
[ 100.]]

标准化序列数据


标准化数据集涉及重新计算值的分布,使观测值的平均值为0,标准偏差为1。

这可以被认为是减去平均值或居中的数据。

与归一化一样,标准化可能是有用的,甚至在某些机器学习算法中,当您的数据具有不同比例的输入值时也是如此。

标准化假设您的观察结果符合具有良好的平均值和标准偏差的高斯分布(钟形曲线)。如果不满足此期望,您仍然可以标准化您的时间序列数据,但是您可能无法获得可靠的结果。

标准化要求您知道或能够准确估计可观测值的平均值和标准偏差。您可能可以从您的培训数据估计这些值。

一个值的标准化如下:
y = (x - mean) / standard_deviation

平均值计算如下:
mean = sum(x) / count(x)

standard_deviation的计算公式如下:
standard_deviation = sqrt( sum( (x - mean)^2 ) / count(x))

我们可以估计平均值为10,标准偏差约为5.使用这些值,我们可以将第20.7的第一个值标准化如下:
y = (x - mean) / standard_deviation
y = (20.7 - 10) / 5
y = (10.7) / 5
y = 2.14

对于新数据,数据集的平均值和标准偏差的估计比最小值和最大值更稳健。

您可以使用Scikit学习对象StandardScaler对数据集进行标准化。
from pandas import Series
from sklearn.preprocessing import StandardScaler
from math import sqrt
# define contrived series
data = [1.0, 5.5, 9.0, 2.6, 8.8, 3.0, 4.1, 7.9, 6.3]
series = Series(data)
print(series)
# prepare data for normalization
values = series.values
values = values.reshape((len(values), 1))
# train the normalization
scaler = StandardScaler()
scaler = scaler.fit(values)
print('Mean: %f, StandardDeviation: %f' % (scaler.mean_, sqrt(scaler.var_)))
# normalize the dataset and print
standardized = scaler.transform(values)
print(standardized)
# inverse transform and print
inversed = scaler.inverse_transform(standardized)
print(inversed)

运行示例打印序列,打印从序列估计的平均值和标准偏差,打印标准值,然后将值以原始比例打印出来。

我们可以看出,估计的平均值和标准差分别为5.3和2.7。
0    1.0
1 5.5
2 9.0
3 2.6
4 8.8
5 3.0
6 4.1
7 7.9
8 6.3

Mean: 5.355556, StandardDeviation: 2.712568

[[-1.60569456]
[ 0.05325007]
[ 1.34354035]
[-1.01584758]
[ 1.26980948]
[-0.86838584]
[-0.46286604]
[ 0.93802055]
[ 0.34817357]]

[[ 1. ]
[ 5.5]
[ 9. ]
[ 2.6]
[ 8.8]
[ 3. ]
[ 4.1]
[ 7.9]
[ 6.3]]

缩放输入变量


输入变量是网络对输入或可见层进行预测的变量。

一个很好的经验法则是,输入变量应该是小的值,可能在0-1的范围内,或者是标准化的零均值和一个标准差。

输入变量是否需要缩放取决于您的问题和每个变量的具体情况。我们来看一些例子。

分类输入


您可能有一系列分类输入,如字母或状态。

通常,分类输入是第一个整数编码,然后是独热编码的。也就是说,将唯一的整数值分配给每个不同的可能输入,然后使用1和0的二进制向量来表示每个整数值。

根据定义,独热编码将确保每个输入都是一个小的实数,在这种情况下为0.0或1.0。

实值输入


您可以将一个序列的数量作为输入,如价格或温度。

如果数量分布正常,则应标准化,否则系列应归一化。这适用于数值范围很大(10s 100s等)或很小(0.01,0.0001)。

如果数值很小(接近0-1)且分布有限(例如,接近1的标准偏差),那么也许你可以不缩放这个序列。

其他输入


问题可能很复杂,如何最大限度地扩展输入数据可能不清楚。

如果有疑问,请对输入序列进行归一化。如果您拥有资源,可以使用原始数据,标准化数据进行建模,并进行归一化,并查看是否有有益的差异。
如果输入变量是线性组合的,如在MLP[多层感知器]中,那么就很少有必要对输入进行标准化,至少理论上是如此。...然而,原因有多种实用的标准化的输入可以使训练速度和减少的几率被困在当地的最适条件。

- 我应该归一化、标准化还是重新调整数据?神经网络常见问题

缩放输出变量


输出变量是由网络预测的变量。

您必须确保输出变量的比例与网络输出层上的激活函数(传递函数)的比例相匹配。
如果您的输出激活功能的范围为[0,1],则显然必须确保目标值在该范围内。但是通常最好选择适合于目标分配的输出激活功能,强制您的数据符合输出激活功能。

- 我应该归一化、标准化还是重新调整数据?神经网络常见问题

以下启发式应涵盖大多数序列预测问题:

二进制分类问题


如果您的问题是二进制分类问题,则输出将为0和1类。这最好用输出层上的sigmoid激活函数建模。输出值将是0到1之间的实数值,可以被捕捉到清晰的值。

多类分类问题


如果您的问题是多类分类问题,则输出将为0到1之间的二进制类值的向量,每个类值一个输出。这最好用输出层上的softmax激活功能建模。同样,输出值将是0到1之间的实数值,可以捕捉到清晰的值。

回归问题


如果你的问题是一个回归问题,那么输出将是一个实值。这是最好用线性激活功能建模的。如果值的分布是正常的,那么可以标准化输出变量。否则,输出变量可以被归一化。

其他问题


还有许多其他激活功能可以在输出层上使用,您的问题的具体细节可能会增加混乱。

经验法则确保网络输出与数据的比例匹配。

缩放时的实际注意事项


缩放序列数据时有一些实际的考虑。

  • 估计系数。您可以从训练数据中估计系数(归一化的最小值和最大值或标准化的平均值和标准偏差)。检查这些大致的估计值,并使用领域知识或求助领域专家帮助改进这些估计,以便他们将来对所有的数据有用。

  • 保存系数。您将需要以完全相同的方式将未来的新数据归一化,就像用于培训模型的数据一样。保存用于文件的系数,稍后在需要在进行预测或扩展新数据时加载它们。

  • 数据分析使用数据分析来帮助您更好地了解您的数据。例如,简单的直方图可以帮助您快速获得数量分布的看法,看看标准化是否有意义。

  • 缩放每个系列。如果您的问题具有多个级数,请将其视为单独的变量,然后分别进行扩展。

  • 在适当的时间缩放。在正确的时间应用任何缩放变换很重要。例如,如果您有一系列不稳定的数量,则可能会在首次使数据静止后进行缩放。在将此系列转换成一个受监督的学习问题后,按不同的方式处理,这是不恰当的。

  • 如果对缩放有疑问。您可能需要重新调整输入和输出变量的大小。如果有疑问,至少规范您的数据。

欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消