使用TensorFlow.js进行时间序列预测

从在线API提取股票价格并使用带有TensorFlow.js框架的递归神经网络和长期短期记忆(LSTM)进行预测

如今,机器学习正变得越来越流行,世界上越来越多的人将其视为一个神奇的水晶球:预测未来何时以及将发生什么。 该实验使用人工神经网络揭示股票市场趋势,并证明了时间序列预测功能可以根据过去的历史数据预测未来的股票价格。

免责声明:由于多种因素导致股市波动是动态的且不可预测的,因此该实验具有100%的教育意义,而绝非交易预测工具。

探索演示 。

项目演练

此项目的演练分为4部分:

1.从在线API获取股票数据

2.计算给定时间范围内的简单移动平均线

3.训练LSTM神经网络

4.预测并将预测值与实际值进行比较

获取库存数据

在训练神经网络并做出任何预测之前,我们将首先需要数据。 我们正在寻找的数据类型是时间序列:按时间顺序排列的数字序列。 从alphavantage.co获取这些数据的好地方。 该API使我们能够检索过去20年中特定公司股票价格的时间顺序数据。

API产生以下字段:

-开盘价

-当天最高价

-当天的最低价格

-收盘价(在该项目中使用)

-音量

为了为我们的神经网络准备训练数据集,我们将使用收盘价。 这也意味着我们将致力于预测未来收盘价。

使用TensorFlow.js进行时间序列预测_第1张图片

该图显示了Microsoft Corporation 20年的周收盘价。

简单移动平均线

对于此实验,我们使用监督学习 ,这意味着将数据馈送到神经网络,并且它通过将输入数据映射到输出标签进行学习。 准备训练数据集的一种方法是从该时间序列数据中提取移动平均值。

简单移动平均线(SMA)是一种通过查看该时间窗口内所有值的平均值来确定特定时间段内趋势方向的方法。 时间窗口中的价格数量是通过实验选择的。

例如,假设过去5天的收盘价为13、15、14、16、17,则SMA为(13 + 15 + 14 + 16 + 17)/ 5 =15。因此,我们训练的输入数据集是单个时间窗口内的一组价格,其标签是这些价格的计算得出的移动平均值。

让我们计算窗口大小为50的Microsoft Corporation每周收盘价数据的SMA。

function ComputeSMA ( data, window_size )
 {
  let r_avgs = [], avg_prev = 0 ;
  for ( let i = 0 ; i <= data.length - window_size; i++){
    let curr_avg = 0.00 , t = i + window_size;
    for ( let k = i; k < t && k <= data.length; k++){
      curr_avg += data[k][ 'price' ] / window_size;
    }
    r_avgs.push({ set : data.slice(i, i + window_size), avg : curr_avg });
    avg_prev = curr_avg;
  }
  return r_avgs;
}

这就是我们得到的,每周收盘价为蓝色,SMA为橙色。 由于SMA是50周的移动平均线,因此它比可能波动的每周价格平滑。

使用TensorFlow.js进行时间序列预测_第2张图片

该图是Microsoft Corporation收盘价数据到实际收盘价的简单移动平均线。

训练数据

我们可以使用每周股票价格和计算得出的SMA准备训练数据。 给定窗口大小为50,这意味着我们将使用连续50周的收盘价作为我们的训练特征(X),并将这50周的SMA作为我们的训练标签(Y)。

接下来,我们将数据分为2组,即训练和验证组。 如果70%的数据用于训练,则30%的数据用于验证。 API向我们返回大约1000周的数据,因此700可以进行培训,而300可以进行验证。

训练神经网络

现在已经准备好训练数据,是时候创建一个用于时间序列预测的模型了,要实现这一点,我们将使用TensorFlow.js框架。 TensorFlow.js是一个用于使用JavaScript开发和训练机器学习模型的库,我们可以在Web浏览器中部署这些机器学习功能。

选择顺序模型 ,该模型仅连接每个层,并在训练过程中将数据从输入传递到输出。 为了使模型学习顺序的时间序列数据,创建了递归神经网络 (RNN)层,并将多个LSTM单元添加到RNN。

该模型将使用Adam ( 研究论文 )进行训练, Adam是一种流行的机器学习优化算法。 均方根误差将决定预测值和实际值之间的差异,因此该模型能够通过在训练过程中将误差最小化来进行学习。

这是上述模型的代码片段, 有关Github的完整代码。

async function trainModel ( inputs, outputs, trainingsize, window_size, n_epochs, learning_rate, n_layers, callback ) {

  const input_layer_shape  = window_size;
  const input_layer_neurons = 100 ;

  const rnn_input_layer_features = 10 ;
  const rnn_input_layer_timesteps = input_layer_neurons / rnn_input_layer_features;

  const rnn_input_shape  = [rnn_input_layer_features, rnn_input_layer_timesteps];
  const rnn_output_neurons = 20 ;

  const rnn_batch_size = window_size;

  const output_layer_shape = rnn_output_neurons;
  const output_layer_neurons = 1 ;

  const model = tf.sequential();

  let X = inputs.slice( 0 , Math .floor(trainingsize / 100 * inputs.length));
  let Y = outputs.slice( 0 , Math .floor(trainingsize / 100 * outputs.length));

  const xs = tf.tensor2d(X, [X.length, X[ 0 ].length]).div(tf.scalar( 10 ));
  const ys = tf.tensor2d(Y, [Y.length, 1 ]).reshape([Y.length, 1 ]).div(tf.scalar( 10 ));

  model.add(tf.layers.dense({ units : input_layer_neurons, inputShape : [input_layer_shape]}));
  model.add(tf.layers.reshape({ targetShape : rnn_input_shape}));

  let lstm_cells = [];
  for ( let index = 0 ; index < n_layers; index++) {
       lstm_cells.push(tf.layers.lstmCell({ units : rnn_output_neurons}));
  }

  model.add(tf.layers.rnn({
    cell : lstm_cells,
    inputShape : rnn_input_shape,
    returnSequences : false
  }));

  model.add(tf.layers.dense({ units : output_layer_neurons, inputShape : [output_layer_shape]}));

  model.compile({
    optimizer : tf.train.adam(learning_rate),
    loss : 'meanSquaredError'
  });

  const hist = await model.fit(xs, ys,
    { batchSize : rnn_batch_size, epochs : n_epochs, callbacks : {
      onEpochEnd : async (epoch, log) => {
        callback(epoch, log);
      }
    }
  });

  return { model : model, stats : hist };
}

这些是可以在前端进行调整的超参数 (训练过程中使用的参数 ):

-培训数据集大小(%):用于培训的数据量,其余数据将用于验证

-时期:数据集用于训练模型的次数( 了解更多 )

-学习率:训练过程中每一步的权重变化量( 了解更多 )

-隐藏的LSTM层:增加模型的复杂性以在更高维度的空间中学习 ( 了解更多 )

使用TensorFlow.js进行时间序列预测_第3张图片

单击开始训练模型按钮…

使用TensorFlow.js进行时间序列预测_第4张图片

该模型似乎在15个时代收敛。

验证方式

现在已经对模型进行了训练,是时候使用它来预测未来值了,在我们的例子中,它是移动平均值。 我们将使用TFJS中的model.predict函数。

数据已分为2组,即训练和验证组。 训练集已用于训练模型,因此将使用验证集来验证模型。 由于模型尚未看到验证数据集,因此如果模型能够预测接近真实值的值将是很好的。

因此,让我们使用剩余数据进行预测,这使我们能够看到预测值与实际值之间的接近程度。

使用TensorFlow.js进行时间序列预测_第5张图片

该图显示了绿线,它是验证数据的预测。

看起来预测的模型(绿线)在逼近实际价格(蓝线)方面做得很好。 这意味着该模型能够预测该模型看不到的最后30%的数据。

可以应用其他算法,并使用均方根误差来比较2个或更多模型的性能。

预测

最后,该模型已经过验证,并且预测值与实际值紧密对应,我们将使用它来预测未来。 我们将应用相同的model.predict函数,并使用最后50个数据点作为输入,因为我们的窗口大小是50。由于我们的训练数据每天都在增加,因此我们将使用过去50天作为输入来预测第51天。

使用TensorFlow.js进行时间序列预测_第6张图片

该图显示最近的50天,即测试数据(蓝线)和预测值(橙色)。

结论

除了使用简单的移动平均值外,还有许多方法可以进行时间序列预测。 未来可能的工作是使用来自各种来源的更多数据来实现这一目标。

使用TensorFlow.js,可以在Web浏览器上进行机器学习,并且实际上非常酷。

在Github上浏览演示 ,该实验具有100%的教育意义,绝不是交易预测工具。

在Github上查看源代码

嗨! 我是洪静(Jingles) ,目前是阿里巴巴集团的数据科学家,南洋理工大学的博士研究生,也是《 迈向数据科学》和《 哈克农恩》的热情作家。 在LinkedIn上与我联系。

本文最初发表于“ 迈向数据科学”

From: https://hackernoon.com/time-series-forecasting-with-tensorflowjs-co3rz32ms

你可能感兴趣的:(人工智能,前端,javascript,ViewUI)