用于序列预测问题的数据可能需要在训练神经网络(如长短期记忆递归神经网络)时进行缩放。
当一个网络可以有效学习具有一定范围的未缩放数据(例如数量在10到100之间)时,大规模输入可能会减慢它的学习和融合速度,并且在某些情况下会阻止网络有效地学习。
在本教程中,你将了解如何对序列预测数据进行规范化和标准化,以及如何确定将哪些序列用于输入和输出。
完成本教程后,你将知道:
让我们开始吧。
图片来自Mathias Appel,并保留了相关权利。
本教程分为4个部分; 他们是:
你需要在归一化和标准化这两种方式中选一种,来进行数据序列的缩放。
这些都可以使用scikit-learn库来实现。
归一化是对数据的原始范围进行重新缩放,以使所有值都在0~1的范围内。
归一化要求你知道或能够准确估计最小和最大可观测值。你可以从你的可获取的数据中估计这些值。如果你的时间序列呈现上升趋势或下降趋势,那么估计这些预期值可能会很困难,并且归一化可能不是用于解决问题的最佳方法。
一个值被归一化如下:
y = (x - min) / (max - min)
其中最小值和最大值与归一化的值x有关。
例如,对于数据集,我们可以猜测max和min可观察值为30和-10。然后,我们可以将任何值(如18.8)归一化,如下所示:
y = (x - min) / (max - min)
y = (18.8 - (-10)) / (30 - (-10))
y = 28.8 / 40
y = 0.72
你可以看到,如果给定的x值超出了最小值和最大值的范围,则结果值将不在0和1的范围内。你可以在进行预测之前检查这些观察值,并删除他们从数据集或限制他们到预先定义的最大值或最小值。
你可以使用scikit-learn的对象MinMaxScaler来归一化数据集。
使用MinMaxScaler和其他缩放技术的最佳实践如下:
如果需要,转换是可逆的。这对于将预测转换回其原始比例以进行报告或绘图非常有用。这可以通过调用inverse_transform()函数来完成。
下面是一个归一化数量为10的人为序列的例子。
缩放对象需要将数据作为矩阵的行和列提供。加载的时间序列数据以Pandas序列的形式加载。
from pandas import Series
from sklearn.preprocessing import MinMaxScale
# 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的计算方法如下:
mean = sum(x) / count(x)
而标准差standard_deviation的计算方式如下:
standard_deviation = sqrt( sum( (x - mean)^2 ) / count(x))
我们可以假设平均值mean=10而标准差standard_deviation=5。使用这些值,我们可以将第一个值20.7标准化如下:
y = (x - mean) / standard_deviation
y = (20.7 - 10) / 5
y = (10.7) / 5
y = 2.14
数据集的平均值和标准偏差估计值对于新数据可能比最小值和最大值更稳健。
你可以使用scikit-learn对象StandardScaler来标准化数据集。
from pandas import Series
from sklearn.preprocessing import StandardScale
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来标准化。
输入变量是否需要缩放取决于要解决的问题和每个变量的具体情况。我们来看一些例子。
你可能有一系列分类输入,例如字母或状态。
通常,分类输入是首先要整数编码,然后进行独热编码。也就是说,一个唯一的整数值被分配给每个不同的可能的输入,然后使用1和0的二进制向量来表示每个整数值。
根据定义,一个独热编码将确保每个输入是一个较小的实际值,例如0.0或1.0。
你可能有一系列数值作为输入,如价格或温度。
如果数量的分布是正常的,那么就应该标准化,否则应该归一化。如果数值的范围很大(10s 100s等)或很小(0.01,0.0001),则适合使用归一化。
如果数量值很小(接近0~1)并且分布是有限的(例如标准偏差接近1),那么也许你无需进行序列的缩放。
问题可能会很复杂,也很难弄清如何才能最好地缩放输入数据。
如果陷入了困境,尝试将输入序列归一化。如果你有资源,就尝试用原始数据或标准化数据分别建模,看看哪一种更好。
如果输入变量是线性组合的,就像在一个MLP [多层感知器]中一样,那么,至少在理论上,很少需要去严格地标准化输入。然而,有多种实际的原因使标准化输入可以加快训练的速度,并减少陷入局部最优的可能性。
- 我应该归一化/标准化/重新缩放数据吗?神经网络常见问题
输出变量是由神经网络预测得到的。
你必须确保输出变量的比例与神经网络输出层上的激励函数(传递函数)的比例相匹配。
如果你的输出激活函数的范围是[0,1],那么显然你必须确保目标值在该范围内。但是选择适合于目标分布的输出激励函数通常比强制数据符合输出激励函数要好。
- 我应该归一化/标准化/重新缩放数据吗?神经网络常见问题
以下的启发式问题,应该能涵盖大部分序列预测问题:
如果你的问题是二元分类问题,那么输出将会是0和1,你最好在神经网络输出层上使用S形激励函数进行建模。输出值将是0到1之间的实际值,并且可以得到准确的值。
如果你的问题是一个多类分类问题,那么输出将是0到1之间的二进制值的向量,每个类值有一个输出。在输出层上最好使用softmax激励函数。此外,输出值将是0到1之间的实际值,可以得到准确的值。
如果你的问题是一个回归问题,那么输出将是一个实际值。这时最好使用线性激励函数的模型。如果该值的分布是正常的,那么可以标准化输出变量。否则,输出变量可以被归一化。
还有许多其他的激励函数可以用在输出层上,你的问题的细节可能会更加混乱。
经验法则可以确保网络输出符合你的数据的缩放比例。
缩放数据序列时的一些实际的考虑。
本节列出了一些额外的资源,你不妨在缩放使参考一下。
在本教程中,你了解了如何在使用Long Short Term Memory递归神经网络使缩放预测数据序列。
具体来说,你了解到: