在训练神经网络(例如长短期记忆循环神经网络)时,您序列预测问题的输入数据可能需要进行缩放。
当网络在具有值范围(例如,10到100的数值)的未缩放数据上进行拟合时,大输入可能会减慢网络的学习和收敛速度,在某些情况下还会阻止网络有效学习您的模型。
在本教程中,您将了解如何标准化和规范化您的序列预测数据,以及如何决定为您的输入和输出变量选择哪种方法。
完成本教程后,您将了解:
- 如何在Python中标准化和规范化序列数据。
- 如何为输入和输出变量选择合适的缩放方法。
- 缩放序列数据的实际注意事项。
立即开始您的项目,阅读我的新书《时间序列预测的深度学习》,其中包含分步教程和所有示例的Python源代码文件。
让我们开始吧。

如何在 Python 中缩放用于长短期记忆网络的数据
照片由Mathias Appel拍摄,保留部分权利。
教程概述
本教程分为4个部分,它们是:
- 缩放序列数据
- 缩放输入变量
- 缩放输出变量
- 缩放时的实际注意事项
在Python中缩放序列数据
您可以考虑对序列进行两种类型的缩放:标准化和规范化。
这些都可以使用scikit-learn库来实现。
规范化序列数据
归一化是对数据从原始范围进行重新缩放,使所有值都在0到1的范围内。
规范化要求您知道或能够准确估计可观测的最小值和最大值。您可能能够从可用数据中估算这些值。如果您的时间序列呈上升或下降趋势,估算这些预期值可能会很困难,规范化可能不是解决您问题的最佳方法。
值归一化如下
1 |
y = (x - min) / (max - min) |
其中最小值和最大值指的是被规范化的值x。
例如,对于一个数据集,我们可以猜测最小和最大可观测值为 30 和 -10。然后我们可以归一化任何值,如 18.8,如下所示
1 2 3 4 |
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和其他缩放技术的良好实践用法如下:
- 使用可用的训练数据拟合缩放器。对于规范化,这意味着将使用训练数据来估算可观测的最小值和最大值。这是通过调用fit()函数完成的。
- 将缩放应用于训练数据。这意味着您可以使用规范化后的数据来训练模型。这是通过调用transform()函数完成的。
- **将尺度应用于未来的数据**。这意味着您可以在未来准备新数据,您想对其进行预测。
如果需要,可以反转变换。这对于将预测值转换回原始缩放比例以便报告或绘图非常有用。可以通过调用inverse_transform()函数完成。
下面是一个规范化包含10个值的自制序列的示例。
缩放器对象需要将数据提供为行和列的矩阵。加载的时间序列数据以Pandas Series的形式加载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from pandas import Series from sklearn.preprocessing import MinMaxScaler # 定义自制序列 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) # 准备数据以进行规范化 values = series.values values = values.reshape((len(values), 1)) # 训练规范化 scaler = MinMaxScaler(feature_range=(0, 1)) scaler = scaler.fit(values) print('Min: %f, Max: %f' % (scaler.data_min_, scaler.data_max_)) # 规范化数据集并打印 normalized = scaler.transform(values) print(normalized) # 反向变换并打印 inversed = scaler.inverse_transform(normalized) print(inversed) |
运行该示例将打印序列,打印从序列估算出的最小值和最大值,打印相同的规范化序列,然后使用反向变换打印回原始缩放比例的值。
我们还可以看到数据集的最小值和最大值分别为10.0和100.0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
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.]] |
时间序列深度学习需要帮助吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
标准化序列数据
标准化数据集涉及重新缩放值的分布,使观测值的平均值为 0,标准差为 1。
这可以看作是减去平均值或居中数据。
与归一化一样,当您的数据具有不同尺度的输入值时,标准化在某些机器学习算法中可能很有用,甚至必不可少。
标准化假设您的观测值符合高斯分布(钟形曲线),具有良好的均值和标准差。如果此期望未得到满足,您仍然可以标准化时间序列数据,但结果可能不可靠。
标准化要求您知道或能够准确估计观测值的均值和标准差。您可以通过训练数据估计这些值。
值标准化如下
1 |
y = (x - mean) / standard_deviation |
其中均值计算为
1 |
mean = sum(x) / count(x) |
标准差计算为
1 |
standard_deviation = sqrt( sum( (x - mean)^2 ) / count(x)) |
我们可以估算均值为10,标准差约为5。使用这些值,我们可以如下标准化第一个值20.7:
1 2 3 4 |
y = (x - mean) / standard_deviation y = (20.7 - 10) / 5 y = (10.7) / 5 y = 2.14 |
数据集的均值和标准差估计比最小值和最大值对新数据更稳健。
您可以使用 scikit-learn 对象 StandardScaler 来标准化您的数据集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
from pandas import Series from sklearn.preprocessing import StandardScaler from math import sqrt # 定义自制序列 data = [1.0, 5.5, 9.0, 2.6, 8.8, 3.0, 4.1, 7.9, 6.3] series = Series(data) print(series) # 准备数据以进行规范化 values = series.values values = values.reshape((len(values), 1)) # 训练规范化 scaler = StandardScaler() scaler = scaler.fit(values) print('Mean: %f, StandardDeviation: %f' % (scaler.mean_, sqrt(scaler.var_))) # 规范化数据集并打印 standardized = scaler.transform(values) print(standardized) # 反向变换并打印 inversed = scaler.inverse_transform(standardized) print(inversed) |
运行该示例将打印序列,打印从序列估算出的均值和标准差,打印标准化后的值,然后打印回原始缩放比例的值。
我们可以看到估算的均值和标准差分别约为5.3和2.7。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
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的范围内,或者标准化为零均值和单位标准差。
输入变量是否需要缩放取决于您问题的具体情况以及每个变量的具体情况。让我们看一些例子。
分类输入
您可能有一系列分类输入,例如字母或状态。
通常,分类输入首先被整数编码,然后被独热编码。也就是说,为每个不同的可能输入分配一个唯一的整数值,然后使用由一和零组成的二进制向量来表示每个整数值。
根据定义,独热编码将确保每个输入都是一个小的实数值,在本例中为0.0或1.0。
实值输入
您可能有一系列数量作为输入,例如价格或温度。
如果数量的分布是正态的,那么应该对其进行标准化,否则序列应该进行规范化。如果数量值的范围很大(10s,100s等)或很小(0.01,0.0001),则此方法适用。
如果数量值很小(接近0-1),并且分布受限(例如,标准差接近1),那么您可能可以跳过序列的缩放。
其他输入
问题可能很复杂,而且很难清楚如何最好地缩放输入数据。
如果您不确定,请规范化输入序列。如果您有资源,可以尝试使用原始数据、标准化数据和规范化数据进行建模,看看是否有益处的差异。
如果输入变量是线性组合的,就像在MLP(多层感知机)中一样,那么很少严格需要标准化输入,至少在理论上如此。……但是,在实践中有各种原因可以使标准化输入能够加快训练速度并减少陷入局部最优的机会。
— 我应该规范化/标准化/重新缩放数据吗?神经网络FAQ
缩放输出变量
输出变量是网络预测的变量。
您必须确保您的输出变量的缩放比例与网络输出层上的激活函数(传递函数)的缩放比例相匹配。
如果您的输出激活函数范围是[0,1],那么显然您必须确保目标值在该范围内。但通常最好选择适合目标分布的输出激活函数,而不是强迫数据符合输出激活函数。
— 我应该规范化/标准化/重新缩放数据吗?神经网络FAQ
以下启发式方法应涵盖大多数序列预测问题:
二分类问题
如果您的任务是二元分类问题,那么输出将是类别值0和1。这最好通过输出层上的sigmoid激活函数来建模。输出值将是介于0和1之间的实值,可以将其截断为离散值。
多类分类问题
如果您的任务是多类分类问题,那么输出将是一个介于0和1之间的二进制类别值的向量,每个类别值有一个输出。这最好通过输出层上的softmax激活函数来建模。同样,输出值将是介于0和1之间的实值,可以将其截断为离散值。
回归问题
如果您的任务是回归问题,那么输出将是一个实值。这最好通过线性激活函数来建模。如果值的分布是正态的,那么您可以标准化输出变量。否则,输出变量可以进行规范化。
其他问题
输出层可能使用许多其他激活函数,并且您问题的具体情况可能会增加混乱。
经验法则是确保网络输出与数据的缩放比例相匹配。
缩放时的实际注意事项
在缩放序列数据时,有一些实际注意事项。
- 估算系数。您可以从训练数据中估算系数(规范化的最小值和最大值,或标准化的均值和标准差)。检查这些初步估算值,并利用领域知识或领域专家来帮助改进这些估算值,以便它们在未来对所有数据都具有有用的准确性。
- 保存系数。将来您需要以与用于训练模型的数据完全相同的方式来规范化新数据。将用于此的系数保存到文件中,并在需要缩放新数据以进行预测时加载它们。
- 数据分析。使用数据分析来帮助您更好地了解您的数据。例如,简单的直方图可以帮助您快速了解数量的分布,以查看标准化是否合理。
- 分别缩放每个序列。如果您的项目有多个序列,请将每个序列视为一个单独的变量,并分别缩放它们。
- 在正确的时间缩放。在正确的时间应用任何缩放变换很重要。例如,如果您有一个非平稳的数量序列,在首先使数据平稳后进行缩放可能是合适的。在将序列转换为监督学习问题后对其进行缩放是不合适的,因为每列将被以不同的方式处理,这是不正确的。
- 不确定时进行缩放。您可能需要重新缩放您的输入和输出变量。如果您不确定,至少要规范化您的数据。
进一步阅读
本节列出了一些其他可供参考的资源。
- 我应该规范化/标准化/重新缩放数据吗?神经网络FAQ
- MinMaxScaler scikit-learn API文档
- StandardScaler scikit-learn API文档
- 如何在Python中从头开始缩放机器学习数据
- 如何在 Python 中对时间序列数据进行归一化和标准化
- 如何使用Scikit-Learn准备Python中的机器学习数据
总结
在本教程中,您了解了在处理长短期记忆循环神经网络时如何缩放序列预测数据。
具体来说,你学到了:
- 如何在Python中标准化和规范化序列数据。
- 如何为输入和输出变量选择合适的缩放方法。
- 缩放序列数据的实际注意事项。
您对缩放序列预测数据有任何疑问吗?
在评论中提出您的问题,我会尽力回答。
感谢Jason的帖子,这是一篇关于如何缩放数据的简洁明了的指南。我想分享Experfy上一个关于机器学习(尤其是监督学习)的优秀课程,我发现它在理解所有这些方面非常有帮助。
这是链接!https://www.experfy.com/training/courses/machine-learning-foundations-supervised-learning
很高兴听到这个消息。
尊敬的Jason博士,
使用缩放数据进行预测时,是否必须使用
或者
谢谢你
预测之后,是的,为了使用它或获得正确的比例的误差得分,以便对模型进行苹果对苹果的比较。
嗨Jason,再次感谢您分享您的绝妙想法!我使用seq2seq应用处理文本输入,文本的长度可变,词汇量很大(数千条)。显然,在这种情况下,填充和独热编码是必要的。如果有人使用keras.tokenizer.texts_to_sequences(...)然后是keras.tokenizer.sequences_to_matrix(sequence, mode='binary'),他们会得到一个无法直接放入LSTM的2D张量。
例如
seq_test = tokenizer.texts_to_sequences(input_text_sequence)
seq_test[:4]
Out[16]: [[1, 2, 110], [23, 5, 150], [1, 3, 17], [8, 2, 218, 332]]
X_test = tokenizer.sequences_to_matrix(seq_test, mode='binary')
X_test[:4,:]
Out[18]
array([[ 0., 1., 1., …, 0., 0., 0.],
[ 0., 0., 0., …, 0., 0., 0.],
[ 0., 1., 0., …, 0., 0., 0.],
[ 0., 0., 1., …, 0., 0., 0.]])
如果有人尝试将填充序列传递给“sequences_to_matrix”,则会生成一条错误消息:
File “C:….\keras\preprocessing\text.py”, line 262, in sequences_to_matrix
if not seq
ValueError:包含多个元素的数组的真值不明确。请使用 a.any() 或 a.all()
这是说,为了以编码-解码的方式使用LSTM,必须手动进行“独热编码”吗???
另一方面,如果我不进行独热编码,并使用与https://machinelearning.org.cn/sequence-classification-lstm-recurrent-neural-networks-python-keras/类似的網絡架构,我会获得非常好的收敛性(>99%)。
问题出现在预测中,因为最后一个Dense层具有activation='sigmoid',它生成介于0和1之间的值。如何在不进行独热编码的input_sequence的情况下,得到(Out[19]: [[1, 2, 110], [23, 5, 150], [1, 3, 17], [8, 2, 218]])形式的预测???
最后一个问题。如果对序列进行独热编码,那么嵌入层和卷积层就没有意义了,对吗???
LSTM输入是3D的[样本,时间步长,特征]。每个样本将是您输入的一个序列。时间步长是单词或字符,特征是独热编码后的值。
您好,感谢您的教程!从中学到了很多!
关于缩放(或规范化)的一个问题:我们如何确保不同数据集之间的缩放结果保持不变?例如
– 步骤1:我们使用一些数据集来训练模型(使用缩放数据),然后保存训练好的模型以备将来使用。
– 步骤2:我们导入在步骤1中创建的模型,并使用它来预测一个预测数据集。
但是:预测数据集也必须进行缩放。更重要的是,它必须使用与步骤1中用于缩放模型相同的缩放参数进行缩放。我是否错了?
或者我们是否必须保存缩放对象,然后在步骤2中再次导入以用于缩放预测数据集?
正确。
这意味着您必须仔细估算缩放参数并将其保存以供将来使用。
很棒的文章Jason!非常感谢您的辛勤工作。
我面临着与Liviu类似的问题。
如何缩放初始训练数据中的特征和目标,假设将来会有更多数据可用,并用于增量训练模型。
如果初始可用数据使用数据中的最大值从0缩放到1,那么新的最大值将改变模型训练的整个缩放比例,因此会歪曲结果。
我所确定的唯一确定的是,由于增长,目标的最大值将在将来更高,但最终幅度完全无法评估。
您是否有任何建议如何解决这个问题,而不必重新缩放整个数据集并使用新的最大值,以及分别在整个数据集上重新训练模型?
提前致谢并致敬,
Lukas
您可以使用领域知识来估算您预期会看到的极端最小/最大值。
或者使用相同的方法,估算均值/标准差并标准化数据,这可能对随时间变化的较大缩放比例变化更具鲁棒性。
感谢您的辛勤工作
很高兴您觉得这篇文章有用,Emmanuel。
感谢您的工作。如果我想缩放图像像素的值,该怎么做?
请看这篇文章
https://machinelearning.org.cn/image-augmentation-deep-learning-keras/
嗨Jason,非常感谢您的工作!
我想问您,与典型的MLP神经网络相比,在LSTM中缩放数据是否有重大动机?
我曾使用MLP,即使不缩放输入数据也能获得良好的结果,而使用LSTM时却给了我非常糟糕的结果(总是恒定的输出值)。但是现在,通过规范化LSTM的输入和输出,我甚至获得了比MLP更好的结果。
所以我想知道,为什么LSTM中的规范化比MLP更重要,是否有理论上的动机?
再次感谢,
Giani
这只是一个经验上的证明,就像大多数应用机器学习一样。
是的,我发现与不缩放相比,将数据重新缩放到0-1之间能获得更好的结果。使数据平稳化也有帮助。
我最好的建议是进行测试和观察。
嗨Jason,我有一个数据集中,其中一些特征的范围非常小,例如0.1 – 0.001,而另一些特征的范围很大,例如10 – 1000,我应该规范化这些特征吗?
我推荐它,看看治疗如何影响模型技能。
嗨,Jason,
首先,非常感谢您博客上提供的这些丰富信息,它在我设置一个工作的循环神经网络以完成我的一个宠物项目时给了我很大的帮助。
几乎所有内容都在工作,但在输入和输出的正确缩放方面我遇到了一些问题。我的时间序列是一些历史金融数据,当我缩放这个序列的每个窗口(输入和输出一起)时,它学习得非常好,并且预测(输入和输出被查询、缩放,然后只有输入被馈送到网络)在从未见过的数据上也能准确地执行。
在实际条件下,每个窗口将没有输出序列部分,所以我只缩放输入。由于这些范围与一起缩放每个窗口的输入和输出时的信号有所不同,因此实际预测效果非常差。
MinMax缩放输入,然后用输入序列的最小值和最大值来MinMax缩放输出(缩放后的输出有时范围会在2到-1之间,而输入总是在0和1之间)会导致非常长的学习时间,预测效果也很差。
我做错了什么吗?您将如何处理这个问题?
提前非常感谢,再次感谢您在这篇博客上投入的时间和精力。
祝好,
Fabian
也许可以手动缩放,并选择您认为可以覆盖所有时间所有可能观察值的最小值和最大值。
我尝试过这种方法,但是算法在那里确实没有收敛。这是一个简单的由200个观察点和48个预测点组成的序列,使用LSTM多单元、t2损失和rmsprop。可能会切换到卷积RNN分类器,在48个时间步长目标中进行一次命中编码的百分比变化,因为这样可以让我将观察序列缩放到-1,1。
我还是有点困惑,信号方差大的回归问题有那么大吗?
LSTM并不真正适合直接回归,它适合序列预测问题。
https://machinelearning.org.cn/sequence-prediction/
我尝试预测一个240时间步长的序列,然后预测一个48时间步长的序列。
如果我对整个窗口(即288个时间步长)进行缩放,我会得到惊人的训练和验证结果。但由于我不能这样做,因为在推理时我只能访问输入,所以在训练和验证期间我也只能缩放输入。结果预测充其量也很差。
也许您可以使用领域知识来估计所有时间所有可能观测值的最小值/最大值?
嗨,Jason,
快速提问,为什么您将数据缩放到(0, 1)范围,而您链接到的文章明确建议缩放到(-1, 1),这将给出零均值?
我发现缩放到[0,1]可以得到更有技能的LSTM模型。
信号,金融性质的,可能会非常不稳定。我最终采用的方法,并且似乎能给出非常好的结果,是使用特征范围为-0.8到0.8来拟合观察期的MinMax缩放器。如果经过观察期拟合缩放器转换后的输出超出-1或1,我会将其限制在那个范围内。在预测时,我将这些异常值替换为null,因此大多数预测都在特征范围内长达48个时间步长,有些可能会更短。这似乎运作得相当好,并产生了可靠和可操作的见解。再次感谢您的帮助,非常感谢。
嗨,Jason,
这是一篇很棒的文章。我正在尝试Keras,并使用一些我手动生成和标记的训练数据。训练数据是序列[0, 1, 2, 3]的排列。输出是1或0。我构建了一个使用Dense层的顺序模型。我发现的是,如果我将训练数据重新缩放到例如[0, 0.25, 0.5, 0.75],准确率会更低。您对此有什么想法吗?
模型超参数可能需要针对新的缩放输入进行调整?
嗨,Jason,
我正在学习如何使用LSTM来预测时间序列(如股票价格预测)。但我有一个关于数据缩放的问题。
对于训练数据集,考虑到最小最大缩放器,我们已经知道了最小值和最大值。但是当我们对验证数据或测试数据应用模型时,我如何缩放数据?如果我们以相同的方式缩放它们,我认为最小和最大值包含未来信息。
我是否误解了什么?
谢谢!
如果您可以估计该领域的最小值/最大值。然后使用该领域知识缩放数据。
你好,
谢谢你的帖子。我仍然不明白如何处理缩放和掩蔽。这两个操作显然不能交换:如果我先填充我的序列,比如说
[[ 1, 2, 3, 4 ]
[ 1, 2, 3, 0 ]
[ 1, 2, 0, 0 ]
[ 1, 2, 3, 0 ]]
然后重新缩放,重新缩放的数组在填充条目对应的位置不再有0。我如何在Keras中处理这个问题?
祝好,
Riccardo
也许先缩放,然后在建模前的最后一步进行填充。
我对LSTM单元使用sigmoid和tanh感到困惑,但为什么我们使用standardscaling呢?当我使用standard scaling,并且值范围是-0.5到11时,sigmoid和tanh将无法工作,还是我错了?我如何为线性层选择激活函数?感谢ML大师!
通常最好先标准化再归一化原始数据。
嗨,Jason,
感谢有用的帖子。不过我有一个小小的疑问。
假设我们有一个输入时间序列,我们在其上训练模型,比如说最后七个值是[2, 3, 4, 5, 6, 7, 8]。时间序列每小时都在收集新数据。当我们应用归一化时,我们的数据将由0到1之间的值组成,其中0是2(最小值)的“替代”,1是8(最大值)的“替代”。我们训练了LSTM模型,并且它在测试集(从上述数组中提取)上工作得很好。问题开始于当我们想要基于出现的几个新数字来预测未来值时。假设现在我们的时间序列看起来像[2, 3, 4, 5, 6, 7, 8, 10, 13, 17]。如果我们用旧的缩放器对其进行归一化,最后几个数字将大于一。如何处理这种情况?
提前感谢!😉
在这种情况下,最好使用领域专业知识来估计该领域的价值范围,并使用它们来缩放数据。
你好:)
感谢您的精彩教程。我还有一个关于处理训练数据、测试数据和用于实际预测的新数据的问题。
假设我有一个数据集X,它只是一个1000个时间点、5个特征的序列。
我想要一个模型,它接收10个这样的时间点序列,并预测第11个(为了简单起见,进行二元分类)是1还是0。
X会变成一个形状为(100,10,5)的数组。因为我们有100个序列,每个序列有10个时间步长,还有5个特征。
现在我会将X分成训练数据和测试数据
train_x = X[:80]
test_x = X[80:]
我该如何进行归一化?
我们先看两种选择。第一种是 x = (x-mean(x))/std(x),第二种是 y = (x – min) / (max – min)
对于第一种选择,我通常会将train_x的每个特征进行归一化。
这意味着我将train_x中一个特征的所有值都取出,并相对于它们自身进行归一化。我对每个特征都这样做了。然后测试集也采用了这种方法。
这是正确的方法吗?因为我相信在RNN中,它应该与常规神经网络的归一化方式不同。
我应该如何处理我不想用于训练的全新数据?比如我有一个新序列,想在它上面运行我的模型。如何在这里进行归一化?
谢谢!
Robin
根据训练数据或领域知识计算最小值/最大值,然后将归一化应用于所有样本、训练、测试以及未来新数据。
您是指,计算每个特征的最小值/最大值(基于训练数据或领域知识),这样您就为每个特征得到一个标量?也就是说,我有13个特征,我会为每个特征计算最小值/最大值,创建一个标量,然后将相应的标量应用于其对应的特征?
我有一个与Robin非常相似的问题。
嗨Max…以下内容可能对您感兴趣
https://machinelearning.org.cn/standardscaler-and-minmaxscaler-transforms-in-python/
我的输入值是从0到7。我真的需要重新缩放吗?
对于神经网络,最好将值重新缩放到0-1范围。
感谢另一篇精彩的文章。
为什么不是“缩小”而是“归一化”?
x ... ... ... ... y
如果我们数组中包含负值 [5, -7, -3, 6, 7, 9, 10]
缩小后 .......................... [..-0.7 ........................ 1]
如果我归一化 ............................. [.....0 ........................ 1]
在缩小中,我保留了-7的权重(为-0.7),使我的Fx向西/负方向拉动
在归一化中,-7变为0,10变为1……。
-7将在我的方程式中没有权重,-0.7x vs 0.x……同时10y将是1.y,将所有东西都拉向东边
归一化是指将数据重新缩放到[0, 1]的范围。
抱歉,我没跟上。或许您可以详细说明一下?
Jason,
我刚浏览了这篇文章。看起来您没有解释为什么数据缩放很重要。我一直在使用LSTM来建模股票价格。输入序列来自不同的股票。因为股票的尺度不同(有些在100到200之间,有些在1到10之间)。当我使用原始价格作为LSTM的输入时,我得到了非常糟糕的预测。但是通过简单地对每只股票应用归一化,LSTM模型的性能会立即提升。我想知道您对此是否有好的解释。
谢谢,
Daniel
是的,我在本教程中详细解释了数据缩放的必要性。
https://machinelearning.org.cn/how-to-improve-neural-network-stability-and-modeling-performance-with-data-scaling/
你好,你如何缩放一个权重矩阵,它是一个上三角矩阵或下三角矩阵?
也许这会有帮助。
https://machinelearning.org.cn/introduction-to-types-of-matrices-in-linear-algebra/
你好,
一个与“领域知识”和估计最小最大值相关的问题:我能否将估计的最大值和最小值设置为像max_value=(current_max_value+30000)和min_value=(current_min_value-30000)这样,直到我找到一个有更多领域知识的人?
也许吧,如果30K的界限是合理的。如果太大,它会压制掉您数据中的任何信号。
嘿,哥们,
您的文章很有帮助。我有一个疑问,需要一些指导。
我的LSTM模型有3个变量需要缩放。现在,我是否为所有变量使用相同的缩放器对象,还是为每个变量创建单独的缩放器对象?
感谢您在文章中付出的努力。
我在这里给出了一个例子
https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/
我如何为我的CNN模型缩放数据?我正在使用Keras,我的输入是四维的[a,b,c,d]。a =训练样本数,[b,c] =图像尺寸,d =输入特征数。我认为MinMaxScalar只适用于二维矩阵。
谢谢。此致,
Suraj Pawar
也许这会有帮助。
https://machinelearning.org.cn/how-to-develop-convolutional-neural-network-models-for-time-series-forecasting/
嗨,Jason,
我遇到的结果问题是,一些预测值是负数,这在实际条件下没有意义,而且输出数据也有一定的正范围。我有训练数据和保留数据(没有提供目标列)。第一次,我怀疑这是因为保留数据集中输入范围超出了训练数据集。但是,我遵循了您的建议,使用领域知识来归一化以获得最小值和最大值。不幸的是,我仍然发现一些预测值是负数,并且我检查了它们的输入是好的并且在训练输入范围内。下面是RNN架构
model = Sequential ()
model.add (LSTM ( n_neurons , activation = ‘relu’, inner_activation = ‘hard_sigmoid’ , input_shape =(x_train.shape[1], 4) ))
model.add(Dropout(dropout))
model.add (Dense (output_dim =1, activation = ‘linear’))
model.compile (loss =”mean_squared_error” , optimizer = “adam”)
我尝试了多元自适应样条回归,也得到了一些负预测值。
请提供建议
谢谢你
恭喜您取得进展。
也许你可以后处理预测?
也许你可以尝试其他建模算法并比较结果?
也许你可以探索其他数据准备方案,看看它们是否会产生影响?
告诉我进展如何。
嗨 Jason,
选择的缩放器特征范围(-1,1或0,1)是否会对激活函数的选择施加限制(如果数据缩放到-1:1,那么我们就不能使用sigmoid,只能使用tanh,反之亦然)?
谢谢。Igor。
都不是,StandardScaler将标准化数据,这意味着它的均值为0,标准差为1。
StandardScaler适用于tanh,MinMaxScaler(归一化)适用于sigmoid。总的来说。比较缩放与不缩放,并加入relu。
嗨,Jason,
我有一个包含30多个特征的时间序列。假设我想对其中15个进行归一化/标准化。我能否为所有这15个特征使用同一个缩放器,还是我需要为每个特征单独的缩放器?
在这篇文章https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/中,您有4个不同的缩放器,但对于10个特征都应该进行归一化/标准化的场景呢?
非常感谢
如果每个序列是一列,那么缩放器将分别对每一列应用缩放。
或者您可以手动进行 - 或者您在代码中发现的任何最简单的方式。
你好,感谢您的资料。
我有一些关于使用LSTM NN的缩放或归一化的问题。我所做的就是这个
1.将数据分割为训练集和验证集。
2.使用MinMaxScaler(0,1),在训练数据集上进行fit_transform,然后在验证集上进行transform。
3.使用缩放器处理未来数据。
我遇到的问题是,当我输入的数值大于或小于缩放器边界时,我会得到奇怪的预测。例如,如果缩放后的输入是负数,预测值就是0,这是错误的。我该如何处理?
我使用的网络是这样的
model=Sequential()
model.add(LSTM(300, input_shape = (window,features), return_sequences=True))
model.add(Dropout(0.5))
model.add(LSTM(200, input_shape=(window,features), return_sequences=False))
model.add(Dropout(0.5))
model.add(Dense(100,kernel_initializer=’uniform’,activation=’relu’))
model.add(Dense(1,kernel_initializer=’uniform’,activation=’relu’))
model.compile(loss=’mse’,optimizer=’adam’)
- 我应该更改密集层的激活函数吗?
- LSTM层应该使用什么激活函数?
- 我应该进行实时缩放新传入的数据以防止这些情况吗?
提前感谢您!
也许可以尝试一系列模型配置,找出最适合您特定预测问题的模型。
感谢您的回复。您说的“模型系列”是什么意思?
不同的算法。
嗨,Jason,
您能告诉我如何为LSTM模型缩放/归一化多元时间序列,其中输入形状为(212,14,5)吗?
我感到很困扰,因为MinMaxScaler期望数组形状<=2,所以重塑数据如下
train.reshape(train.shape[0]*train.shape[1]*train.shape[2], train.shape[2]) 来拟合缩放器,然后将其重塑回(212,14,5)是否仍然有效?
您认为这会影响结果的有效性/可靠性吗?以及如何检查?
谢谢
分别缩放每个特征。
这可能有帮助
https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/
嗨,Jason,
感谢这篇文章,我觉得它非常有帮助。
我有一个小小的困惑:假设我标准化了输入数据并用它来训练我的模型。然后我标准化了测试数据进行验证。
我的问题是,我如何对预测数据应用逆变换。我是否使用与标准化测试数据相同的缩放器(用于逆变换)?
不客气。
是的,使用与最初用于变换相同的缩放器对象来反变换。更多信息请看这里。
https://machinelearning.org.cn/how-to-save-and-load-models-and-data-preparation-in-scikit-learn-for-later-use/
精彩的文章。我有一个快速的问题,您提到如果我们有多条序列,我们应该分别处理和标准化它们。所以,假设我的训练数据集中有7条序列,测试数据集中有3条序列。我将首先单独标准化这7条序列,现在我不清楚如何将变换应用于测试数据中的3条序列,因为我将有7个来自训练集的均值和7个标准差,而我不知道如何决定一个均值和标准差来标准化测试集中的3条序列。预先感谢您的帮助。
每条序列都是一个独立的变量,可以单独缩放,需要自己的系数(例如,最小值和最大值或均值和标准差)。
Jason,我的回归模型目标变量90%的时间是一个指定的数字,所以如果没有任何模型,只是每次都返回那个数字,预测的MSE会很低,但是当我使用几个LSTM和Dense层训练我的模型时,它甚至无法接近“无模型情况”的准确率。有没有一种方法可以改进我的模型在这些目标分布上的表现?某种数据转换或模型改进,我的意思是。我非常需要帮助。
先谢谢了
也许你可以使用级联模型,第一层是分类,判断是否是“相同的数字”,第二层是回归,用于“非相同”的情况并预测具体的数值。
你好Jason,一如既往的精彩帖子!
我有一个关于MinMaxScaler的问题。
当测试数据集的值低于训练数据集时,我们应该怎么做?是用所有数据集训练缩放器,而不是只用训练数据集?
我希望我的特征范围在0到1之间,但这种情况会导致负值,这对于LSTM神经网络来说是不推荐的。
预先感谢!
理想情况下,训练集应代表所有数据。
如果新数据超出了训练集的范围,可以将值强制设置为已知的最小值和最大值。
对于 LSTM,当输入数据是面板数据时,例如
客户 1,month_1 上的花费,month_1 上的奖金,month_2 上的花费,month_2 上的奖金,
客户 2,month_1 上的花费,month_1 上的奖金,month_2 上的花费,month_2 上的奖金,
客户 2,month_1 上的花费,month_1 上的奖金,month_2 上的花费,month_2 上的奖金,
这是 (3, 2*2) 形状的表格数据,不包括客户 ID 列,并且将以 (N, T ,D) 格式重塑为 (3,2,2) 输入 LSTM 模型。(3 行,2 个月,2 个特征)
在这种情况下,如何对特征进行归一化?
– 归一化是在特征级别进行的,与时间无关? – 例如,每个列 – normalise(spend_on_month_1)
– 还是在特征级别跨时间进行? – 例如,给定特征的所有列,跨时间 – normalise([spend_on_month_1, spend_on_month_2])
很想了解你的想法,谢谢!
感谢您的询问。
我很想帮忙,但我实在没有能力为您调试代码。
我很乐意提出一些建议
考虑将代码积极削减到最低要求。这将帮助您隔离问题并专注于它。
考虑将问题简化为一个或几个简单的例子。
考虑寻找其他可行的类似代码示例,并慢慢修改它们以满足您的需求。这可能会暴露您的失误。
考虑在 StackOverflow 上发布您的问题和代码。
(在此处纠正示例中的错字)
对于 LSTM,当输入数据是面板数据时,例如
客户 1,month_1 上的花费,month_1 上的奖金,month_2 上的花费,month_2 上的奖金,
客户 2,month_1 上的花费,month_1 上的奖金,month_2 上的花费,month_2 上的奖金,
客户 3,month_1 上的花费,month_1 上的奖金,month_2 上的花费,month_2 上的奖金,
这是 (3, 2*2) 形状的表格数据,不包括客户 ID 列,并且将以 (N, T ,D) 格式重塑为 (3,2,2) 输入 LSTM 模型。(3 行,2 个月,2 个特征)
在这种情况下,如何对特征进行归一化?
– 归一化是在特征级别进行的,与时间无关? – 例如,每个列 – normalise(spend_on_month_1)
– 还是在特征级别跨时间进行? – 例如,给定特征的所有列,跨时间 – normalise([spend_on_month_1, spend_on_month_2])
很想了解你的想法,谢谢!
你好 Keeed…你可能会对以下内容感兴趣
https://machinelearning.org.cn/standardscaler-and-minmaxscaler-transforms-in-python/