Datawhale数学建模打卡-Task3时间序列与投资模型

一、时间序列的基本概念

时间序列:数据有时间列作为索引;

1.1 建模内容

参数学习:通过模型参数分析序列的特征

预测:基于已知预测未知;包括长期、短期预测两种,其中,预测精度高时,预测周期要求不能太长,长期预测只能用于做趋势预测(难以考虑环境变化与突发事件的影响)。

1.2 描述分解

平稳型时间序列:一个序列的均值、方差和协方差不会随着时间变化

①序列的趋势线是一条水平线

②序列不会某一段波动很大,某一段波动很小

③序列不会某一段分布密集,某一段分布稀疏

分解模型分为:加法模型、乘法模型;

其中,

  • 加法指的是时间序分的组成是相互独立的,四个成分都有相同的量纲。
  • 乘法模型输出部分和趋势项有相同的量纲,季节项和循环项是比例数,不规则变动项为独立随机变量序列,服从正态分布。

(注:也可以把加法与乘法的分解模式进行组合)

#读取名为"Bitcoin.csv"的CSV文件,并将读取的数据存储在变量df中
df=pd.read_csv("Bitcoin.csv")

#从数据框df中提取名为"Bitcoin"的列,并将这个列赋值给变量y。这里y代表因变量,即比特币的价格
y=df.Bitcoin

#将数据框df中的"Date"列转换成日期时间格式。pd.to_datetime函数是Pandas库提供的一个函数,用于将字符串或数值转换为日期时间类型
df.Date=pd.to_datetime(df.Date)

#将"Date"列设置为数据框df的索引。set_index函数用于将一列转换为数据框的索引。参数drop=True表示在设置索引后,原来的"Date"列将从数据框中删除
df=df.set_index(df['Date'],drop=True)

# 使用Matplotlib库创建一个新的图形,并设置图形的大小为宽12英寸,高4英寸
plt.figure(figsize=(12, 4))

#绘制比特币价格的时间序列图。plt.plot函数用于绘制线图,其中df.Bitcoin是y轴的数据,label='Bitcoin'为图例设置标签
plt.plot(df.Bitcoin, label='Bitcoin')

#设置图表的标题为"Bitcoin Time Series"
plt.title('Bitcoin Time Series')

#设置x轴的标签为"Date"
plt.xlabel('Date')

plt.ylabel('Bitcoin')

#显示图例,根据plt.plot中的label参数显示
plt.legend()

plt.show()

1.3 组成部分

长期趋势T:现象在较长时间内持续变化的一种趋势/状态,通常表现为一条光滑曲线趋势线。

季节变动S:由于季节的变化引起的现象发展水平的规则变动,通常表现为周期相对短一些的周期曲线。

循环波动I:在某段时间内,不具严格规则的周期性变动,通常表现为周期更长的周期曲线。

不规则波动C(噪声):由于众多偶然因素对时间序列造成的影响。

1.4 时序数据及其对应时间序列

单变量时序数据

时序预测的数据往往由相对确定的时间戳组成(即,每个样本是一个时间点,如上一节中的月份),每个时间点对应一个标签值,时间是影响该标签唯一的自变量。许多时候,单变量时序数据的时间戳会呈现等间隔的状况,例如每一天一个值、每一分钟一个值等等。在时序预测中,假设样本与样本之间存在相关性(即之前的时间上的指标会影响之后的时间上的指标),利用历史数据预测未来数据走向就是时间序列预测的本质。在单变量时间序列中,时间或时间相关的变量是影响标签变化的众多因子中唯一可以被获得的因子。因此在建模过程中,标签的变化只与时间这一单一变量有关(例如,在上面的左侧图中,销售额只与时间相关)。这种预测的难度往往很大,且精度很低,投入现实使用相对困难。

多变量时序序列

在多变量时间序列中,时间是影响标签变化的因素之一,除了时间之外,往往还有别的决定性因素、或同样重要的因素和时间共同作用、影响着标签。(例如在上面的图中,销售额、广告费用和产品数量都随时间有所增长,但是这三个变量之间的关系并不是一一对应的)。这一类型的预测精度会远远高于单变量时序预测。

1.5 时间序列模型VS传统机器学习模型

1.5.1 单变量时间序列模型

1.5.2 时间序列模型 

在处理时间序列数据时,我们通常使用专门的时间序列模型。尽管时间序列模型和传统的机器学习模型在许多方面都相似,比如他们都通过从历史数据中学习模式进行预测,他们都使用平均绝对误差(MAE)、均方根误差(RMSE)、精确度等来衡量模型的表现,他们都需要将数据集拆分为训练集和测试集。然而,由于时间序列数据的特殊性,时间序列模型在数据结构、特征工程、模型类型以及训练/测试拆分方式等方面和传统的机器学习模型有着明显的区别。理解这些区别和共性是构建有效的时间序列预测模型的关键。

1.6 划分训练集与测试集原则 

1.7 时序模型的训练方式
1.7.1 单步预测
  • 最简单的方式是,将时间数据按照普通回归数据的方式进行训练和预测。即训练集、验证集和测试集是完全分割的三段时间,在训练集上训练、在验证集上调参,在测试集上输出最终预测结果。这种方式被称为“单步预测”。
  • 使用历史数据来预测未来的一个时间步的值。这个“步”可以是任意时间单位,比如分钟、小时、天、月,等等。具体来说,我们只预测未来一个时间步长(例如,下一个小时、下一天、下一年等)的值,而不考虑其后的情况。例如:

        该方法执行较为简单,但训练难度较大,一个模型需要学习多种规律。 

1.7.2 多步预测

多步预测指的是使用历史数据来预测未来多个时间步的值。与单步预测只预测未来一个时间步长的值不同,多步预测将预测范围扩展到了未来多个时间步长。例如:

将预测的值作为真实值加入到训练集中再对下一个单位时间进行预测,这样累加可以让训练数据的时间点与测试数据的时间点尽量接近。缺陷也是很明显的。多步预测中可能会导致误差累加,如果在最开始预测时就存在很大的误差,那预测效果会变得越来越差且无法挽回。

1.7.3 逐点预测与分布预测
  • 逐点预测是指在每一个特定的未来时间点,预测一个最可能的值。逐点预测是我们最常见的预测形式,例如在天气预测中,我们可能会预测明天的最高气温为27度,这就是一个逐点预测。在金融市场中,我们可能会预测明天的股票价格为$150,这也是逐点预测的一种应用
  • 分布预测则是预测一个未来时间点的所有可能值的概率分布。相比于逐点预测,分布预测提供了更多的信息,包括预测值的不确定性和风险。例如,对于明天的天气,我们不仅预测最高温度可能为27度,还预测它可能在25-29度之间的概率为90%,可能在23-31度之间的概率为95%,这样的预测就是分布预测。在金融市场中,我们可能会预测明天的股票价格在$145-$155的概率为80%,在$140-$160的概率为90%,这也是分布预测的一种应用。

总的来说,逐点预测为我们提供了一种精确的预测值,而分布预测则给出了更多关于预测不确定性和风险的信息。

1.8 时序任务分类

1.8.1 单变量时间序列分析中,预测的数据要求

        预测是时间序列分析的最常见任务,主要目标是利用过去的数据来预测未来的数据。

  1. 数据样本必须遵循时间顺序排列
  2. 各个样本之间的时间间隔必须保持一致
  3. 数据样本之间存在相互关联性
  4. 过去的样本数据将影响未来的预测值

这类预测要学习的是过去的值、要预测的是“下一个样本”的值,并不关心特征。在实际中,我们使用规则+统计学模型来完成这类预测,但只要遵守“过去预测未来”的铁律,我们也可以使用机器学习模型+多步预测等方式完成Forecasting。

1.8.2 时序有监督学习

时序有监督学习包括时间序列回归时间序列分类两种有监督学习方法(Time Series Regression/ Time Series Classification),指的是在多变量时间序列上,基于时间或时间相关的数据,完成回归或分类任务,这类任务对样本与样本之间的时间顺序、相关等都没有要求、反而更关注特征之间的关系,因此这类任务要求:

  • 数据中必须存在除时间之外的其他特征,且特征越多越好
  • 可以完成“去时序化”处理,将时序数据彻底变为一般机器学习数据

这一类任务是学习特征值、预测标签值,并不关心样本。

1.9 时序算法总结

二、移动平均法与指数平滑法

2.1 移动平均法

2.1.1 基础概念

        移动平均法是用一组最近的实际数据值来预测未来时间序列的一种常用方法。移动平均法适用于短期预测。当序列需求既不快速增长也不快速下降,且不存在季节性因素时,移动平均法能有效地消除预测中的随机波动,是非常有用的。移动平均法根据预测时使用的各元素的权重不同,可以分为:简单移动平均和加权移动平均。

        移动平均法是一种简单平滑预测技术,它的基本思想是:根据时间序列资料、逐项推移,依次计算包含一定项数的序列平均值,以反映长期趋势的方法。因此,当时间序列的数值由于受周期变动和随机波动的影响,起伏较大,不易显示出事件的发展趋势时,使用移动平均法可以消除这些因素的影响,显示出事件的发展方向与趋势(即趋势线),然后依趋势线分析预测序列的长期趋势。

 注意:

①对于简单移动平均的各元素权重都相等,而加权移动平均给固定跨越期限内的每个变量值以不同的权重。其原理是:历史各期产品需求的数据信息对预测未来期内的需求量的作用是不一样的。除了以n为周期的周期性变化外,远离目标期的变量值的影响力相对较低,故应给予较低的权重。

②时间序列中如果出现明显的直线型或曲线型趋势,需要先把这个趋势成分分离出来以后才方便分析。无论是上面提到的二次移动平均还是趋势移动平均都是为了对这个直线型大趋势或曲线型大趋势做拟合,将其分离出来以后剩下的序列才更接近平稳。平稳序列的分析永远比非平稳的序列分析方便。

1、 加大移动平均法的期数(即加大n值)会使平滑波动效果更好,但会使预测值对数据实际变动更不敏感;

2、 移动平均值并不能总是很好地反映出趋势。由于是平均值,预测值总是停留在过去的水平上而无法预计会导致将来更高或更低的波动;

3、 移动平均法要由大量的过去数据的记录。

import numpy as np
#将之前从CSV文件中提取的y(比特币价格)转换为NumPy数组,NumPy数组在数值计算上比Pandas的Series更高效
y=np.array(y)

def MoveAverage(y,N):
#创建一个名为Mt的列表,初始化为N个y的第一个元素的值
    Mt=[y[0]]*N
    for i in range(N+1,len(y)+2):
#对于当前索引i,计算从y数组中索引i-N-1到i-1的子数组的平均值,并将结果赋值给变量M
#注意这里减去1是因为Python的切片是左闭右开区间
        M=y[i-N-1:i-1].mean()
#将计算得到的移动平均值M添加到列表Mt的末尾
        Mt.append(M)
    return Mt
yt3=MoveAverage(y, 30)
yt5=MoveAverage(y, 80)
import matplotlib.pyplot as plt
plt.plot(y,label='y')
plt.plot(yt3,label='yt30')
plt.plot(yt5,label='yt80')
plt.legend()
plt.show()

2.2 指数平滑法

指数平滑法是在移动平均法基础上发展起来的一种时间序列分析预测法,它是通过计算指数平滑值,配合一定的时间序列预测模型对现象的未来进行预测。其原理是任一期的指数平滑值都是本期实际观察值与前一期指数平滑值的加权平均。

import matplotlib.pyplot as plt
 
 
# 一次指数平滑预测
def es1(list3, t, a):
    if t == 0:
        return list3[0]  # 初始的平滑值取实际值
 
    return a * list3[t - 1] + (1 - a) * es1(list3, t - 1, a)  # 递归调用 t-1 → 12
 
 
# 二次指数平滑预测
def es2(list3, t, a):
    if t == 0:
        return list3[0]
 
    return (a * es2(list3, t - 1, a) + (1 - a) * list3[t - 1])
 
 
def answer3(list2):
    # 指数平滑法
    a = 0.8  # 平滑常数
    listES = []  # 指数平滑值的列表
    for i in range(len(list2)):
        if i == 0:
            listES.append(list2[i])
            continue
        s = a * list2[i] + (1 - a) * listES[-1]
        listES.append(s)
    print("指数平滑值的列表:{}".format(listES))
 
    # 画图
    plt.scatter(list(range(len(listES))), listES)
    plt.show()
 
    # 一次指数平滑预测
    t = len(list2)  # 预测的时期 13
    x = es1(list2, t, a)
    print("下一个数的一次指数平滑预测:{}".format(x))
 
    # 二次指数平滑预测
    m = 3  # 预测的值为之后的第m个
    yt = es2(list2, t - 1, a)
    ytm = listES[t - 2]
    esm = ((2 * ytm - yt) + m * (ytm - yt) * a / (1 - a))
    print("之后的第{}个数的二次指数平滑预测:{}".format(m, esm))
 
 
if __name__ == '__main__':
    list1 = [1, 2, 4, 5, 6, 8, 10, 12, 14, 16, 19, 24, 29]  # 13个
    n = 3  # 移动平均期数
 
    answer3(list1)  # 指数平滑法
 

三、ARIMA系列模型

时间序列建模基本步骤
  1. 获取被观测系统时间序列数据。

  2. 对数据进行绘图,观测是否为平稳时间序列;对于非平稳时间序列要先进行阶差分运算,化为平稳时间序列。

  3. 经过第二步处理,已经得到平稳时间序列。要对平稳时间序列分别求得其自相关系数ACF 和偏自相关系数PACF ,通过对自相关图和偏自相关图的分析,得到最佳的阶层和阶数。

  4. 由以上得到ARIMA模型,然后开始对得到的模型进行模型检验。

3.1 AR模型

①概念:全称为自回归模型(Autoregressive model),是一种被广泛用于分析时间序列数据的统计模型。在统计学中,一个自回归模型的形式是描述某个变量与其过去值的关系的,是统计上一种处理时间序列的方法,用同一变数例如x的之前各期,亦即x1至x t−1​来预测本期xt​的表现,并假设它们为线性关系。该模型描述了当前值与历史值之间的相关关系,用变量自身的历史数据对当前数据进行预测。

②要求:

AR模型相信:一个时间点上的标签值一定是依赖于之前的时间点上的标签值而存在的。所以有两个重要的假设:

  • 时序依赖性:在AR模型中,我们假设不同时间点的标签值之间存在强相关性。这意味着一个给定时间点的标签值受到其过去的标签值的显著影响。在数学上,这表现为两个时间点的标签值之间的相关系数较大。换言之,过去的信息对预测未来具有重要影响。
  • 时序衰减:另一个基础假设是,两个时间点之间的距离越远,他们之间的关联性越弱。例如,昨天的天气可能对今天的天气影响很大,但三个月前的某一天的天气,对今天的天气的影响就相对微弱。

        在实际运用中,AR模型必须满足弱平稳性的要求,且必须具有自相关性,自相关系数小于0.5则不适用。

自回归模型假设过去的值与未来的值之间存在线性关系。也就是说,它假设你能通过给过去的值加权求和来预测未来的值,这些权重就是模型的参数。

注意:时间序列中自回归的思想在后面也很有用。本质上自己和自己的历史去做回归也不一定局限在线性的模型形式,也可以用多项式去做一个广义的回归,还可以用支持向量机等构建一个机器学习模型。

3.2 MA模型

①概念:MA模型,全称移动平均模型(moving average model),是一种用于分析时间序列数据的统计模型。它描述的是当前时间点的数据与过去噪声的关系。严格定义上来讲:其模型的定义是基于白噪声序列的假设。白噪声是一种特殊的时间序列模型,每个时间点的数据都是独立且服从相同分布的,且具有常数的均值和方差。

②特点:该模型的主要特点是当前的输出(或时间序列值)被视为过去白噪声误差的加权和。

③组成:在MA模型中,通常包括一个常数项,用于表示时间序列的平均水平。这个模型假设时间序列的数据是平稳的,即它们的均值和方差保持不变,并且每个时间点的数据都是独立的。

MA模型的基本思想是:大部分时候时间序列应当是相对稳定的。在稳定的基础上,每个时间点上的标签值受过去一段时间内、不可预料的各种偶然事件影响而波动

  • 均值稳定:时间序列的均值或期望值是恒定的,不随时间变化。这就是公式中的μ项,它对所有时间点都是相同的。这也是为什么会说“时间序列应该是围绕着某个均值上下波动的序列”。在许多实际的时间序列分析中,我们可能需要通过一些预处理步骤(如差分或去趋势)将原始时间序列转换为均值稳定的序列。
  • 方差稳定:时间序列的方差也是恒定的,不随时间变化。换句话说,时间序列的波动程度是一致的,不会在不同的时间点表现出明显的扩大或缩小。在MA模型中,这个特性主要由白噪声项ϵ t来保证,因为白噪声的方差是常数。
  • 无自相关:在理想的MA模型中,不同时间点的观察值之间没有自相关性。这意味着过去的值不能用来预测未来的值,除非你考虑到了白噪声项。这就是为什么会说“每个时间点上的标签值受过去一段时间内、不可预料的各种偶然事件影响而波动”。

④应用:MA模型在信号处理信号处理、谱估计谱估计、金融分析金融分析和时间序列预测时间序列预测等领域有广泛应用。

⑤特征:MA模型的一个重要特征是它的自协方差函数自协方差函数和自相关系数自相关系数表现出特定的模式。自协方差函数在某个滞后阶数后趋于零,表现出q阶截尾的特性,而自相关系数则表现出q阶截尾的特性。这与自回归(AR)模型形成对比,后者的自相关系数表现出拖尾的特性。 在实际应用中,MA模型常与其他模型结合使用,如自回归滑动平均(ARMA)模型和自回归移动平均 (ARIMA)模型,以适应更复杂的时间序列分析需求。

⑥基本假设:

  • 平稳性:MA模型假设时间序列是平稳的。这意味着序列的主要统计属性,如均值和方差,不随时间变化。这个假设强调了序列在长期内保持稳定的行为,而在短期内可能会受到随机因素的影响。
  • 白噪声:MA模型假设存在一个白噪声序列。白噪声是随机误差项,它的均值为0,方差为常数,且各个时间点上的值是相互独立的。这个假设强调了在一段较短的时间内,时间序列的波动可能受到不可预测的随机因素的影响。
  • 线性:MA模型假设时间序列可以被过去的白噪声项的线性组合表示。这就是模型被称为“移动平均”模型的原因,因为它的预测值是过去白噪声的加权平均。
  • 有限历史影响:MA模型假设只有过去的q个白噪声才对当前时间点的值有影响,其中q是模型的阶数。换句话说,过去更久的白噪声对当前值没有直接影响。
  • 标签值的关联性与白噪声的独立性:MA模型假设不同时间点的标签值之间是关联的,这反映了历史标签影响时间序列的长期趋势。而偶然事件在不同时间点上产生的影响(即白噪声)是相互独立的,这反映了在短期内,时间序列的波动可能受到不可预测的随机因素的影响。

⑦建模流程:

 

#使用Python生成MA模型的示例
import numpy as np
import matplotlib.pyplot as plt

# 设置随机数种子以便结果可复现
np.random.seed(0)

# 生成长度为1000的白噪声序列
Z = np.random.normal(size=1000)

# 初始化MA模型的参数
theta = [0.6, 0.4]

# 初始化X
X = np.zeros_like(Z)

# 使用MA(2)模型生成X
for t in range(2, len(Z)):
    X[t] = Z[t] + theta[0]*Z[t-1] + theta[1]*Z[t-2]

# 绘制模拟的时间序列数据
plt.figure(figsize=(14, 6))
plt.plot(X)
plt.title("A Simulated MA(2) Time Series")
plt.show()

'''
在这个例子中,我们创建了一个MA(2)模型,它使用过去两期的白噪声(通过ϵ [ t − 1 ]和ϵ [ t − 2 ] 表示)来生成当前的时间序列数据。
这个模型的参数(theta)定义了过去的白噪声对当前时间序列数据的影响程度。生成的图形展示了一个典型的MA(2)模型的时间序列数据。
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/Lvbaby_/article/details/130943224

'''

3.3 AR模型与MA模型的区别

3.4 ARMA模型和ARIMA模型

3.4.1 ARIMA模型的由来

AR模型,即自回归模型,其优势是对于具有较长历史趋势的数据,AR模型可以捕获这些趋势,并据此进行预测。但是AR模型不能很好地处理某些类型的时间序列数据,例如那些有临时、突发的变化或者噪声较大的数据。AR模型相信“历史决定未来”,因此很大程度上忽略了现实情况的复杂性、也忽略了真正影响标签的因子带来的不可预料的影响。

相反地,MA模型,即移动平均模型,可以更好地处理那些有临时、突发的变化或者噪声较大的时间序列数据。但是对于具有较长历史趋势的数据,MA模型可能无法像AR模型那样捕捉到这些趋势。MA模型相信“时间序列是相对稳定的,时间序列的波动是由偶然因素影响决定的”,但现实中的时间序列很难一直维持“稳定”这一假设。

基于以上两个模型的优缺点,我们引入了ARIMA模型,这是一种结合了AR模型和MA模型优点的模型,可以处理更复杂的时间序列问题。

3.4.2 基本概念

ARIMA模型全称为自回归差分移动平均模型(Autoregressive Integrated Moving Average Model)。ARIMA模型主要由三部分构成,分别为自回归模型(AR)、差分过程(I)和移动平均模型(MA)。

ARIMA模型的基本思想是利用数据本身的历史信息来预测未来。一个时间点上的标签值既受过去一段时间内的标签值影响,也受过去一段时间内的偶然事件的影响,这就是说,ARIMA模型假设:标签值是围绕着时间的大趋势而波动的,其中趋势是受历史标签影响构成的,波动是受一段时间内的偶然事件影响构成的,且大趋势本身不一定是稳定的

简而言之,ARIMA模型就是试图通过数据的自相关性和差分的方式,提取出隐藏在数据背后的时间序列模式,然后用这些模式来预测未来的数据。其中:

  • AR部分用于处理时间序列的自回归部分,它考虑了过去若干时期的观测值对当前值的影响。
  • I部分用于使非平稳时间序列达到平稳,通过一阶或者二阶等差分处理,消除了时间序列中的趋势和季节性因素
  • MA部分用于处理时间序列的移动平均部分,它考虑了过去的预测误差对当前值的影响。
  • 结合这三部分,ARIMA模型既可以捕捉到数据的趋势变化,又可以处理那些有临时、突发的变化或者噪声较大的数据。所以,ARIMA模型在很多时间序列预测问题中都有很好的表现。
3.4.3 ARMA模型

3.4.4 差分详解

差分是一种数学操作,用于计算一组数值序列中相邻数据点的差值。在时间序列分析中,差分常用于将非平稳序列转化为平稳序列,也就是减小或消除时间序列的趋势和季节性变化。

当我们对一个序列进行差分运算,就意味着我们会计算该序列中的不同观测值之间的差异

简单地说,如果我们有一个时间序列Y t,那么该序列的一阶差分就可以定义为

 ①滞后

差分(Differencing):这是一种预处理技术,用于使非平稳时间序列变得平稳。在时间序列中进行一阶差分,就是将每个观察值与其前一步的观察值进行比较,然后取这两个观察值之间的差异。例如,如果我们有一个时间序列x1,x2,x3,...,xn,那么一阶差分序列将是x2 - x1, x3 - x2, ..., xn - xn-1。

滞后差分(Lagged Differencing):这个术语和"差分"非常相似。当我们说"滞后"时,我们是在说比较一个观察值和其"前一步"或"几步前"的观察值。因此,“滞后一阶差分"实际上就是常规的一阶差分,因为我们比较的是每个观察值与其前一步的观察值。如果我们进行的是"滞后k阶差分”,那么我们比较的是每个观察值与其k步前的观察值

n阶差分(n-th Order Differencing):n阶差分是差分的一种更一般的形式。一阶差分是比较每个观察值与其前一步的观察值,二阶差分是对一阶差分序列进行再一次的差分(也就是比较一阶差分序列中的每个值与其前一步的值)。更一般地,n阶差分就是连续进行n次一阶差分。

多步差分(Multi-step Differencing):这个术语可能根据上下文有不同的含义。它可能指的是n阶差分(即进行多次连续的一阶差分)。也可能指的是滞后差分,比如比较每个观察值与其几步前的观察值。

3.4.5 使用差分消除数据波动

这段代码首先创建了一个不平稳的时间序列。然后,它对原始数据、一阶差分数据和二阶差分数据进行了平稳性检验。最后,它画出了原始数据以及一阶和二阶差分数据的图形。

# 导入必要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller

# 创建一个函数来检查数据的平稳性
def test_stationarity(timeseries):
    # 执行Dickey-Fuller测试
    print('Results of Dickey-Fuller Test:')
    dftest = adfuller(timeseries, autolag='AIC')
    dfoutput = pd.Series(dftest[0:4], index=['Test Statistic', 'p-value', '#Lags Used', 'Number of Observations Used'])
    for key, value in dftest[4].items():
        dfoutput['Critical Value (%s)' % key] = value
    print(dfoutput)

# 生成不平稳的时间序列
np.random.seed(0)
n = 100
x = np.cumsum(np.random.randn(n))

# 把它转换成Pandas的DataFrame格式
df = pd.DataFrame(x, columns=['value'])

# 检查原始数据的平稳性
test_stationarity(df['value'])

# 进行一阶差分
df['first_difference'] = df['value'] - df['value'].shift(1)

# 检查一阶差分后的数据的平稳性
test_stationarity(df['first_difference'].dropna())

# 进行二阶差分
df['second_difference'] = df['first_difference'] - df['first_difference'].shift(1)

# 检查二阶差分后的数据的平稳性
test_stationarity(df['second_difference'].dropna())

# 可视化原始数据和差分后的数据
plt.figure(figsize=(12, 6))
plt.plot(df['value'], label='Original')
plt.plot(df['first_difference'], label='1st Order Difference')
plt.plot(df['second_difference'], label='2nd Order Difference')
plt.legend(loc='best')
plt.title('Original and Differenced Time Series')
plt.show()

3.4.6 ARIMA模型建立的基本步骤 
一般步骤

① 首先需要对观测值序列进行平稳性检测,如果不平稳,则对其进行差分运算直到差分后的数据平稳
② 在数据平稳后则对其进行白噪声检验,白噪声是指零均值常方差的随机平稳序列;
③ 如果是平稳非白噪声序列就计算ACF(自相关系数)、PACF(偏自相关系数),进行ARMA等模型识别;
④ 对已识别好的模型,确定模型参数,最后应用预测并进行误差分析。

一般地,对于给定的时间序列 ,平稳序列的建模过程可以用下图中的流程图表示。

其中,白噪声检验也称为纯随机性检验,当数据是纯随机数据时,再对数据进行分析就没有任何意义了,所以拿到数据后最好对数据进行一个纯随机性检验。

# 数据的纯随机性检验函数
acorr_ljungbox(x, lags=None, boxpierce=False, 
               model_df=0, period=None, 
               return_df=True, auto_lag=False)

#主要参数

lags为延迟期数,如果为整数,则是包含在内的延迟期数,如果是一个列表或数组,那么所有时滞都包含在列表中最大的时滞中。

boxpierce为True时表示除开返回LB统计量还会返回Box和Pierce的Q统计量

返回值

lbvalue: (float or array)
测试的统计量

pvalue: (float or array)
基于卡方分布的p统计量

bpvalue: ((optionsal), float or array)
基于 Box-Pierce 的检验的p统计量

bppvalue: ((optional), float or array)
基于卡方分布下的Box-Pierce检验的p统计量

#若p值远小于0.01,因此我们拒绝原假设,认为该时间序列是平稳的。(这里原假设是存在单位根,即时间序列为非平稳的)

def acorr_val(ts):
    '''
    # 白噪声(随机性)检验
    ts: 时间序列数据,Series类型
    返回白噪声检验的P值
    '''
    lbvalue, pvalue = acorr_ljungbox(ts, lags=1)  # 白噪声检验结果
    return lbvalue, pvalue
    
acorr_val(ts_data)

ARIMA模型是统计模型中最常见的一种用来进行时间序列预测的模型,只需要考虑内生变量而无需考虑其他外生变量,但要求序列是平稳序列或者差分后是平稳序列。ARIMA模型包含3个部分,即自回归(AR)、差分(I)和移动平均(MA)三个部分。对其每一个部分,都有其递推公式定义。当差分阶数为0的时候模型退化为ARMA模型。

 ARIMA模型实现

注:

3.5 ARIMA(p,d,q)模型的参数选择

一般来说,ARIMA模型中的d代表的就是这样的差分阶数。当我们在ARIMA模型中设定d等于一个特定的数值时,我们实际上是在告诉模型,我们应用了多少次滞后运算(也就是进行了多少次差分)来使数据变得平稳。这就是为什么在进行ARIMA模型拟合前,我们需要先通过画图或者ADF检验等方式,确定最小的d使得数据平稳。在确定了d之后,我们就可以将d阶差分后的序列代入模型进行拟合。

上面的推导,可以帮助我们理解ARIMA(p, d, q)中的d是如何通过滞后运算与差分建立起来的关系,以及它是如何影响我们的模型的。

在实际使用中,我们经常将多步差分和高阶差分混用,最典型的就是在ARIMA模型建模之前:一般我们会先使用多步差分令数据满足ARIMA模型的基础建模条件,再在ARIMA模型中使用低阶的差分帮助模型更好地建模。例如,先对数据进行12步差分、再在模型中进行1阶差分,这样可以令数据变得平稳的同时、又提取出数据中的周期性,极大地提升模型对数据的拟合精度。

3.6 ARIMA模型与移动平均法、指数平滑法的关系

3.7 ACF和PACF

3.7.1 时序数据的平稳性

当我们说一个时间序列是平稳的,基本上意味着其统计特性(如均值,方差)在时间上是常数或不会随时间变化。平稳性是ARIMA模型所假设的关键特性,因为模型的预测能力在很大程度上取决于这个假设。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 设置随机种子以确保结果可重复
np.random.seed(0)

# 生成平稳时间序列
stationary = np.random.normal(loc=0, scale=1.0, size=1000)
s_ts = pd.Series(stationary)
s_ts.plot()
plt.title('Stationary Time Series')
plt.show()

# 生成非平稳时间序列
non_stationary = np.cumsum(np.random.normal(loc=0, scale=2.0, size=1000)) + 10 * np.sin(np.linspace(-10, 10, 1000))
ns_ts = pd.Series(non_stationary)
ns_ts.plot()
plt.title('Non-Stationary Time Series')
plt.show()

非平稳时间序列:在第一幅图中,我们看到的序列有一个明显的周期性波动模式。这个序列的均值和方差都在随时间变化。均值在随时间变化是因为我们在生成这个序列时,将随机数进行了累加;方差在随时间变化是因为我们增加了一个正弦项,使得序列在不同的时间点具有不同的波动幅度。

平稳时间序列:在第二幅图中,我们可以看到序列在0附近随机波动。这个序列的均值和方差都是常数。均值是因为我们在生成这个序列时,从均值为0的正态分布中抽取了随机数;方差也是常数,因为这些随机数是独立同分布的。

在时间序列分析中,我们通常需要将非平稳时间序列转化为平稳时间序列,因为许多时间序列模型(如AR、MA和ARIMA模型)都假设输入的数据是平稳的。这种转化可以通过差分或其他预处理方法来实现。

ACF (Auto-Correlation Function)和PACF (Partial Auto-Correlation Function)是时间序列分析中的两个重要工具,它们可以用来检验一个时间序列是否是平稳的,以及帮助确定ARIMA模型的参数。

3.7.2 自相关函数ACF与偏自相关函数PACF

ACF 是一个完整的自相关函数,可为我们提供具有滞后值的任何序列的自相关值。简单来说,它描述了该序列的当前值与其过去的值之间的相关程度。时间序列可以包含趋势,季节性,周期性和残差等成分。ACF在寻找相关性时会考虑所有这些成分。

直观上来说,ACF 描述了一个观测值和另一个观测值之间的自相关,包括直接和间接的相关性信息。

PACF 是部分自相关函数或者偏自相关函数。基本上,它不是找到像ACF这样的滞后与当前的相关性,而是找到残差(在去除了之前的滞后已经解释的影响之后仍然存在)与下一个滞后值的相关性。因此,如果残差中有任何可以由下一个滞后建模的隐藏信息,我们可能会获得良好的相关性,并且在建模时我们会将下一个滞后作为特征。请记住,在建模时,我们不想保留太多相互关联的特征,因为这会产生多重共线性问题。因此,我们只需要保留相关功能。

 

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt 
%matplotlib inline 

import matplotlib
matplotlib.rc('xtick', labelsize=40) 
matplotlib.rc('ytick', labelsize=40) 

import seaborn as sns
sns.set(style="whitegrid", color_codes=True)
from statsmodels.tsa.stattools import acf, pacf


t = np.linspace(0, 10, 500)
#normal distributed values
ys = np.random.normal(0,5,500)


#exponential series to get the trend
ye = np.exp(t**0.5)
#adding normally distributed series in exponential series
y = ys+ye
#plot
plt.figure(figsize=(16,7))
plt.plot(t,y)

#ACF:

from statsmodels.tsa.stattools import acf

#calling auto correlation function
lag_acf = acf(y, nlags=300)
#Plot PACF:
plt.figure(figsize=(16, 7))
plt.plot(lag_acf,marker='+')
plt.axhline(y=0,linestyle='--',color='gray')
plt.axhline(y=-1.96/np.sqrt(len(y)),linestyle='--',color='gray')
plt.axhline(y=1.96/np.sqrt(len(y)),linestyle='--',color='gray')
plt.title('Autocorrelation Function')
plt.xlabel('number of lags')
plt.ylabel('correlation')
plt.tight_layout()

#PACF:
from statsmodels.tsa.stattools import pacf

#calling partial correlation function
lag_pacf = pacf(y, nlags=30, method='ols')
#Plot PACF:
plt.figure(figsize=(16, 7))
plt.plot(lag_pacf,marker='+')
plt.axhline(y=0,linestyle='--',color='gray')
plt.axhline(y=-1.96/np.sqrt(len(y)),linestyle='--',color='gray')
plt.axhline(y=1.96/np.sqrt(len(y)),linestyle='--',color='gray')
plt.title('Partial Autocorrelation Function')
plt.xlabel('Number of lags')
plt.ylabel('correlation')
plt.tight_layout()

四、灰色系统模型

4.1 基本概念

灰色系统是指系统数据有一些是未知,有一些是已知。而灰色预测就是对含有已知和未知信息的系统进行预测,寻找数据变动规律,再建立相应的微分方程模型,来对事物发展进行预测。

目前常用的一些预测方法(如回归分析等),需要较大的样本,若样本较小,常造成较大误差,使预测目标失效。灰色预测模型所需建模信息少,运算方便,建模精度高,在各种预测领域都有着广泛的应用,是处理小样本预测问题的有效工具,特别是它对时间序列短、统计数据少、信息不完全系统的分析与建模,具有独特的功效,因此得到了广泛的应用。

4.2 灰色系统生成

①基本概念:

将原始数据列中的数据,按某种要求作数据处理称为生成客观世界尽管复杂,表述其行为的数据可能是杂乱无章的,然而它必然是有序的,都存在着某种内在规律,不过这些规律被纷繁复杂的现象所掩盖,人们很难直接从原始数据中找到某种内在的规律.对原始数据的生成就是企图从杂乱无章的现象中去发现内在规律。

常用的灰色系统生成方式有:
 (1)累加生成,
 (2)累减生成,
 (3)均值生成,
 (4)级比生成等

4.2.1 累加生成

4.3 灰色预测模型

 虽然是个离散的差分模型,我们当它连续,建立灰微分方程:,以及对应的白化微分方程:

4.4 灰色关联模型

#导入相关库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 解决图标题中文乱码问题
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
#导入数据
data=pd.read_excel('huiseguanlian.xlsx')
# print(data)
#提取变量名 x1 -- x7
label_need=data.keys()[1:]
# print(label_need)
#提取上面变量名下的数据
data1=data[label_need].values
print(data1)
[m,n]=data1.shape #得到行数和列数
data2=data1.astype('float')
data3=data2
ymin=0
ymax=1
for j in range(0,n):
  d_max=max(data2[:,j])
  d_min=min(data2[:,j])
  data3[:,j]=(ymax-ymin)*(data2[:,j]-d_min)/(d_max-d_min)+ymin
print(data3)
# 绘制 x1,x4,x5,x6,x7 的折线图
t=range(2007,2014)
plt.plot(t,data3[:,0],'*-',c='red')
for i in range(4):
  plt.plot(t,data3[:,2+i],'.-')
plt.xlabel('year')
plt.legend(['x1','x4','x5','x6','x7'])
plt.title('灰色关联分析')
plt.show()
# 得到其他列和参考列相等的绝对值
for i in range(3,7):
  data3[:,i]=np.abs(data3[:,i]-data3[:,0])
#得到绝对值矩阵的全局最大值和最小值
data4=data3[:,3:7]
d_max=np.max(data2)
d_min=np.min(data2)
a=0.5 #定义分辨系数
# 计算灰色关联矩阵
data4=(d_min+a*d_max)/(data4+a*d_max)
xishu=np.mean(data4, axis=0)
print(' x4,x5,x6,x7 与 x1之间的灰色关联度分别为:')
print(xishu)

五、组合投资中的基本策略

5.1 马科维兹均值方差模型

马科维茨均值-方差理论被广泛用于解决最优投资组合选择问题。该理论主要通过研究各资产的预期收益、方差和协方差来确定最优投资组合。

5.2 最大夏普比率模型

夏普比率是可以 同时考虑回报和风险的三个经典指标之一。夏普比率的目的是计算一个投资组合每单位总风险将产生多 少超额回报。如果夏普比率为正,则表示基金的回报率高于波动风险;如果为负,则表示基金的操作风 险大于回报率。夏普比率越高,投资组合就越好。

5.3 风险平价模型

 风险平价是一种资产配置哲学,它为投资组合中的不同 资产分配相等的风险权重。风险平价的本质实际上是假设各种资产的夏普比率在长期内往往是一致的, 以找到投资组合的长期夏普比率的最大化。

六、马尔可夫模型

6.1 基础概念

6.1.1 生成模式

6.1.2 一个马尔科夫过程

 6.2 马尔科夫模型

6.3 马尔科夫链

 

参考资料

移动平均法(Moving average,MA) 指数平滑法(Exponential Smoothing,ES)_移动平均平滑-CSDN博客

理论加实践,终于把时间序列预测ARIMA模型讲明白了-CSDN博客

https://blog.csdn.net/Lvbaby_/article/details/130828470

【时间序列】怎么理解ACF 和PACF_acf和pacf-CSDN博客

马尔可夫模型 | 机器之心

马尔科夫模型 Markov Model-CSDN博客

Datawhale 数学建模教程

  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值