时间序列预测在R中的应用 (Part1 简介和预测工具集)

本文介绍了时间序列预测在R中的应用,包括预测的基本步骤、选择模型的依据,强调了时间序列模型在实践中的优势。文章探讨了时间序列数据的特性,如趋势、季节性和周期性,并展示了R语言中的基本可视化工具,如时间图、季节图、散点图和滞后图,以及预测者常用的简单方法,如均值法、Naïve方法等。
摘要由CSDN通过智能技术生成

最近认真阅读了一份商业分析的咨询报告案例,并分析了其写作思路,有兴趣请戳:商业分析、咨询报告思路详细解读(CASE R001) - 知乎

在仔细分析完这份报告中,发现商业领域中的咨询报告都逃不过“市场规模预测”的部分,而市场规模预测通常又与统计学中时间序列预测的内容脱离不了干系。所以,来恶补一下时间序列分析的内容,并探究如何在R中实现时间序列的预测。本内容来源于Rob J Hyndman 和 George Athanasopoulos的《Forecasting:principles and practice》。这本书是免费的,电子书资源网站:预测: 方法与实践

本文是时间序列预测在R中的应用的第一部分,涉及到目录中1 Introduction以及2 预测的工具及部分。

目录

1 Introduction

2 预测的工具集

3 时间序列回归模型

4 时间序列分解

5 指数平滑

6 ARIMA模型


1 Introduction

  每个环境都是在变化的,并且一个优秀的预测模型会捕捉事物变化的方式。根据时间跨度、确定实际结果的因素、数据模式的类型以及许多其他方面,预测情况会有很大的不同。预测方法可以非常简单,例如使用最近一次观测作为预测(被称为“朴素方法”),也可以很复杂,例如神经网络和联立方程的计量经济系统。

1)进行预测的步骤

  • 定义问题。此步骤需要了解怎样运用预测方法,谁需要这个预测,以及预测效果如何满足需要这个预测的机构。
  • 收集信息。一般会收集统计数据和专家经验建议。
  • 初步(探索性)分析。通常会使用数据可视化的方式来对数据结构进行初步探索。我们通过可视化可以发现有明显的长期趋势吗?季节性重要吗?是否有证据表明商业周期存在?数据中是否包含需要专业知识解释的异常值?用于分析的变量之间的相关性有多强?
  • 选择及拟合模型。目前已有多种模型供我们选择,我们可以根据探索性分析中对数据结构的把握,来选择合适的模型进行时间序列预测。如回归模型、指数平滑方法、Box-Jenkins ARIMA模型、动态回归模型、分层预测,以及其他各种方法,包括计数时间序列、神经网络的向量自回归。
  • 使用及评估预测模型。模型的预测效果只有用于预测的数据得到之后才能得到正确的评价。

可以看出,与一般数据建模的思路相同:建模过程都要从所需解决的问题入手,再到收集数据、探索性分析、选择拟合模型、模型评估调整的步骤。

2)预测数据和方法

数据决定了选择什么样的模型进行预测。大多数定量预测问题都使用时间序列数据 (按时间间隔定期收集) 横截面数据 (在一个时间点收集)。我们在日常生活中,主要专注于时间序列的领域:

时间序列数据:

任何按照时间顺序观察的事物都是时间序列。在预测时间序列数据时, 目的是估计观测序列将如何持续到未来。

最简单的时间序列预测方法只用了预测变量的信息,而不去寻找影响预测变量的因素。因此,这些方法可以推断趋势部分和季节性部分,但是它们会忽略掉所有其他的信息。关于时间序列的预测模型,可能有如下三种类型:

①解释模型:我们可以考虑一些其他有关外部变量的信息,而不仅仅是要预测的变量的。这类包含其他变量的模型可以称之为“解释模型”,例如:

ED=f(当前气温,经济实力,人口当日时间,星期几,误差)

②时间序列模型:对未来的预测是基于变量的历史值,而不是基于可能影响系统的外部变量。

EDt+1=f(EDt,EDt−1,EDt−2,EDt−3,…,误差)

t表示当前的时间,t+1表示下一个小时,t−1表示前一个小时,t−2表示前两个小时,以此类推

③混合模型:结合了上述两种模型的特点。例如, 它可能有如下形式:

EDt+1=f(EDt,当前气温,当日时间,星期几,误差)

虽然解释模型看起来非常有用,但是在实际运用中,预测者通常会选择使用时间序列模型:不仅仅因为其他模型太过复杂、难以理解和衡量、缺少和实践中管理行为的练习,最为关键的一点事,时间序列模型可以提供比解释或混合模型更准确的预测。在预测中使用的模型取决

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Transformer模型可以用于时间序列预测,以下是一个使用Python和TensorFlow对时间序列进行预测的示例: 首先,导入必要的库和数据集: ```python import tensorflow as tf import numpy as np import matplotlib.pyplot as plt # 生成数据集 def generate_time_series(): frequency1, frequency2, offset1, offset2 = np.random.rand(4) * 0.5 time = np.linspace(0, 1, 200) series = offset1 + np.sin((frequency1 * 10 + time) * 2 * np.pi) * 0.2 + \ offset2 + np.sin((frequency2 * 20 + time) * 2 * np.pi) * 0.1 return series[..., np.newaxis].astype(np.float32) # 划分数据集 data = generate_time_series() train_data = data[:150] val_data = data[150:175] test_data = data[175:] # 可视化数据集 plt.plot(np.arange(200), data) plt.show() ``` 接下来,构建Transformer模型: ```python class Transformer(tf.keras.Model): def __init__(self, num_layers, units, d_model, num_heads, dropout, name='transformer'): super(Transformer, self).__init__(name=name) self.encoder = tf.keras.layers.Dense(units, activation='relu') self.decoder = tf.keras.layers.Dense(1) self.pos_encoding = positional_encoding(200, d_model) self.num_layers = num_layers self.d_model = d_model self.dec_layers = [DecoderLayer(d_model, num_heads, units, dropout, name='dec_layer_{}'.format(i)) for i in range(num_layers)] self.dropout = tf.keras.layers.Dropout(dropout) def call(self, inputs, training=False): # 编码器 x = self.encoder(inputs) # (batch_size, input_seq_len, d_model) x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32)) x += self.pos_encoding[:, :tf.shape(x)[1], :] # 解码器 for i in range(self.num_layers): x = self.dec_layers[i](x, training=training) x = self.decoder(x) # (batch_size, input_seq_len, 1) return x # 解码器层 class DecoderLayer(tf.keras.layers.Layer): def __init__(self, d_model, num_heads, units, dropout, name='dec_layer'): super(DecoderLayer, self).__init__(name=name) self.mha1 = MultiHeadAttention(d_model, num_heads) self.mha2 = MultiHeadAttention(d_model, num_heads) self.ffn = point_wise_feed_forward_network(units, d_model) self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6) self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6) self.layernorm3 = tf.keras.layers.LayerNormalization(epsilon=1e-6) self.dropout1 = tf.keras.layers.Dropout(dropout) self.dropout2 = tf.keras.layers.Dropout(dropout) self.dropout3 = tf.keras.layers.Dropout(dropout) def call(self, inputs, training=False): # 第一层多头注意力 attn1 = self.mha1(inputs, inputs, inputs) attn1 = self.dropout1(attn1, training=training) out1 = self.layernorm1(inputs + attn1) # 第二层多头注意力 attn2 = self.mha2(out1, out1, out1) attn2 = self.dropout2(attn2, training=training) out2 = self.layernorm2(out1 + attn2) # 前馈神经网络 ffn_output = self.ffn(out2) ffn_output = self.dropout3(ffn_output, training=training) out3 = self.layernorm3(out2 + ffn_output) return out3 # 多头注意力机制 class MultiHeadAttention(tf.keras.layers.Layer): def __init__(self, d_model, num_heads, name='multi_head_attention'): super(MultiHeadAttention, self).__init__(name=name) self.num_heads = num_heads self.d_model = d_model assert d_model % self.num_heads == 0 self.depth = d_model // self.num_heads self.wq = tf.keras.layers.Dense(d_model) self.wk = tf.keras.layers.Dense(d_model) self.wv = tf.keras.layers.Dense(d_model) self.dense = tf.keras.layers.Dense(d_model) def split_heads(self, x, batch_size): x = tf.reshape(x, (batch_size, -1, self.num_heads, self.depth)) return tf.transpose(x, perm=[0, 2, 1, 3]) def call(self, v, k, q): batch_size = tf.shape(q)[0] q = self.wq(q) # (batch_size, seq_len, d_model) k = self.wk(k) # (batch_size, seq_len, d_model) v = self.wv(v) # (batch_size, seq_len, d_model) q = self.split_heads(q, batch_size) # (batch_size, num_heads, seq_len_q, depth) k = self.split_heads(k, batch_size) # (batch_size, num_heads, seq_len_k, depth) v = self.split_heads(v, batch_size) # (batch_size, num_heads, seq_len_v, depth) scaled_attention, attention_weights = scaled_dot_product_attention(q, k, v) scaled_attention = tf.transpose(scaled_attention, perm=[0, 2, 1, 3]) concat_attention = tf.reshape(scaled_attention, (batch_size, -1, self.d_model)) output = self.dense(concat_attention) return output # 缩放点积注意力机制 def scaled_dot_product_attention(q, k, v): matmul_qk = tf.matmul(q, k, transpose_b=True) dk = tf.cast(tf.shape(k)[-1], tf.float32) scaled_attention_logits = matmul_qk / tf.math.sqrt(dk) # 掩码 mask = tf.linalg.band_part(tf.ones_like(scaled_attention_logits), -1, 0) scaled_attention_logits += (mask * -1e9) attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1) output = tf.matmul(attention_weights, v) return output, attention_weights # 位置编码 def get_angles(pos, i, d_model): angle_rates = 1 / np.power(10000, (2 * (i // 2)) / np.float32(d_model)) return pos * angle_rates def positional_encoding(position, d_model): angle_rads = get_angles(np.arange(position)[:, np.newaxis], np.arange(d_model)[np.newaxis, :], d_model) # 将 sin 应用于数组的偶数索引(indices);2i angle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2]) # 将 cos 应用于数组的奇数索引;2i+1 angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2]) pos_encoding = angle_rads[np.newaxis, ...] return tf.cast(pos_encoding, dtype=tf.float32) # 前馈神经网络 def point_wise_feed_forward_network(d_model, diff): return tf.keras.Sequential([ tf.keras.layers.Dense(diff, activation='relu'), tf.keras.layers.Dense(d_model) ]) ``` 接下来,定义损失函数和优化器,并进行模型训练: ```python # 损失函数 loss_object = tf.keras.losses.MeanSquaredError() # 优化器 optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4) # 指标 train_loss = tf.keras.metrics.Mean(name='train_loss') val_loss = tf.keras.metrics.Mean(name='val_loss') # 训练步骤 @tf.function def train_step(inputs, targets): with tf.GradientTape() as tape: predictions = transformer(inputs, training=True) loss = loss_object(targets, predictions) gradients = tape.gradient(loss, transformer.trainable_variables) optimizer.apply_gradients(zip(gradients, transformer.trainable_variables)) train_loss(loss) # 验证步骤 @tf.function def val_step(inputs, targets): predictions = transformer(inputs, training=False) loss = loss_object(targets, predictions) val_loss(loss) # 训练模型 num_epochs = 2000 transformer = Transformer(num_layers=4, units=64, d_model=128, num_heads=8, dropout=0.1) for epoch in range(num_epochs): train_loss.reset_states() val_loss.reset_states() for input_series in range(len(train_data) - 10): inputs = train_data[input_series:input_series + 10] targets = train_data[input_series + 10] train_step(inputs, targets) for input_series in range(len(val_data) - 10): inputs = val_data[input_series:input_series + 10] targets = val_data[input_series + 10] val_step(inputs, targets) if epoch % 100 == 0: print('Epoch {}, Train Loss: {:.4f}, Val Loss: {:.4f}'.format(epoch, train_loss.result(), val_loss.result())) ``` 最后,使用训练好的模型进行预测并可视化: ```python # 预测 predictions = [] for input_series in range(len(test_data) - 10): inputs = test_data[input_series:input_series + 10] prediction = transformer(inputs[np.newaxis, ...], training=False)[0, -1].numpy() predictions.append(prediction) # 可视化预测结果 plt.plot(np.arange(175, 200), np.array(predictions), label='Predictions') plt.plot(np.arange(175, 200), test_data[10:], label='Real Data') plt.legend() plt.show() ``` 这里的示例是基于一个简单的时间序列预测问题,你可以根据自己的数据集和需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值