第八章 使用时序数据
预测神经网络是如何工作
使用Encog时序数据集
尝试预测太阳黑子
使用Encog市场数据集
尝试预测股票市场
预测是神经网络的另一种常用功能。预测神经网络将尝试根据当前值和过去值预测未来的值。这种神经网络被称为时序神经网络,因为它们随着时间的推移而运作。本章将介绍时序神经网络和Encog为它们提供的支持类。
在这一章中,你将看到Encog时序神经网络的应用。首先,我们将看看如何使用Encog预测太阳黑子。太阳黑子的可预测性很强,神经网络应该能够通过分析过去的数据来学习未来的模式。接下来,我们将研究一个简单的应用神经网络进行股票市场预测的例子。
在我们看这两个例子之前,我们必须了解时序神经网络是如何工作的。时序神经网络通常是前馈网络或简单递归网络进行恰当的构造,迄今为止所示的前馈神经网络可以通过分配一定的输入和输出神经元来构造时序神经网络。
8.1预测神经网络如何工作
预测神经网络使用其输入接受当前数据的信息,并利用其输出预测未来数据。它使用两个窗口,一个未来的窗口和一个过去的窗口。两个窗口必须有一个窗口大小,就是预测或需要预测的数据量。要查看操作中的两个窗口,请考虑以下数据。
考虑一个过去的窗口大小为五和未来两个窗口大小的时序神经网络。这个神经网络有五个输入神经元和两个输出神经元。我们将在这些窗口中打乱上述数据以生成训练数据。下面的数据显示了这样一个训练数据的元素。
当然,上面的数据需要在某种程度上进行规范化,才能将它送入神经网络。上面的插图简单地显示了输入和输出神经元是如何映射到实际数据的。为了获得追加数据,窗口要向前挪。训练数据的下一个内容如下。
当生成更多的训练数据时,您将继续向前滑动过去和将来的窗口。在这个格式准备数据上Encog包含专门的类。只需指定过去(输入)窗口和未来(输出)窗口的大小。这些专门的类将在下一节中进行讨论。8.2使用Encog时序数据集
Encog时序数据集位于以下的包里:
Encog时序数据集由四个类组成:
TemporalDataDescription类描述了一个单元的要么是用于预测或输出的数据。如果处理时态数据有错误,抛出TemporalError异常。TemporalMLDataSet类就像任何Encog数据集,允许时序数据被用于训练。TemporalPoint类代表数据的一个时间点。
要开始使用TemporalMLDataSet必须实例化如下:
上面的实例化指定了过去和未来窗口的大小。您还必须定义一个或多个TemporalDataDescription对象。这些定义了过去和未来窗口中的单个项。一个TemporalDataDescription对象可以作为过去和未来的窗口元素,如下面的代码所示。
指定一个TemporalDataDescription对象既是一个过去和未来的元素,Boolean值为最后两个参数。对于每个数据描述,您可以指定几种计算类型。这里总结了这些类型。
RAW类型指定数据点应传递给未修改的神经网络。PERCENT CHANGE指定每个点应按百分比变化传递。DELTA CHANGE指定每个点应作为两个值之间的实际变化传递。如果您自己对数据进行规范化,那么您将使用RAW类型。否则,您很可能会使用PERCENT CHANGE类型。
接下来,提供原始数据来训练时序网络。要做到这一点,创造TemporalPoint对象并将其添加到时序数据集。每个TemporalPoint对象可以包含多个值,和在TemporalDataDescription对象里一样,即在每个时间数据点里数值的数量相同。下面的代码展示了如何定义一个时态数据点。
每个数据点都应该有一个序列号,以便对数据点进行排序。调用SetData方法时允许设置单独值,应匹配在构造函数里指定的值。最后,调用生成方法。该方法利用所有的时间点创建训练集。生成被调用后,TemportalMLDataSet对象可以被用于训练。
下一节将使用TemportalMLDataSet对象预测太阳黑子。
8.3应用到太阳黑子
在这一节中我们将看到如何使用Encog预测太阳黑子,这个的周期性和可预见性很强。神经网络可以学习这种模式,并以合理的精度预测太阳黑子的数量。太阳黑子预报程序的输出如下所示。当然,神经网络首先开始训练,直到错误率降到百分之六以下为止。
Epoch #1 Error :0.39165411390480664
Epoch #2 Error :1.2907898518116008
Epoch #3 Error :1.275679853982214
Epoch #4 Error :0.8026954615095163
Epoch #5 Error :0.4999305514145095
Epoch #6 Error :0.468223450164209
Epoch #7 Error :0.22034289938540677
Epoch #8 Error :0.2406776630699879...
Epoch #128 Error :0.06025613803011326
Epoch #129 Error :0.06002069579351901
Epoch #130 Error :0.059830227113598734
Year Actual Predict Closed Loop Predict
1960 0.5723 0.5547 0.5547
1961 0.3267 0.4075 0.3918
1962 0.2577 0.1837 0.2672
1963 0.2173 0.1190 0.0739
1964 0.1429 0.1738 0.1135
1965 0.1635 0.2631 0.3650
1966 0.2977 0.2327 0.4203
1967 0.4946 0.2870 0.1342
1968 0.5455 0.6167 0.3533
1969 0.5438 0.5111 0.6415
1970 0.5395 0.3830 0.4011
1971 0.3801 0.4072 0.2469
1972 0.3898 0.2148 0.2342
1973 0.2598 0.2533 0.1788
1974 0.2451 0.1686 0.2163
1975 0.1652 0.1968 0.2064
1976 0.1530 0.1470 0.2032
1977 0.2148 0.1533 0.1751
1978 0.4891 0.3579 0.1014
一旦网络得到训练,它就试图预测1960到1978年间太阳黑子的数量。这样做至少有一定程度的准确性。显示的数字是标准化的,只提供了太阳黑子相对数量的概念。较大的数字表示太阳黑子活动较多;较低的数字表明太阳黑子活动较少。
给出了两个预测数:规则预测和闭环预测。两种预测类型都使用了过去的30窗口和未来的1窗口。规则预测仅使用实际数据中的最后30个值。闭环以这种方式启动:当它前进时,它自己的预测成为窗口向前滑动时的输入。这通常导致一个不太准确的预测,因为任何神经网络的错误都会叠加。
我们现在将研究这个程序是如何实现的。这个程序可以在下面的位置找到。
你可以看到,在文件的顶部程序有太阳黑子数据硬编码。这个数据是来自于一个基于C的神经网络的例子程序。您可以在下面的URL中找到原始应用程序:
http://www.neural-networks-at-your-fingertips.com/bpn.html
这个旧的,基于C的神经网络的例子将使用Encog进行修改,你会注意到Encog版本比基于C版短得多。这是因为例子所做的大部分已经在Encog实现。此外,encog版本的网络训练速度更快因为它利用弹性传播,而C的例子,利用反向传播算法。
这个例子通过两个步骤来使用数据。首先,规范化原始数据。然后这种规范化的数据加载到一个TemportalMLDataSet时序训练对象。normalizeSunspots方法来规范太阳黑子。此方法如下。
HI和LO参数指定太阳黑子正常化的高和低范围。这指定了规范化的太阳黑子范围。第2章讨论了规范化。在本例中,LO值为0.1,高值为0.9。
创建的NormalizeArray类的一个实例来规范这些数组。该对象将允许您快速地对数组进行规范化。若要使用此对象,只需设置规范化的高和低值,如下所示。
调用的方法能规范数组的值到一个指定的范围。
现在复制规范化太阳黑子到闭环太阳黑子。
最初,闭环数组的启动与常规预测相同。然而,它的预测会填充这个数组。现在太阳黑子数据已经被规范化,它应该被转换成时序数据。这是通过调用generateTraining方法完成,如下图所示。
该方法将返回一个encog数据集,可用于训练。首先是创造了一个指定过去和未来窗口大小的TemporalMLDataSet。
我们将有一个单一的数据描述。因为数据已经规范化了,所以我们将使用原始数据。此数据描述将用于输入和预测,因为最后两个参数指定。最后,我们将这个描述添加到数据集中。
现在需要创建所有的数据点。我们将在开始和结束的一年之间循环,这是用来训练神经网络的年份。其他年份将被用来测试神经网络的预测能力。
每个数据点只有一个值来预测太阳黑子。序列是一年,因为每年只有一个太阳黑子样本。
我们使用的值是太阳黑子的规范化数字。这个数字既可以用来获取过去的价值,也可以用来预测未来的价值。
最终,我们生成训练集和返回它。
这些数据现在已经准备好进行训练。该数据集使用弹性传播进行训练。这个过程与本书中多次使用的过程相同。一旦训练完成,我们将尝试使用应用程序来预测太阳黑子。这是用预测方法预测的结果,在这里展示。
首先,我们创建一个NumberFormat对象,因此这个数字能够格式化显示,这里我们将显示四个小数点。
我们通过评估每一年的循环显示表的头和开始。
我们根据实际数据建立神经网络的输入,这将是实际的预测。我们为过去的窗口提取了30年的数据。
神经网络传递输入数据之后我们检测获取的预测数据。
对于使用未来的预测,将这个保存到一个闭环数据
现在我们计算闭环值。计算基本上是相同的,除了闭环数据,这是不断修改,使用。和以前一样,我们使用30年的数据。
我们计算输出
最后,我们显示闭环预测,常规的预测和真实值。
这将显示一个由Encog做出的太阳黑子预测组成的列表。在下一节中我们将看到Encog如何自动拉取当前的市场信息和试图预测股市的方向。8.4使用Encog市场数据集
Encog还包括一个专门的股票市场数据集。此数据集能够从外部资源下载数据。目前,唯一的外部来源包括Encog雅虎金融。Encog市场数据是建立在时间数据的基础上,Encog市场数据集的大多数类直接来源于时序数据集中的相应类。
下面的类组成Encog市场数据包:
Marketdatadescription类代表一个市场的数据,无论是过去或未来的窗口。它来源于TemporalDataDescription类。主要是由一个股票代码对象和一个marketdatatype枚举组成。股票代码指定证券,marketdatatype指定使用来自这个证券数据的什么类型。可用数据类型如下所示。
这些都是Encog目前支持的市场数据类型标准。在Marketdatatype枚举内部对他们有表示。
Maketmldataset类是来自TemporalMLDataSet。在为Ecog创建以市场为基础的训练数据时,这是主要的类。这个类是一个encog数据集,可以训练。如果出现任何错误,则抛出异常的marketerror。
MarketPoint来自TemporalPoint MarketPoint类。你通常不会直接处理该对象,encog通常从雅虎财经下载市场数据。下面的代码展示了使用Marketmldataset类的一般格式。首先,创建一个加载程序。目前,该Yahoofinanceloader是唯一可用的Encog公共下载程序。
接下来,我们创建市场数据集,我们通过加载,以及制定过去窗口和未来窗口大小。
下一步创建一个Marketdatadescription对象。为此,请指定所需的股票代码和数据类型。末尾的最后两个真值指定此项用于过去和预测目的。
我们添加数据描述到数据集。
我们能够添加额外需要的描述,接下来,加载市场数据和生成训练数据。
如代码所示,必须指定开始日期和结束日期。这告诉Encog,生成训练数据的范围。8.5应用到股票市场
现在我们将看看应用encog预测股市的例子。这个程序试图根据过去的表现来预测单个股票的方向。这是一个非常简单的股票市场例子,不提供任何类型的投资建议。
首先,让我们解释一下如何运行这个示例。这个示例可以运行四种不同的模式,这取决于传递的命令行参数。这些参数概括如下。
首先你应该运行主类的实例,即MarketPredict。下面的部分将展示这个示例是如何生成数据、训练和评估神经网络的结果。此应用程序位于以下位置。
现在使用这些程序的每一种模式都将覆盖。
8.5.1产生训练数据
第一步是生成训练数据。该示例将下载大约八年的财务信息以供训练。下载和处理此信息需要一定的时间。数据下载和写入到一个Encog EG文件。类Marketbuildtraining提供此功能。
该类执行的所有工作都在静态方法中,命名为generate。此方法如下所示。
首先通过YahooFinanceLoader加载创建要求的金融数据方法。
一个新的marketmldataset对象创建时,将使用装载机和对过去和未来的窗口指定大小。默认情况下,程序使用未来窗口大小为1和过去窗口大小为10。这些常量都是在Config类中定义的。这是通过改变配置类中的值来控制网络结构和训练的方法。
这个程序使用单一的市场值来进行预测。它将使用指定证券的调整收盘价。程序试图预测的证券在Config类中指定。
市场数据是从两年前开始的,在今天之前的两个月结束。最后两个月将用于评估神经网络的性能。
我们现在以二进制EGB文件保存训练数据。需要注意的是,temporaldataset或其派生类将持久原数值数据,像basicmldataset那样。只有产生的数据被保存,而不是其他的支持对象如marketdatadescription对象。
我们将创建一个网络,并保存到EG文件中。这个网络是一个简单的前馈神经网络,它可能有一个或两个隐藏层。隐藏层的大小在Config类中指定。
我们现在创建EG文件和存储神经网络到一个EG文件。
最后阶段的程序,例如训练和评估阶段,将使用这些文件。
8.5.2训练神经网络
训练神经网络非常简单。网络和训练数据已经创建并存储在一个EG文件中。训练类所需要做的就是从EG文件中加载这两个资源并开始训练。markettrain类就是这样做的。
静态方法训练完成所有的训练。此处显示此方法。
方法开始验证是否存在Encog EG文件,训练数据和神经网络将从这里加载。
接下来,使用EncogDirectoryPersistence对象加载EG文件,我们将得到一个神经网络。
接下来,从磁盘加载训练文件,给这个神经网络训练使用。
神经网络现在已经准备好训练了。我们将用Encogutility训练和在Config类指定的分钟数。这与创建一个训练对象和使用迭代一样,正如之前在本书中所做的一样。trainConsole是运行指定的分钟数的迭代的简单快捷方法。
最后,神经网络保存回EG文件。
此时,训练神经网络。为了进一步训练神经网络,再次运行训练或继续评估神经网络。如果使用弹性传播再次训练相同的神经网络,错误率将开始尖峰。这是因为弹性传播算法必须重建适当的delta值来进行训练。8.5.3增量修剪
神经网络的一个挑战是确定隐藏层的最佳架构。隐藏层应该为一层还是两层?每个隐藏层中应该有多少神经元?这些问题没有简单的答案。
一般来说,最好是用一个隐藏层的神经网络,以及隐藏层神经元数目是输入神经元的两倍。有一些报告表明,第二层隐藏层没有优势,尽管这经常引起争议。其他报告表明第二隐藏层有时会导致更快的收敛速度。更多信息,参考隐藏层的希顿研究Wiki页面。http://www.heatonresearch.com/wiki/Hidden_Layers
Encog提供了一个增量修剪类。这个类允许您使用蛮力技术来确定最佳隐藏层配置。用“修剪”参数调用市场示例将执行增量剪枝。这将尝试一些不同的隐藏层配置,试图找到最好的一个。
这个命令从加载一个训练集到内存开始。
接下来创建一个模式到指定的神经网络类型。
上面的代码指定创建前馈神经网络,使用双曲正切激活函数,接下来,创建prune对象。
该对象将执行100次训练迭代,每次尝试一个权重,并拥有10个顶级网络。在100次训练迭代之后,对象将挑出10个最佳网络。这10个最好的被选择成为网络的最少链接数。
用户还可以指定隐藏层的数量和大小以供尝试。每次调用addhiddenlayer指定上限和下限来尝试。对addhiddenlayer第一次调用指定第一隐层的范围。在这里,我们指定尝试隐藏层的大小从5到50。因为低点不是零,所以我们必须有第一个隐藏层。
接下来,我们指定第二隐藏层的大小。下面我们试着隐藏层有0到50个神经元。由于低点是零,我们也将尝试没有第二层的神经网络。
现在这个对象我们已经准备好了,调用Process方法开始搜索。
一旦搜索完成后你可以调用getbestnetwork得到最好的执行网络。下面的代码获取这个网络并保存它。
我们现在保存了一个有良好的隐藏层和神经元组合的神经网络。修剪对象并不特别训练每一个网络,因为它试图搜索大量的网络。在这一点上,您将需要进一步培训这个最好的网络。
8.5.4评估神经网络
我们现在已经准备好从上一节使用经过训练的神经网络来评估,并评估它在实际的股票市场数据上的表现。Marketevaluate类包含所有的评价准则。
在评估过程中有两个重要的方法。首先是determinedirection类。我们不是试图确定一个证券的实际百分比变化,而是第二天它将朝哪个方向移动。
此方法只返回一个枚举,指定股票价格是向上还是向下移动。
我们需要一些目前的市场数据来评估。grabdata方法获得必要的市场数据。它使用一个marketmldataset,就像训练一样,获得一些市场数据。此处显示此方法。
就像训练数据生成,市场数据从YahooFinanceLoader对象中加载。
我们创建与培训相同的数据描述:用于指定股票代码的调整关闭。也希望得到过去和将来的数据。通过将过去的数据输入到神经网络,我们将看到输出与未来数据的匹配程度。
选择数据范围到评估网络,我们将抓取最近60天的数量。
市场数据现在通过使用load方法加载和生成。
生成的数据被返回给调用方法。既然我们已经讨论了支持的方法,现在是学习实际训练如何发生的时候了。静态方法评价进行实际评价。此方法如下所示。
首先,检查Encog EG文件是否存在。
然后,我们从EG文件中加载神经网络,使用前一节的神经网络训练。
为网络评估加载市场数据到使用,在这节中早就讨论了grabData方法的使用。
使用一个格式化程序格式化百分比。
在评估期间,计算所检查的count和correct的数量。
循环所有加载的市场数据。
检索一对训练集,获得实际数据和预测结果。预测数据是通过使用计算方法运行网络来确定的。
现在检索实际数据和预测数据,计算差异。这就建立了神经网络预测实际价格变化的准确性。
也计算网络预测安全的方向和安全实际采取的方向。
如果是当前的方向,correct加一,无论哪种方式,count都要加一。
显示每一次检测的结果。
最后,显示统计数据对整个神经网络的精度。
下面的代码片段显示了一旦启动一个应用程序的输出。因为它使用当前日期之前的数据,运行时结果会不同。这些结果是因为该程序试图预测苹果电脑股票价格的移动百分比。
Day 1: actual =0.05(up) , predict =-0.09(up) , diff =0.1331431391626865
Day 2: actual =-0.02(down) , predict =0.15(down) , diff=0.1752316137707985
Day 3: actual =-0.04(down) , predict =-0.08(down) , diff=0.04318588896364293
Day 4: actual =0.04(up) , predict =-0.13(up) , diff =0.167230163960771
Day 5: actual =0.04(up) , predict =0.08(up) , diff =0.041364210497886064
Day 6: actual =-0.05(down) , predict =-0.15(down) , diff=0.09856291235302134
Day 7: actual =0.03(up) , predict =0.02(up) , diff =0.0121349208067498
Day 8: actual =0.06(up) , predict =0.14(up) , diff =0.07873950162422072
Day 9: actual =0.00(up) , predict =-0.04(up) , diff =0.044884229765456175
Day 10: actual =-0.02(down) , predict =-0.11(down) , diff=0.08800357702537594
Day 11: actual =-0.03(down) , predict =0.10(down) , diff=0.1304932331559785
Day 12: actual =0.03(up) , predict =-0.00(up) , diff =0.03830226924277358
Day 13: actual =-0.04(down) , predict =-0.03(down) , diff=0.006017023124087514
Day 14: actual =0.01(up) , predict =-0.00(up) , diff =0.011094798099546017
Day 15: actual =-0.07(down) , predict =0.10(down) , diff=0.1634993352860712
Day 16: actual =0.00(up) , predict =0.09(up) , diff =0.08529079398874763
Day 17: actual =0.01(up) , predict =0.08(up) , diff =0.07476901867409716
Day 18: actual =-0.05(down) , predict =0.10(down) , diff=0.14462998342498684
Day 19: actual =0.01(up) , predict =0.01(up) , diff =0.0053944458622837204
Day 20: actual =-0.02(down) , predict =0.16(down) , diff=0.17692298105888082
Day 21: actual =0.01(up) , predict =0.01(up) , diff =0.003908063600862748
Day 22: actual =0.01(up) , predict =0.05(up) , diff =0.04043842368088156
Day 23: actual =-0.00(down) , predict =0.05(down) , diff=0.05856519756505361
Day 24: actual =-0.01(down) , predict =-0.01(down) , diff=0.0031913517175624975
Day 25: actual =0.06(up) , predict =0.03(up) , diff =0.02967685979492382
Day 26: actual =0.04(up) , predict =-0.01(up) , diff =0.05155871532643232
Day 27: actual =-0.02(down) , predict =-0.09(down) , diff=0.06931714317358993
Day 28: actual =-0.02(down) , predict =-0.04(down) , diff=0.019323500655091908
Day 29: actual =0.02(up) , predict =0.06(up) , diff =0.04364949212592098
Day 30: actual =-0.02(down) , predict =-0.06(down) , diff=0.036886336426948246
Direction correct :18/30
Directional Accuracy :60.00%
在这里,程序的准确率为60%,这是非常好的这个简单的神经网络。当这个程序以不同的间隔运行时,准确率一般在30-40%之间。
这是一个非常简单的股市预测,不应该用于任何实际投资。它展示了如何构造一个神经网络来预测市场方向。
8.5应用到股票市场
在这一章中,我们学习了Encog怎样处理时序神经网络,时序网络使用来预测未来将要发生的东西,在这一章中的第一个例子显示怎样使用Encog预测太阳黑子,第二个例子显示怎样使用Encog尝试预测股票价格变动。
太阳黑子示例使用TemporalDataSet,这是一个低层时序数据集,设计模式为任意“基于窗口”预测神经网络,使用一个过去窗口提供几个值到神经网络去预测,一个未来窗口指定神经网络的元素的数量,应该预测的未来。
股票市场示例使用MarketMLDataSet类,该类基于TemporalDataSet, 它会自动去雅虎金融网站下载金融信息,这是一个非常简单的例子,展示了将神经网络应用于股票市场的基础。投资者不应该基于这个网络。
下一章将展示怎样为使用图像数据,将图像呈现给神经网络是将图像转换成数字数组的问题,这样神经网络就可以把它看作输入。这是真实的任何信息被提交到一个神经网络。这是一个将数据转换为浮点值的数组。