当前位置: 首页 > article >正文

统计软件与数据分析Lesson5---时间序列分析入门

统计软件与数据分析Lesson5---时间序列分析入门

    • 1.什么是时间序列数据?
    • 2.什么是伪回归?
    • 3.什么是白噪声?
    • 4.怎么判断一个序列是白噪声序列?
    • 5.时间序列数据做预测的前提假设是什么?
    • 6.预测时间序列为什么要求数据满足平稳性?
    • 7.怎样检测时序数据是否满足平稳性?
    • 8.不满足平稳性应该怎么办?
      • 差分
      • 对数变换
      • 移动平均法
    • 9.满足平稳性后有哪些可供选择的时间序列预测模型?
    • 10.自回归参数和移动平均的参数怎么确定?
    • 11.确定参数后怎么基于合适的时序预测模型进行模型的拟合?
    • 12.拟合好模型后怎样进行预测结果的可视化
    • 13.怎样评估预测结果的好坏?

1.什么是时间序列数据?

时间序列数据是按照时间顺序排列的数据,每个时间点上都有一个对应的观测值。时间序列数据可以用于对过去和未来的趋势、周期性、随机波动等进行分析和预测。

以下是日常生活中常见的时间序列数据的一些例子:

  • 1.股票价格:每天的股票价格是按照时间顺序排列的时间序列数据。
  • 2.天气数据:每天的温度、降雨量、风速等天气数据也是时间序列数据。
  • 3.交通流量:每小时、每天或每周的交通流量也是时间序列数据。
  • 4.网站访问量:每天、每周或每月的网站访问量也是时间序列数据。
  • 5.电影票房:每天或每周的电影票房收入也是时间序列数据。

下面是一个使用Python导入时间序列数据的示例:

# 加载包
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf
from statsmodels.tsa.ar_model import AutoReg
from sklearn.metrics import mean_squared_error

plt.rcParams['font.family'] = ['SimHei']
plt.rcParams['axes.unicode_minus']=False

%matplotlib inline
#读取已处理好的数据
df0 = pd.read_csv('./data/sh601318_processed.csv',index_col='Date')
df = df0[['Close']]
df.index = pd.to_datetime(df.index, format='%Y-%m-%d') # 将Date列转换为datetime格式

# 查看数据的基本信息
print('~~~~~~~~~~~~~~~~~~~~df.head()~~~~~~~~~~~~~~~~~~~~~')
print(df.head())
print('~~~~~~~~~~~~~~~~~~~~df.info()~~~~~~~~~~~~~~~~~~~~~')
print(df.info())
print('~~~~~~~~~~~~~~~~~~~df.describe()~~~~~~~~~~~~~~~~~~~~~~')
print(df.describe())

#对数据进行可视化,以了解股票价格的趋势和变化。
plt.figure(figsize=(10, 6))
plt.plot(df['Close'])
plt.title('ZGPA收盘价')
plt.xlabel('日期')
plt.ylabel('收盘价格(元)')
plt.show()

输出:

~~~~~~~~~~~~~~~~~~~~df.head()~~~~~~~~~~~~~~~~~~~~~
            Close
Date             
2015-01-05  76.16
2015-01-06  73.73
2015-01-07  73.41
2015-01-08  71.08
2015-01-09  72.84
~~~~~~~~~~~~~~~~~~~~df.info()~~~~~~~~~~~~~~~~~~~~~
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 1986 entries, 2015-01-05 to 2023-03-03
Data columns (total 1 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   Close   1986 non-null   float64
dtypes: float64(1)
memory usage: 31.0 KB
None
~~~~~~~~~~~~~~~~~~~df.describe()~~~~~~~~~~~~~~~~~~~~~~
             Close
count  1986.000000
mean     59.308565
std      19.078526
min      25.110000
25%      42.335000
50%      59.700000
75%      76.757500
max      93.380000

在这里插入图片描述

2.什么是伪回归?

伪回归指的是两个或多个变量之间出现了显著相关性,但这种相关性并非由因果关系所引起,而是由于这些变量受到相同的趋势或其他因素的共同影响而引起的,因此在建模时不能简单地将相关性解释为因果关系。伪回归也被称为“干扰回归”或“错觉回归”、“虚假相关性”或“伪关联”。

以下是一些伪回归的经典案例:

  • 一是“啤酒与尿布”的案例。在过去的营销数据中发现啤酒的销量与尿布的销量有显著的相关性,但这并不是因为啤酒会让人们购买更多的尿布,而是因为这些数据是在便利店中收集的,而父母在购买尿布时也会顺便买些啤酒。

  • 二是研究寿命与身高之间的关系。研究可能会发现身高高的人寿命更长,但是这并不意味着身高是寿命的因果影响,因为身高和寿命都受到其他因素的影响,例如生活方式、基因等。

  • 三是冰淇淋和游泳圈两种商品的价格,其趋势看似高度相关,但实际上是由于两种商品价格都受市场需求和供应等多种因素的影响,而不是互相影响。

以下是使用Python模拟伪回归的示例。我们首先生成两个随机变量,分别表示x和y,然后将它们加上一个共同的随机趋势项,最后用散点图展示它们的关系。

# 生成两个随机变量
x = np.random.rand(100)
y = np.random.rand(100)

# 计算相关系数
corr_coef = np.corrcoef(x, y)[0, 1]

# 绘制散点图和回归线
plt.scatter(x, y)
plt.plot(np.unique(x), np.poly1d(np.polyfit(x, y, 1))(np.unique(x)), color='red')
plt.title('散点图和回归线 (相关系数 = {:.2f})'.format(corr_coef))
plt.xlabel('x')
plt.ylabel('y')
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m96XDbQC-1679635345461)(output_83_0.png)]

运行上述代码,可以看到散点图和回归线。尽管回归线斜率接近于0,但由于样本较小,相关系数仍然可能会接近于1,但它们之间并没有明显的因果关系,这说明两个变量之间存在伪回归关系。

3.什么是白噪声?

白噪声序列是一种非常特殊的随机序列,它具有以下几个特点:

  • 1.平均值为0:即序列的期望值为0。

  • 2.方差为常数:即序列中每个值的方差相等。

  • 3.自协方差为0:即序列中任意两个不同时间点的值之间不存在相关性。

在Python中,我们可以用随机函数生成一个符合白噪声特征的序列,例如使用 numpy 库的 random 模块中的 normal() 函数生成一个均值为0,方差为1的白噪声序列,代码如下:

import numpy as np

# 生成100个符合标准正态分布的随机数
noise = np.random.normal(0, 1, 100)

print(noise)
[-0.13348867  1.98656511 -1.27942616 -1.34020918  0.35460205 -0.21237329
 -1.77459599 -0.31222966 -0.71065577  1.1311286  -0.62125177  1.05061465
  0.4597817  -0.20633091  0.02117183  0.42865874 -2.30803851  0.32706841
 -0.37911961  1.79791937 -0.69126896  1.14256392 -2.51492462  0.81462501
  0.27610275 -0.24701649 -0.12088931 -0.26056059  0.42300321 -0.13424856
 -1.78773771 -0.18581086  2.23472174  0.0468462   0.29078795 -0.43805451
  0.17405447  0.17794556 -0.26120192  0.8632634  -0.92307796 -0.13019521
  0.50505375 -0.26700418 -1.22387965  0.55826422 -0.98216096 -0.44730816
 -0.82814759 -0.11072841 -0.42938597 -0.47458987  0.68097893  1.7626089
 -0.35751421  0.52265517 -0.35541349  0.09894225  1.12775134  0.05029324
 -0.81554735 -0.72992661 -0.61674643 -0.01330422  0.85801145 -1.35879684
 -1.03728917 -0.92454121 -1.74940542  1.32592268 -0.03637864  1.90077932
 -1.42433368  1.29418231 -0.70164853 -0.40736969 -0.98896446 -0.94986386
 -1.32374541  0.21633296 -1.31420103 -0.24180187 -0.00920154  0.66661069
  0.10039172  0.32132583  0.51441156 -0.01725087  0.36334792 -0.97972019
 -0.77547043  1.89751081 -0.01173421 -0.71050067  1.3798799  -0.15684261
 -0.64649103 -1.44899155  0.77949187 -1.08630091]

在时间序列分析中,检验一个序列是否为白噪声序列通常用于模型诊断和模型优化的过程中。如果一个时间序列被判断为白噪声序列,意味着序列中的每个观测值都是独立的、随机的,不存在任何结构性的模式,因此可以被看作是一个“随机噪声”,不包含任何有用的信息,也不能用来预测未来的值。在这种情况下,我们需要重新检查模型是否存在问题,以便更好地对序列进行建模。

同时,对于某些时间序列分析的应用场景,如金融、气象、环境等领域的数据分析中,往往需要预测未来的值。如果我们判断一个时间序列不是白噪声序列,那么我们可以使用时间序列分析中的方法来建立模型,并利用该模型进行未来值的预测。

反过来想,时序预测中的残差被认为是时间序列中没有被模型捕捉到的信息,因此它们应该是随机的,没有任何模式。如果残差是白噪声,那么模型预测的准确性就可以得到进一步提高。因此,检验预测模型的残差是否为白噪声也是时序预测中的一个重要步骤。

综上所述,检验一个序列是否为白噪声序列对于时间序列分析和预测都是非常重要的一步。

4.怎么判断一个序列是白噪声序列?

判断一个序列是否为白噪声序列,通常可以使用下面的方法:

  • 1.检查序列的均值和方差是否不随时间而变化,即序列的均值和方差应该保持稳定;

  • 2.检查序列的自相关系数是否在阈值范围内,即序列中各时刻的观测值之间是否存在任何相关性。可以使用自相关函数(ACF)和偏自相关函数(PACF)来检查相关性;

  • 3.进行Ljung-Box检验或是Box-Pierce检验,这两种检验方法都是用来检验序列是否具有自相关性的统计检验方法。若检验结果中p值大于某一显著性水平(如0.05),则认为序列为白噪声序列。

在Python中,可以使用一些统计工具包如statsmodels或者scipy来进行白噪声检验。其中,最常用的是Ljung-Box检验和Jarque-Bera检验。

import numpy as np
from statsmodels.stats.diagnostic import acorr_ljungbox

# 生成一个随机白噪声序列
noise = np.random.randn(1000)

# 检验序列是否为白噪声序列
lbvalue, pvalue = acorr_ljungbox(noise, lags=10)
print('Ljung-Box test results: ')
print('p-value: ', pvalue)

Ljung-Box test results:
p-value: [0.34092681 0.42667528 0.07680586 0.10045797 0.12028975 0.15856346
0.20392486 0.26115473 0.28644898 0.06047993]

这里使用numpy库生成了一个长度为1000的随机白噪声序列,然后使用statsmodels库中的acorr_ljungbox()函数进行Ljung-Box检验,检验序列是否存在自相关性。函数的lags参数指定了要检验的滞后阶数,此处设为10。检验结果输出了p-value,如果p-value越小,则越不可能是白噪声序列。如果p-value很小,则可以判断该序列不是白噪声序列。

acorr_ljungbox()函数的返回值包括两个数组,其中lbvalue是Ljung-Box检验的统计量数组,pvalue是对应的p-value值数组,两个数组的长度都是设定的滞后阶数。

对于p-value数组,如果一个值小于显著性水平(如0.05),则可以拒绝序列是白噪声序列的原假设(即序列不存在自相关性)。在这种情况下,可以认为序列存在自相关性,不是白噪声序列。如果所有p-value的值都大于显著性水平,则不能拒绝原假设,可以认为序列是白噪声序列。在这个例子中,pvalue数组中有10个元素,对应了从滞后1到10的Ljung-Box检验的p-value值,所有值都大于0.05,可以判断该序列是白噪声序列。

需要注意的是,Ljung-Box检验并不能保证判断白噪声序列的正确性,它只是一种检验方法,也存在一定的局限性。因此,在进行时间序列分析时,建议使用多种方法和技术来对序列进行判断和分析。

在时间序列分析中,检验一个序列是否为白噪声序列通常用于模型诊断和模型优化的过程中。如果一个时间序列被判断为白噪声序列,意味着序列中的每个观测值都是独立的、随机的,不存在任何结构性的模式,因此可以被看作是一个“随机噪声”,不包含任何有用的信息,也不能用来预测未来的值。在这种情况下,我们需要重新检查模型是否存在问题,以便更好地对序列进行建模。

同时,对于某些时间序列分析的应用场景,如金融、气象、环境等领域的数据分析中,往往需要预测未来的值。如果我们判断一个时间序列不是白噪声序列,那么我们可以使用时间序列分析中的方法来建立模型,并利用该模型进行未来值的预测。

反过来想,时序预测中的残差被认为是时间序列中没有被模型捕捉到的信息,因此它们应该是随机的,没有任何模式。如果残差是白噪声,那么模型预测的准确性就可以得到进一步提高。因此,检验预测模型的残差是否为白噪声也是时序预测中的一个重要步骤。

综上所述,检验一个序列是否为白噪声序列对于时间序列分析和预测都是非常重要的一步。

5.时间序列数据做预测的前提假设是什么?

时间序列数据做预测的前提假设是其具有平稳性。可以用数学符号表示为:

Y t = μ t + ϵ t Y_t=\mu_t + \epsilon_t Yt=μt+ϵt

其中, Y t Y_t Yt 表示在时刻 t t t 的时间序列观测值, μ t \mu_t μt 表示在时刻 t t t 的时间序列的均值, ϵ t \epsilon_t ϵt 表示在时刻 t t t 的时间序列的随机误差,满足以下条件:

  • 1. μ t \mu_t μt 是常数;
  • 2. ϵ t \epsilon_t ϵt 满足零均值、同方差、互不相关的条件。

即:

E ( Y t ) = μ t E(Y_t)=\mu_t E(Yt)=μt

V a r ( ϵ t ) = σ 2 Var(\epsilon_t) = \sigma^2 Var(ϵt)=σ2

C o v ( ϵ t , ϵ t − h ) = 0 , h ≠ 0 Cov(\epsilon_t, \epsilon_{t-h}) = 0, h \neq 0 Cov(ϵt,ϵth)=0,h=0

其中, E ( ⋅ ) E(\cdot) E() 表示期望, V a r ( ⋅ ) Var(\cdot) Var() 表示方差, C o v ( ⋅ ) Cov(\cdot) Cov() 表示协方差。

6.预测时间序列为什么要求数据满足平稳性?

时间序列的平稳性(stationary process)是时间序列经济计量分析中非常重要的问题。时间序列的平稳性是指时间序列的统计规律不会随着时间的推移而发生变化。即时间序列数据的随机过程特征不随时间变化而变化。

非平稳序列的统计特性(如均值、方差、自相关等)会随时间发生变化,因此难以建立稳定的预测模型。用平稳时间序列进行计量分析,估计方法和假设检验才有效。

假设有一个非平稳的时间序列,我们首先画出它的时序图和自相关函数图:

# 非平稳时间序列
np.random.seed(1)
x = np.cumsum(np.random.randn(1000))

# 时序图
plt.plot(x)
plt.title('非平稳时间序列')
plt.show()

# 自相关函数图
plot_acf(x, lags=50)
plt.title('非平稳时间序列的自相关图')
plt.show()

在这里插入图片描述

可以看出,该时间序列的均值和方差都随时间变化,且自相关函数衰减缓慢。如果我们尝试用AR模型进行预测,得到的结果如下:

# 拆分训练集和测试集
train_size = int(len(x) * 0.8)
train, test = x[:train_size], x[train_size:]

# 训练AR模型
model = AutoReg(train, lags=10)
model_fit = model.fit()
print('系数: %s' % model_fit.params)

# 预测测试集
predictions = model_fit.predict(start=len(train), end=len(train)+len(test)-1, dynamic=False)

# 计算均方误差
mse = mean_squared_error(test, predictions)
print('测试集 MSE: %.3f' % mse)

# 绘制预测结果
plt.plot(test)
plt.plot(predictions, color='red')
plt.title('AR模型预测非平稳数据')
plt.show()

输出:
系数: [ 0.17690348 0.97875339 0.03639093 -0.07003079 0.08896836 -0.08008059
0.05126822 -0.06686572 0.01508418 0.02153707 0.01843534]
测试集 MSE: 170.781

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G9ewlzYL-1679635345462)(output_95_1.png)]

可以看到,用AR模型进行预测的结果非常糟糕,均方误差很高:170.781。
这是因为AR模型要求序列是平稳的,而这个非平稳序列的统计特性随时间变化太快,这意味着过去的统计性质可能不再适用于未来,所以AR模型无法捕捉到其趋势和周期性。

接下来我们生成一个弱平稳序列,利用时间序列模型进行预测,然后查看其均方误差。

# Generate a weakly stationary time series
np.random.seed(1)
stationary_ts = np.random.randn(1000)

# Plot the time series and ACF
fig, ax = plt.subplots(2, 1, figsize=(12, 6))
ax[0].plot(stationary_ts)
ax[0].set_title('弱平稳时间序列')
plot_acf(stationary_ts, ax=ax[1])
plt.show()

在这里插入图片描述

# 拆分训练集和测试集
train_size = int(len(stationary_ts) * 0.8)
train, test = stationary_ts[:train_size], stationary_ts[train_size:]

# 训练AR模型
model = AutoReg(train, lags=1)
model_fit = model.fit()
print('系数: %s' % model_fit.params)

# 预测测试集
predictions = model_fit.predict(start=len(train), end=len(train)+len(test)-1, dynamic=False)

# 计算均方误差
mse = mean_squared_error(test, predictions)
print('测试集 MSE: %.3f' % mse)

# 绘制预测结果
plt.plot(test)
plt.plot(predictions, color='red')
plt.title('AR模型预测弱平稳数据')
plt.show()
系数: [ 0.02866045 -0.0306329 ]
测试集 MSE: 0.819

在这里插入图片描述

7.怎样检测时序数据是否满足平稳性?

时序数据的平稳性指的是数据在时间上的统计特性不随时间而变化。具体来说,平稳的时序数据具有以下三个特点:

  • 1.均值不随时间变化:即在任何时间点,数据的均值都保持不变。

  • 2.方差不随时间变化:即在任何时间点,数据的方差都保持不变。

  • 3.自相关不随时间变化:即在任何时间点,数据的自相关性都保持不变。

因此,要检测时序数据是否满足平稳性,可以使用滚动统计量的方式来验证时序数据的平稳性,具体实现步骤如下:

  • 1.对于给定的时序数据,将数据按照时间顺序排序。

  • 2.定义一个固定大小的窗口,例如,可以选择窗口大小为1000。

  • 3.从数据的第一个时间点开始,以步长为1的方式滑动窗口,每次计算窗口内的均值、方差和自相关系数。

如果在所有窗口内,均值、方差和自相关系数都保持不变,则可以认为该时序数据是平稳的。

下面是用Python实现这个方法的示例代码:

import numpy as np
import pandas as pd

# 生成示例数据
np.random.seed(123)
data = pd.Series(np.random.randn(10000).cumsum())

# 定义窗口大小
window_size = 1000

# 滑动窗口计算均值、方差和自相关系数
means = []
variances = []
autocorrelations = []
for i in range(len(data) - window_size):
    window = data[i:i+window_size]
    means.append(window.mean())
    variances.append(window.var())
    autocorrelations.append(window.autocorr())

# 判断均值、方差和自相关系数是否保持不变
if np.allclose(means, means[0]) and np.allclose(variances, variances[0]) and np.allclose(autocorrelations, autocorrelations[0]):
    print("该时序数据是平稳的")
else:
    print("该时序数据不是平稳的")

> 输出:该时序数据不是平稳的

需要注意的是,滑动窗口的大小和步长可以根据具体的数据情况进行调整。如果窗口大小太小,可能无法捕捉到数据的长期趋势;如果窗口大小太大,可能会导致计算量过大,影响计算效率。步长的选择可以根据数据的时间间隔来决定,一般建议选择时间间隔的一半作为步长。

另外,进行平稳性检验常用的统计量有哪些,分别展示其python实现。进行平稳性检验的常用统计量包括:

  • 1.ADF检验统计量(Augmented Dickey-Fuller Test Statistics)
  • 2.KPSS检验统计量(Kwiatkowski-Phillips-Schmidt-Shin Test Statistics)

下面分别展示它们的Python实现:

# ADF检验统计量
from statsmodels.tsa.stattools import adfuller

result = adfuller(df)
print('ADF检验统计量:', result[0])
print('p值:', result[1])

# KPSS检验统计量
from statsmodels.tsa.stattools import kpss
result = kpss(df)
print('KPSS检验统计量:', result[0])
print('p值:', result[1])

ADF检验统计量: -1.8399140240422605
p值: 0.36083316271754495
KPSS检验统计量: 1.3521689909278918
p值: 0.01

8.不满足平稳性应该怎么办?

如果时序数据不满足平稳性,通常有以下几种处理方式:

  • 1.差分:差分是一种常见的处理非平稳性时序数据的方法,可以通过对时序数据进行一阶或高阶差分来使其平稳。差分操作可以通过pandas库中的.diff()函数来实现。

  • 2.对数变换:对数变换可以将时序数据中的大幅度波动变成较小的波动,从而使其更接近于平稳。对数变换可以通过numpy库中的log()函数来实现。

  • 3.移动平均法:移动平均法是一种平滑时序数据的方法,可以通过计算时序数据的滑动平均值来降低噪声的影响。移动平均法可以通过pandas库中的rolling()函数来实现。

需要注意的是,不同的时序数据可能需要不同的处理方法,处理方式的选择应该基于对数据的分析和理解。此外,处理时序数据可能会对数据的信息损失和预测精度产生一定的影响,因此需要谨慎选择处理方法,并进行充分的评估和验证。

下面给出针对时序数据不满足平稳性时常用的四种处理方式的Python代码示例:

差分

当时序数据不满足平稳性时,差分是一种常见的处理方法,可以通过对时序数据进行一阶或高阶差分来使其平稳。下面是一些使用Python进行差分操作的示例代码:

import pandas as pd

# 生成示例数据
data = pd.Series([1, 3, 5, 7, 9, 11, 13, 15])

# 一阶差分
diff_1 = data.diff()

# 二阶差分
diff_2 = data.diff().diff()

print("原始数据:", data.values)
print("一阶差分:", diff_1.dropna().values)
print("二阶差分:", diff_2.dropna().values)

原始数据: [ 1  3  5  7  9 11 13 15]
一阶差分: [2. 2. 2. 2. 2. 2. 2.]
二阶差分: [0. 0. 0. 0. 0. 0.]

上述代码中,首先生成了一个简单的示例数据,包含8个整数。然后,通过pandas库中的.diff()函数,对数据进行一阶和二阶差分操作,分别保存到了diff_1和diff_2两个变量中。最后,使用dropna()函数去除了差分操作后产生的NaN值,并打印了原始数据和差分后的数据。

需要注意的是,差分操作可能会使得数据的时间顺序发生改变,因此在使用差分操作进行处理时,需要根据实际情况进行调整。另外,差分操作可能会导致数据的信息损失,因此需要在进行差分操作前进行充分的分析和评估。

对数变换

当时序数据不满足平稳性时,对数变换可以通过对时序数据进行对数变换来使其更接近于平稳。下面是一些使用Python进行对数变换操作的示例代码:

import pandas as pd
import numpy as np

# 生成示例数据
data = pd.Series([1, 10, 100, 1000, 10000])

# 对数变换
log_data = np.log(data)

print("原始数据:", data.values)
print("对数变换后的数据:", log_data.values)

原始数据: [    1    10   100  1000 10000]
对数变换后的数据: [0.         2.30258509 4.60517019 6.90775528 9.21034037]

上述代码中,首先生成了一个简单的示例数据,包含5个整数。然后,通过numpy库中的log()函数,对数据进行对数变换操作,并将结果保存到log_data变量中。最后,打印了原始数据和对数变换后的数据。

对数变换可以用于调整数据的范围和分布,使得数据更符合模型的假设,并提高模型的预测能力。在实际应用中,一些变量适合采用对数变换,下面是几个常见的例子:

  • 1.金融领域中的收益率:金融领域中经常使用收益率来衡量投资的回报。由于收益率可以取负值,而且通常具有高峰厚尾的分布特征,因此可以使用对数变换来调整其分布,并使其更接近于正态分布。

  • 2.生物领域中的基因表达量:生物领域中的基因表达量通常具有指数分布特征,因此可以使用对数变换来调整其分布,并使其更接近于正态分布。

  • 3.经济领域中的收入和财富:经济领域中的收入和财富通常具有高度的不平等性,并且通常呈现出高峰厚尾的分布特征。因此可以使用对数变换来调整其分布,并使其更接近于正态分布。

需要注意的是,对数变换后的变量仍然具有实际意义。例如,对数变换后的收益率仍然可以用来衡量投资的回报,对数变换后的基因表达量仍然可以用来分析基因的表达水平。

需要注意的是,对数变换可能会使得数据的范围和分布发生改变,因此在使用对数变换进行处理时,需要根据实际情况进行调整。另外,对数变换也可能会导致数据的信息损失,因此需要在进行变换操作前进行充分的分析和评估。

移动平均法

当时序数据不满足平稳性时,可以通过移动平均法对时序数据进行移动平均操作来使其平稳。下面是一些使用Python进行移动平均操作的示例代码:

import pandas as pd

# 生成示例数据
data = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

# 移动平均法
window_size = 3
ma_data = data.rolling(window_size).mean()

print("原始数据:", data.values)
print("移动平均后的数据:", ma_data.dropna().values)

原始数据: [ 1  2  3  4  5  6  7  8  9 10]
移动平均后的数据: [2. 3. 4. 5. 6. 7. 8. 9.]

上述代码中,首先生成了一个简单的示例数据,包含10个整数。然后,通过pandas库中的.rolling()函数和.mean()函数,对数据进行了移动平均操作,并将结果保存到ma_data变量中。其中,window_size参数表示移动窗口的大小,这里设置为3。最后,使用dropna()函数去除了移动平均操作后产生的NaN值,并打印了原始数据和移动平均后的数据。

需要注意的是,移动平均法可能会使得数据的时间顺序发生改变,因此在使用移动平均法进行处理时,需要根据实际情况进行调整。另外,移动平均法也可能会导致数据的信息损失,因此需要在进行移动平均操作前进行充分的分析和评估。

9.满足平稳性后有哪些可供选择的时间序列预测模型?

在满足平稳性的前提下,可以选择以下几种时间序列预测模型:

  • 1.AR模型(自回归模型):该模型基于时间序列过去时刻的观测值,预测未来时刻的观测值。AR模型适用于没有明显趋势和季节性的时间序列数据。AR模型的表达式:

y t = α + ∑ i = 1 p β i y t − i + ϵ t y_t = \alpha + \sum_{i=1}^p \beta_i y_{t-i} + \epsilon_t yt=α+i=1pβiyti+ϵt

其中, y t y_t yt表示时间 t t t的值, p p p表示使用 p p p个时间点的值作为自变量, α \alpha α β i \beta_i βi是系数, ϵ t \epsilon_t ϵt是误差项。

  • 2.MA模型(移动平均模型):该模型基于时间序列过去时刻的误差项,预测未来时刻的观测值。MA模型适用于没有明显趋势和季节性的时间序列数据。MA模型表达式:

y t = μ + ∑ i = 1 q θ i ϵ t − i + ϵ t y_t = \mu + \sum_{i=1}^q \theta_i \epsilon_{t-i} + \epsilon_t yt=μ+i=1qθiϵti+ϵt

其中, y t y_t yt表示时间 t t t的值, q q q表示使用 q q q个时间点的误差作为自变量, μ \mu μ θ i \theta_i θi是系数, ϵ t \epsilon_t ϵt是误差项。

  • 3.ARMA模型(自回归移动平均模型):该模型结合了AR和MA模型的特点,既考虑了时间序列过去时刻的观测值,也考虑了误差项,因此可以更好地处理具有一定趋势和季节性的时间序列数据。ARMA模型表达式:

y t = α + ∑ i = 1 p β i y t − i + ∑ i = 1 q θ i ϵ t − i + ϵ t y_t = \alpha + \sum_{i=1}^p \beta_i y_{t-i} + \sum_{i=1}^q \theta_i \epsilon_{t-i} + \epsilon_t yt=α+i=1pβiyti+i=1qθiϵti+ϵt

其中, y t y_t yt表示时间 t t t的值, p p p表示使用 p p p个时间点的值作为自回归项, q q q表示使用 q q q个时间点的误差作为移动平均项, α \alpha α β i \beta_i βi θ i \theta_i θi是系数, ϵ t \epsilon_t ϵt是误差项。

  • 4.ARIMA模型(差分自回归移动平均模型):该模型在ARMA模型的基础上,对非平稳时间序列进行差分处理,使其转化为平稳时间序列,然后再建立ARMA模型进行预测。ARIMA模型适用于具有明显趋势和季节性的时间序列数据。ARIMA模型表达式:

y ′ t = α + ∑ i = 1 p β i y ′ t − i + ∑ i = 1 q θ i ϵ t − i + ϵ t y′_t = \alpha + \sum_{i=1}^p \beta_i y′_{t-i} + \sum_{i=1}^q \theta_i \epsilon_{t-i} + \epsilon_t yt=α+i=1pβiyti+i=1qθiϵti+ϵt

其中, y t ′ y'_t yt表示时间 t t t的差分值(即原始值减去 t − 1 t-1 t1时刻的值), p p p表示使用 p p p个时间点的差分值作为自回归项, q q q表示使用 q q q个时间点的误差作为移动平均项, α \alpha α β i \beta_i βi θ i \theta_i θi是系数, ϵ t \epsilon_t ϵt是误差项。

from statsmodels.tsa.ar_model import AutoReg
from random import random

# 创建模拟数据
data = [x + random() for x in range(1, 100)]

# 建立AR模型,参数p=2表示使用2阶移动平均
model_AR = ARIMA(data, order=(2, 0, 0))
model_AR_fit = model_AR.fit()
print(f'AR模型的回归系数:{model_AR_fit.params}')

# 建立MA模型,参数q=1表示使用1阶滑动平均
model_MA = ARIMA(data, order=(0, 0, 1))
model_MA_fit = model_MA.fit()
print(f'MA模型的回归系数:{model_MA_fit.params}')

# 建立ARMA模型,参数p=2,q=1表示使用2阶自回归和1阶滑动平均
model_ARMA = ARIMA(data, order=(2, 0, 1))
model_ARMA_fit = model_ARMA.fit()
print(f'ARMA模型的回归系数:{model_ARMA_fit.params}')

# 建立ARIMA模型,参数p=2,d=1,q=1表示使用2阶自回归,1阶差分,1阶滑动平均
model_ARIMA = ARIMA(data, order=(2, 1, 1))
model_ARIMA_fit = model_ARIMA.fit()
print(f'ARIMA模型的回归系数:{model_ARIMA_fit.params}')

AR模型的回归系数:[50.42572253 1.76718167 -0.76764933 0.46487344]
MA模型的回归系数:[ 50.51767869 0.99940811 211.00731768]
ARMA模型的回归系数:[50.50667983 0.1222451 0.87725561 0.9936276 1.09337922]
ARIMA模型的回归系数:[ 0.45173062 0.54826921 -0.9979595 0.12752159]

10.自回归参数和移动平均的参数怎么确定?

ARMA模型是由自回归模型AR§和移动平均模型MA(q)组成的,其中p表示自回归模型中过去p个时刻的观测值对当前值的影响,q表示移动平均模型中过去q个时刻的随机误差对当前值的影响。

自回归模型AR§的参数可以通过自相关函数(ACF)和偏自相关函数(PACF)来确定ACF是衡量时间序列与其自身滞后版本之间的相关性,PACF是衡量时间序列与其自身滞后版本之间消除其他滞后版本影响后的相关性。在AR§模型中,ACF的p阶滞后截尾而PACF是有尖峰的。因此,可以使用ACF和PACF来选择自回归模型的阶数p。

移动平均模型MA(q)的参数可以通过自相关函数(ACF)来确定。在MA(q)模型中,ACF的q阶滞后截尾。因此,可以使用ACF来选择移动平均模型的阶数q。

一般来说,为了选择ARMA模型的参数,可以先用自相关函数和偏自相关函数确定AR§模型的参数p,然后使用残差序列来确定MA(q)模型的参数q。可以采用最大似然估计或贝叶斯估计等方法来估计模型的参数值,然后进行模型检验和模型优化。

以已读取的股票数据为例,进行python代码的展示:

import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# 绘制自相关函数(ACF)和偏自相关函数(PACF)图像
plot_acf(df, lags=30)
plot_pacf(df, lags=30)

plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dkcy6BsQ-1679635345464)(output_116_0.png)]
在这里插入图片描述

其中,df为时序数据,lags表示滞后期数。在图像中,蓝色区域代表置信区间,如果自相关函数或偏自相关函数超出置信区间,则表示在该滞后期存在显著自相关性或偏自相关性,可以作为AR§模型中的参数之一。

11.确定参数后怎么基于合适的时序预测模型进行模型的拟合?

在ARMA模型中,自回归(AR)和移动平均(MA)参数的确定通常需要经过以下几个步骤:

检查数据的平稳性:在ARMA模型中,数据需要是平稳的。可以通过观察时间序列图、自相关函数(ACF)和偏自相关函数(PACF)来初步判断数据的平稳性。

确定自回归参数§:通过观察PACF图可以初步确定自回归模型的阶数p,即需要考虑的滞后项数量。PACF图上显著超过置信区间的滞后项可以被认为是显著的自回归系数。

确定移动平均参数(q):通过观察ACF图可以初步确定移动平均模型的阶数q,即需要考虑的滞后项数量。ACF图上显著超过置信区间的滞后项可以被认为是显著的移动平均系数。

拟合ARMA模型:将p和q的值代入ARMA模型,然后使用最大似然估计等方法来拟合模型,

12.拟合好模型后怎样进行预测结果的可视化

在Python中,可以使用matplotlib库来进行预测结果的可视化。下面给出一个简单的示例:

假设我们有一个时间序列数据data,我们使用ARIMA模型进行预测,并将预测结果可视化。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA

# 读取数据
df0 = pd.read_csv('./data/sh601318_processed.csv',index_col='Date')
df = df0[['Close']]
df.index = pd.to_datetime(df.index, format='%Y-%m-%d')

# 拆分训练集和测试集
train_size = int(len(df) * 0.8)
train_data, test_data = df.iloc[:train_size], df.iloc[train_size:]

# 训练ARIMA模型
model = ARIMA(train_data, order=(1, 1, 1))
results = model.fit()

# 进行预测
start = len(train_data)
end = len(train_data) + len(test_data) - 1
predict = results.predict(start=start, end=end, typ='levels')

# 绘制预测结果
plt.plot(test_data.index, test_data, label='True')
plt.plot(test_data.index, predict, label='Predict')
plt.legend()
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ETUU3PXP-1679635345464)(output_120_0.png)]

13.怎样评估预测结果的好坏?

为了评估模型的预测效果,我们需要计算一些常用的评估指标,包括均方误差(Mean Squared Error,MSE)、均方根误差(Root Mean Squared Error,RMSE)、平均绝对误差(Mean Absolute Error,MAE)和平均绝对百分误差(Mean Absolute Percentage Error,MAPE)等。

这些指标的计算公式如下:

M S E = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 MSE = \frac{1}{n} \sum_{i=1}^{n}(y_i - \hat{y}_i)^2 MSE=n1i=1n(yiy^i)2

R M S E = M S E RMSE = \sqrt{MSE} RMSE=MSE

M A E = 1 n ∑ i = 1 n ∣ y i − y ^ i ∣ MAE = \frac{1}{n} \sum_{i=1}^{n}|y_i - \hat{y}_i| MAE=n1i=1nyiy^i

M A P E = 1 n ∑ i = 1 n ∣ y _ i − y ^ i y i ∣ × 100 MAPE = \frac{1}{n} \sum_{i=1}^{n}|\frac{y\_i - \hat{y}_i}{y_i}| \times 100% MAPE=n1i=1nyiy_iy^i×100

其中, y i y_i yi 表示真实值, y ^ i \hat{y}_i y^i 表示预测值, n n n 表示样本数量。

from sklearn.metrics import mean_squared_error, mean_absolute_error
# 计算评估指标
mse = mean_squared_error(test_data.values, predict.values)
rmse = np.sqrt(mse)
mae = mean_absolute_error(test_data.values, predict.values)
mape = np.mean(np.abs((test_data.values - predict.values) / test_data.values)) * 100

# 打印评估指标
print('MSE: %.2f' % mse)
print('RMSE: %.2f' % rmse)
print('MAE: %.2f' % mae)
print('MAPE: %.2f%%' % mape)
MSE: 158.50
RMSE: 12.59
MAE: 11.73
MAPE: 25.80%

http://www.kler.cn/a/2992.html

相关文章:

  • 【C++高并发服务器WebServer】-9:多线程开发
  • thinkphp6+swoole使用rabbitMq队列
  • 代码随想录|动态规划 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组
  • C语言连接Mysql
  • 三天急速通关JavaWeb基础知识:Day 1 后端基础知识
  • 【C++ 真题】P1706 全排列问题
  • 中式教育下的大学生以后会不会被ChatGPT全面取代?
  • GIS开源库GEOS库学习教程(一):编译及示例代码
  • ChatGPT文心一言逻辑大比拼(一)
  • 查看当前API key可以调用哪些Open AI的模型
  • SpringCloud:统一网关Gateway
  • 【Nginx二】——Nginx常用命令 配置文件
  • 微搭低代码实现二维码显示及上传功能
  • 11. C#高级进阶
  • 【jenkins部署】一文弄懂自动打包部署(前后台)
  • 7.避免不必要的渲染
  • SpringCloud微服务技术栈.黑马跟学(五)
  • 2022年亏损超10亿,告别野蛮成长的众安在线急需新“引擎”
  • scala一些函数
  • java调用chatgpt接口,实现专属于自己的人工智能助手
  • 2023面试题汇总二
  • leetcode究极刷题笔记(11~15)
  • NC65 单据控制规则
  • WPF毛笔字实现过程
  • 【剑指offer】旋转数组的最小数字
  • 【算法】手把手学会二分查找