本章主要涉及到的知识点有:
-
时间序列的基本概念
-
移动平均法与指数平滑法
-
ARIMA系列模型
-
GARCH系列模型
-
灰色系统模型
-
组合投资中的基本策略
8.1 时间序列的基本概念
时间序列,顾名思义就是有时间性的序列。这种数据一个典型的特征就是有一个时间列作为索引。这个时间表示的是一个先后关系,可以以日为单位,可以以小时为单位,可以以分钟或秒为单位,这些都可以,并且它的应用范畴也很广。
8.1.1 时间序列的典型应用和描述与分解
时间序列分析是一种用于分析和预测随时间变化的数据点的统计方法。它在多个领域中都有广泛的应用,包括经济学、金融、气象学和工程学。时间序列数据可以是离散的,如每日的天气预报或股票价格,也可以是连续的,如实时记录的温度或湿度。
在时间序列建模中,我们不仅关注预测未来趋势,也致力于通过模型参数来分析和理解时间序列的特征。预测可以分为短期和长期,其中短期预测通常更为精确,因为长期预测需要考虑更多的不确定性和潜在的外部影响。
时间序列数据通常被组织成一个面板,每一行代表一个时间点的多个观测值。平稳时间序列是一个特殊类型,它的均值、方差和协方差不随时间变化,表现出一种统计上的稳定性。
时间序列可以分解为几个基本组成部分:长期趋势、季节波动、循环波动和不规则波动。长期趋势反映了数据随时间推移的总体方向;季节波动是由季节性因素引起的规律性变化;循环波动则是非周期性的长期变动;不规则波动则是由随机事件引起的短期波动。
分解模型可以是加法的或乘法的,取决于各组成部分之间的关系。在加法模型中,各组成部分是相互独立的,而在乘法模型中,部分组成部分可能以比例的形式存在。这些模型有助于我们更深入地理解时间序列的结构,并为预测和分析提供基础。
例如,一个时间序列Y[t]Y[t]可以通过以下加法模型进行分解: Y[t]=T[t]+S[t]+C[t]+I[T]Y[t]=T[t]+S[t]+C[t]+I[T] 或者通过以下乘法模型: Y[t]=T[t]×S[t]×C[t]×I[T]Y[t]=T[t]×S[t]×C[t]×I[T] 这些模型不仅帮助我们识别和分离时间序列的不同成分,还可以通过组合加法和乘法模型来适应更复杂的时间序列结构。
时间序列分析是一个不断发展的领域,它结合了统计学、数学和领域知识,以提供对时间数据的深入理解和准确的预测。
df=pd.read_csv("Bitcoin.csv")
y=df.Bitcoin
df.Date=pd.to_datetime(df.Date)
df=df.set_index(df['Date'],drop=True)
# 绘制时间序列图
plt.figure(figsize=(12, 4))
plt.plot(df.Bitcoin, label='Bitcoin')
plt.title('Bitcoin Time Series')
plt.xlabel('Date')
plt.ylabel('Bitcoin')
plt.legend()
plt.show()
# 季节性分析
res = sm.tsa.seasonal_decompose(df.Bitcoin, model='additive')
res.plot()
plt.suptitle('Seasonal Decomposition')
plt.show()
8.2 移动平均法与指数平滑法
移动平均法和指数平滑法是两种在时间序列分析中常用的预测技术,特别适用于大趋势的建模和短期趋势的外推。移动平均法通过使用一组最近的实际数据值来预测未来的时间序列,这种方法在股票K线图中也很常见。它特别适用于短期预测,当需求变化不大且不存在季节性因素时,能够有效消除预测中的随机波动。移动平均法可以进一步细分为简单移动平均和加权移动平均。
简单移动平均法是一种基本的平滑预测技术,其核心思想是计算包含一定项数的序列平均值,以反映长期趋势。这种方法可以消除周期变动和随机波动的影响,显示出事件的发展趋势。当预测目标的基本趋势是水平的,即趋势线是一条水平线时,可以使用一次移动平均方法。一次移动平均方法的递推公式如下: Mt(1)=1N∑i=1NyiMt(1)=N1∑i=1Nyi 其中,M0(1)M0(1) 是初始值,yiyi 是第 ii 个数据点。
如果预测目标的趋势是线性的,可以使用二次移动平均方法,其递推公式为: Mt(2)=Mt(1)+Mt−1(1)+K+Mt−N+1(1)NMt(2)=NMt(1)+Mt−1(1)+K+Mt−N+1(1) 这里的 KK 是一个常数,用于调整移动平均的平滑度。预测标准误差 SS 可以通过以下公式计算: S=1T−N∑t=N+1T(yt−y^t)2S=T−N1∑t=N+1T(yt−y^t)2。
当预测目标的基本趋势呈周期加线性时,可以使用趋势移动平均法。这种方法的公式为: yT+m=aT+bTmyT+m=aT+bTm 其中,aTaT 和 bTbT 分别表示趋势的斜率和截距,可以通过以下公式计算: aT=2MT(1)−MT(2)aT=2MT(1)−MT(2) bT=2N−1N(MT(1)−MT(2))bT=N2N−1(MT(1)−MT(2))
在实际应用中,如果时间序列中出现明显的直线型或曲线型趋势,通常需要先分离这些趋势成分,以便更清晰地分析序列的平稳部分。无论是二次移动平均还是趋势移动平均,目的都是拟合并分离这些大趋势,从而使剩余的序列更接近平稳状态。平稳序列的分析总是比非平稳序列的分析更为简单和直接。
import numpy as np
y=np.array(y)
def MoveAverage(y,N):
Mt=[y[0]]*N
for i in range(N+1,len(y)+2):
M=y[i-N-1:i-1].mean()
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()
8.2.2 指数平滑法
指数平滑法是一种基于时间序列预测的方法,它的核心思想是给予更近期的数据更大的权重。这种方法特别适用于时序预测,因为它认为最近的数据对预测未来趋势更为重要。例如,在股市预测中,近期的市场数据比多年前的数据更能反映当前的经济状况和市场情绪。
指数平滑法有几种不同的形式,包括一次指数平滑法、二次指数平滑法和三次指数平滑法。一次指数平滑法适用于没有趋势和季节性的序列,二次指数平滑法适用于有趋势但没有季节性的序列,而三次指数平滑法则适用于同时具有趋势和季节性的序列。
一次指数平滑法的递推公式如下: St(1)=αyt+(1−α)St−1(1)St(1)=αyt+(1−α)St−1(1) 其中,αα 表示修正幅度,通过对 αα 的调整,可以实现对序列的平滑处理。
进一步地,三次指数平滑法的模型可以定义为: yt+m=at+btm+ctm2yt+m=at+btm+ctm2 这里,atat、btbt 和 ctct 分别代表趋势项、季节项和季节的二次项。
在实际应用中,指数平滑法的累计序列可以定义为: St(1)=αyt+(1−α)St−1(1)St(1)=αyt+(1−α)St−1(1) St(2)=αSt(1)+(1−α)St−1(2)St(2)=αSt(1)+(1−α)St−1(2) St(3)=αSt(2)+(1−α)St−1(3)St(3)=αSt(2)+(1−α)St−1(3)
值得注意的是,与移动平均法相比,指数平滑法在应用时趋势线的长度与原始序列的长度是一致的,而移动平均法则会因为窗口长度的原因减少预测序列的数据量。这种方法使得指数平滑法在处理时间序列数据时更为灵活,能够更好地适应不同类型和特征的序列。
import numpy as np
import pandas as pd
def ExpMove(y,a):
n=len(y)
M=np.zeros(n)
#M[0]=(y[0]+y[1])/2
M[0]=y[0]
for i in range(1,len(y)):
M[i]=a*y[i-1]+(1-a)*M[i-1]
return M
yt1=ExpMove(y,0.2)
yt2=ExpMove(y,0.5)
yt3=ExpMove(y,0.8)
s1=np.sqrt(((y-yt1)**2).mean())
s2=np.sqrt(((y-yt2)**2).mean())
s3=np.sqrt(((y-yt3)**2).mean())
d=pd.DataFrame(np.c_[y,yt1,yt2,yt3])
f=pd.ExcelWriter('exp_smooth_example.xlsx')
d.to_excel(f)
f.close()
d.plot()
plt.show()
print(d)
8.3 ARIMA系列模型
积土成山,风雨兴焉;积水成渊,蛟龙生焉。ARIMA模型实际上是由多个模型组合而来,而最起初的模型也都是针对平稳时间序列而言的。在一开始,我们会重新回温一下平稳时间序列和白噪声的概念,然后介绍如何判断一个序列是平稳时间序列的检验方法,再来介绍模型的演化和组合。
8.3.1 自回归模型(AR模型):时间序列分析的基石
自回归模型(AR模型)是时间序列分析中的一个关键工具,它利用时间序列的历史信息来预测其未来值。这种模型基于一个基本假设:时间序列的当前值与其过去的值存在一定的线性关系。在构建AR模型时,我们首先要求时间序列是弱平稳的,这意味着其统计特性,如均值、方差和自相关性,不会随时间发生显著变化。
一个p阶自回归模型的递推公式如下: yt=μ+∑i=1pϕiyt−i+ϵtyt=μ+∑i=1pϕiyt−i+ϵt 这里,μ 表示序列的长期均值,ϕi 是自回归系数,它们共同决定了序列的动态行为,而 ϵt 是白噪声项,代表了模型无法解释的随机波动。通过精确估计这些系数,AR模型能够揭示时间序列的内在结构,为预测提供坚实的基础。
8.3.2 移动平均模型(MA模型):捕捉随机波动
移动平均模型(MA模型)是另一种重要的时间序列分析方法,它专注于分析时间序列当前值与过去误差项之间的关系。MA模型的核心思想是将时间序列的当前值视为过去一系列随机误差的加权平均。这种模型特别适合于分析那些具有明显随机波动特性的数据。
一个q阶移动平均模型的递推公式如下: yt=μ+∑i=1qβiϵt−i+ϵt这里,μ 是时间序列的平均水平,βi 是移动平均系数,它们共同决定了序列对过去随机波动的响应程度,而 ϵt 是当前的白噪声项。MA模型通过平滑过去的随机波动,帮助我们识别时间序列的未来走势,并对其进行预测。
8.3.3 ARMA和ARIMA模型:时间序列分析的高级框架
自回归滑动平均模型(ARMA模型)和自回归移动平均模型(ARIMA模型)是结合了AR和MA模型特点的高级时间序列分析工具。这些模型不仅能够捕捉时间序列的自相关性,还能够处理数据的非平稳性,使其成为预测和分析复杂时间序列的强大工具。
ARIMA模型由自回归(AR)、差分(I)和移动平均(MA)三个部分组成,其一般形式可以表示为ARIMA(p,d,q),其中p是自回归项的阶数,d是差分阶数,用于使序列平稳,q是移动平均项的阶数。一个ARIMA(p,d,q)模型的递推公式如下: ∇dyt=∑i=1pϕi∇dyt−i+∑i=1qβiϵt−i+ϵt这个公式通过差分操作 ∇d 转换非平稳序列为平稳序列,然后应用自回归和移动平均项来建模和预测序列的行为。
在模型参数的选择上,赤池信息准则(AIC)和贝叶斯信息准则(BIC)是两个非常重要的准则。AIC准则旨在找到最佳的模型拟合,同时避免过拟合,其公式如下: AIC=2(p+q+d)−2ln(L)AIC=2(p+q+d)−2ln(L) 而BIC准则则更加严格地惩罚模型复杂度,其公式如下: BIC=(p+q+d)ln(n)−2ln(L)这里,L 表示模型的最大似然函数,n 是样本数量。通过应用这些准则,我们可以从多个候选模型中选择出最合适的一个,确保模型既能够准确反映数据的特性,又不至于过于复杂。
8.4 灰色系统模型
8.4.1 灰色预测模型
灰色系统理论是一种独特的系统分析方法,它专门处理那些含有未知和已知信息的系统。在现实世界中,很多系统的运作都伴随着不确定性和信息的不完全性,灰色预测正是在这样的背景下应运而生。通过寻找数据变动的规律,并建立相应的微分方程模型,灰色预测能够对事物的发展趋势进行有效的预测。值得一提的是,灰色理论的创始人邓聚龙教授,当时在华中理工大学(现华中科技大学)工作,为该领域的发展做出了开创性的贡献。
灰色预测模型基础:GM(1,1)模型
灰色预测的起点是GM(1,1)模型,它是灰色预测中最基本的模型。这个模型的构建过程开始于对已知数据列 x(0)=(x(0)t(1),x(0)t(2),...,x(0)进行一次累加,生成新的数据序列,即一阶累加序列 x(1)x(1)。这个过程可以通过以下公式实现: x(1)t(n)=∑i=1nx(0)t(i)
接下来,通过对序列进行均值化处理,可以得到新的序列 z(1)(k)z(1)(k),它为建立灰色微分方程提供了基础: z(1)(k)=x(1)(k)+x(1)(k−1)2z(1)(k)=2x(1)(k)+x(1)(k−1)
在灰色预测中,虽然我们处理的是离散数据,但我们会假设这些数据是连续的,并在此基础上建立灰色微分方程: x(0)(k)+az(1)(k)=b,k=2,3,...,mx(0)(k)+az(1)(k)=b,k=2,3,...,m
对应的白化微分方程为: dx(1)(t)dt+az(1)(t)=b,k=2,3,...,mdtdx(1)(t)+az(1)(t)=b,k=2,3,...,m
这两个方程本质上是等价的,通过求解白化微分方程并使用最小二乘法拟合参数,可以得到模型参数 u=[a,b]Tu=[a,b]T 的估计值。
GM(1,1)模型的求解与预测
求解GM(1,1)模型后,我们可以得到未来数据点的预测值。具体来说,通过最小二乘法的矩阵模式,我们可以求解出模型参数,并应用以下公式来预测下一时刻的数据点: x(1)(k+1)=(x(0)(1)−ba)e−ak+bax(1)(k+1)=(ax(0)(1)−b)e−ak+ab
通过对预测值进行向后差分,我们可以得到原始数据的预测值。这个过程不仅能够帮助我们理解数据的内在规律,还能够为未来的发展趋势提供预测。
GM(2,1)模型:灰色预测的进一步拓展
GM(2,1)模型是灰色预测中的一个更一般的形式,它适用于原始序列的建模。通过一次累加和一次差分,我们可以得到序列 x1 和 x0′,然后建立GM(2,1)的灰色方程: x′(0)(k)+a1x(0)(k)+a2z(1)(k)=bx′(0)(k)+a1x(0)(k)+a2z(1)(k)=b
对应的白化微分方程是一个二阶微分方程: d2x(1)dt2+a1dx(1)dt+a2x(1)=bdt2d2x(1)+a1dtdx(1)+a2x(1)=b
求解这个方程可以得到更复杂的模型参数,从而对时间序列进行更精确的预测。尽管求解过程可能较为复杂,但GM(2,1)模型提供了一种强大的工具,用于处理和预测含有不确定性的时间序列数据。
灰色预测模型通过其独特的数据处理和模型建立方法,在许多领域都显示出了其强大的预测能力。从经济预测到环境科学,再到工程技术,灰色预测都已成为一种重要的分析工具。通过这些模型,我们能够更好地理解和预测那些在信息不完全的情况下系统的行为和发展趋势。
import numpy as np
import math
import matplotlib.pyplot as plt
history_data = [724.57,746.62,778.27,800.8,827.75,871.1,912.37,954.28,995.01,1037.2]
def GM11(history_data,forcast_steps):
n = len(history_data) # 确定历史数据体量
X0 = np.array(history_data) # 向量化
# 级比检验的部分可以自行补充
lambda0=np.zeros(n-1)
for i in range(n-1):
if history_data[i]:
lambda0[i]=history_data[i+1]/history_data[i]
if lambda0[i]<np.exp(-2/(n+1)) or lambda0[i]>np.exp(2/n+2):
print("GM11模型失效")
return -1
#累加生成
history_data_agg = [sum(history_data[0:i+1]) for i in range(n)]
X1 = np.array(history_data_agg)
#计算数据矩阵B和数据向量Y
B = np.zeros([n-1,2])
Y = np.zeros([n-1,1])
for i in range(0,n-1):
B[i][0] = -0.5*(X1[i] + X1[i+1])
B[i][1] = 1
Y[i][0] = X0[i+1]
#计算GM(1,1)微分方程的参数a和b
A = np.linalg.inv(B.T.dot(B)).dot(B.T).dot(Y)
a = A[0][0]
b = A[1][0]
#建立灰色预测模型
XX0 = np.zeros(n)
XX0[0] = X0[0]
for i in range(1,n):
XX0[i] = (X0[0] - b/a)*(1-math.exp(a))*math.exp(-a*(i))
#模型精度的后验差检验
e=sum(X0-XX0)/n
#求历史数据平均值
aver=sum(X0)/n
#求历史数据方差
s12=sum((X0-aver)**2)/n
#求残差方差
s22=sum(((X0-XX0)-e)**2)/n
#求后验差比值
C = s22 / s12
#求小误差概率
cobt = 0
for i in range(0,n):
if abs((X0[i] - XX0[i]) - e) < 0.6754*math.sqrt(s12):
cobt = cobt+1
else:
cobt = cobt
P = cobt / n
f = np.zeros(forcast_steps)
if (C < 0.35 and P > 0.95):
#预测精度为一级
print('往后各年预测值为:')
for i in range(0,forcast_steps):
f[i] = (X0[0] - b/a)*(1-math.exp(a))*math.exp(-a*(i+n))
print(f)
else:
print('灰色预测法不适用')
return f
f=GM11(history_data,20)
plt.plot(range(11,31),f)
plt.plot(range(1,11),history_data)
plt.show()
灰色关联分析方法,是根据因素之间发展趋势的相似或相异程度,亦即“灰色关联度”,作为衡量因素间关联程度的一种方法。其思想很简单,确定参考列和比较列以后需要对数列进行无量纲化处理,然后计算灰色关联系数。这里我们使用均值处理法,即每个属性的数据除以对应均值:
灰色关联系数的定义如下:
其中ρ不超过0.5643时分辨力最好,这里为了简洁,可以取之为0.5。灰色关联度为关联系数在样本上的平均值,计算出每个属性的灰色关联度以后就可以进行分析。
例7.1 对表7.1中的属性进行灰色关联分析,分析x4-x7与x1之间的相关关系。
表7.1 例7.1使用数据
可以写出以下代码:
#导入相关库
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)
8.5 组合投资问题的一些策略
组合投资的重要性
投资领域有一句老话:“永远不要把鸡蛋放在同一个篮子里”。这句话道出了分散投资的精髓。通过将资产分配到不同的投资渠道,比如不动产、古玩字画、黄金、石油和股票等,可以在某些投资领域亏损时,依靠其他领域的收益来平衡损失,从而降低整体投资风险。几十年前,有些人将全部身家投入赌场,结果一夜之间倾家荡产,这样的例子在现实中并不罕见。学会分散资产配置,是投资成功的关键之一。
投资策略与时间序列预测
假设你持有的本金为单位1,在市场上进行投资选股时,你需要做两件事:一是从众多股票中挑选出潜力股;二是确定每支股票的投资比例。你的投资策略会根据你的投资周期而有所不同,可能是一周后套现,也可能是一年后。从理论上讲,动态规划可以用来建模这一问题,但在现实中,由于股票市场波动的不确定性,我们通常需要依赖时间序列方法进行预测,并基于预测结果制定投资组合策略。
马科维兹均值方差模型
马科维兹均值-方差理论是解决最优投资组合选择问题的一种经典方法。它通过分析资产的预期收益、方差和协方差来确定最优投资组合。这一理论首次将数理统计方法引入投资组合理论,为投资者提供了一种量化风险和收益的工具。
在马科维兹理论中,股票的风险可以通过时间序列的统计特性来描述,通常用方差来衡量。风险越大,意味着可能的亏损或盈利幅度也越大。而收益则通过期望收益来衡量,即收益的平均水平。在计算收益时,需要考虑的是套现时的股票价格与购买成本之间的差额。
基于马科维兹均值方差模型,我们可以建立一个多目标规划问题,通过最小化风险函数和最大化收益函数来确定最优投资组合。这个问题可以通过引入拉格朗日乘子来简化,并求解得到最优策略。
最大夏普比率模型
夏普比率是由1990年诺贝尔经济学奖得主威廉·夏普提出的,它是一种综合考虑投资回报和风险的指标。夏普比率的目的是计算每单位总风险所能产生的超额回报。一个高的夏普比率意味着投资组合在风险调整的基础上表现良好。
夏普比率的定义是投资组合的超额回报与总风险的比值。在优化问题中,我们可以通过最大化夏普比率来寻找最优投资组合。这个问题可以通过数值方法求解,从而得到一个综合考虑风险和收益的投资策略。
风险平价模型
风险平价模型是由爱德华·钱博士在2005年提出的,它是一种资产配置哲学,旨在为投资组合中的不同资产分配相等的风险权重。风险平价的核心思想是假设不同资产的夏普比率在长期内是一致的,以此来寻找投资组合的长期夏普比率最大化。
在风险平价模型中,我们可以计算出比特币和黄金的风险贡献率,并构造一个规划模型来使两种资产的风险尽可能一致。通过求解这个规划问题,我们可以得到最优的投资组合策略,实现风险的平衡分配。
通过这些模型,投资者可以更好地理解和管理投资风险,同时追求最大化收益。无论是均值方差模型、夏普比率模型还是风险平价模型,它们都提供了一种系统的方法来构建和管理投资组合。
8.6 马尔可夫模型
马尔可夫链的基本概念
马尔可夫链是一种离散时间的随机过程,其核心特点是无记忆性,即系统的下一个状态只依赖于当前状态,而与之前的历史状态无关。这可以用概率表达式表示为: P(Xt+1∣Xt,Xt−1,...,Xt−k)=P(Xt+1∣Xt) 这种性质使得马尔可夫链在许多领域,如物理学、经济学、金融学、语言模型等,都有着广泛的应用。
马尔可夫链的数学特性
马尔可夫链的长期行为可以通过状态转移矩阵 PP来描述。根据马尔氏定理,对于一个非周期的马尔可夫链,随着时间 n 趋向无穷大,状态转移矩阵的 nn 次方会趋于一个极限矩阵,其所有行都是相同的,并且这行向量 ππ构成了马尔可夫链的平稳分布。数学上可以表示为: limn→∞Pn=[π(1)⋯π(j)]其中,π(j) 是状态 j的平稳概率,且满足: π(j)=∑i=0∞π(i)Pij并且所有 π(i)的和为 1: ∑i=0∞πi=1
细致平稳定理
细致平稳定理是马尔可夫链理论中的一个重要概念。它表明,如果对于非周期马尔可夫链,存在一个概率分布 ππ 满足: π(j)=∑i=0∞π(i)Pij那么我们就说 π 是马尔可夫链的平稳分布,且满足细致平稳条件。这个定理为找到马尔可夫链的长期行为提供了一个强有力的工具。
马尔可夫随机场
马尔可夫随机场(Markov Random Field,MRF)是概率无向图模型的一种,它通过无向图来表示一组随机变量的联合概率分布。在马尔可夫随机场中,每个节点代表一个随机变量,每条边表示两个变量间的概率依赖。一个联合概率分布 P(Y) 构成马尔可夫随机场的条件是满足成对马尔可夫性、局部马尔可夫性和全局马尔可夫性中的任意一个。
- 成对马尔可夫性 指的是,任意两个非相邻节点的变量在给定它们各自相邻节点的条件下是条件独立的。
- 局部马尔可夫性 指的是,一个节点的变量在给定其相邻节点的条件下,与图中其他节点的变量是条件独立的。
- 全局马尔可夫性 指的是,对于图上的任意两个不相交的子集,它们的变量在给定它们边界节点的条件下是条件独立的。
8.6.1 马尔可夫模型的实现
隐马尔可夫模型(Hidden Markov Model, HMM)是一个强大的工具,用于模拟具有隐藏状态的时间序列数据。HMM广泛应用于多个领域,如语音识别、自然语言处理和生物信息学等。在处理HMM时,主要集中于三个经典问题:评估问题、解码问题和学习问题。三个问题构成了使用隐马尔可夫模型时的基础框架,使得HMM不仅能够用于模拟复杂的时间序列数据,还能够从数据中学习和预测。
1、评估问题
在隐马尔可夫模型(Hidden Markov Model, HMM)的应用中,评估问题是指确定一个给定的观测序列在特定HMM参数下的概率。简而言之,就是评估一个模型生成某个观测序列的可能性有多大。模型评估问题通常使用前向算法解决。前向算法是一个动态规划算法,它通过累积“前向概率”来计算给定观测序列的概率。前向概率定义为在时间点t
观察到序列的前t
个观测,并且系统处于状态i
的概率。算法的核心是递推公式,它利用前一时刻的前向概率来计算当前时刻的前向概率。
import numpy as np
# 定义模型参数
states = {'Rainy': 0, 'Sunny': 1}
observations = ['walk', 'shop', 'clean']
start_probability = np.array([0.6, 0.4])
transition_probability = np.array([[0.7, 0.3], [0.4, 0.6]])
emission_probability = np.array([[0.1, 0.4, 0.5], [0.6, 0.3, 0.1]])
# 观测序列,用索引表示
obs_seq = [0, 1, 2] # 对应于 'walk', 'shop', 'clean'
# 初始化前向概率矩阵
alpha = np.zeros((len(obs_seq), len(states)))
# 初始化
alpha[0, :] = start_probability * emission_probability[:, obs_seq[0]]
# 递推计算
for t in range(1, len(obs_seq)):
for j in range(len(states)):
alpha[t, j] = np.dot(alpha[t-1, :], transition_probability[:, j]) * emission_probability[j, obs_seq[t]]
# 序列的总概率为最后一步的概率之和
total_prob = np.sum(alpha[-1, :])
print("Forward Probability Matrix:")
print(alpha)
print("\nTotal Probability of Observations:", total_prob)
2、解码问题
在隐马尔可夫模型(Hidden Markov Model, HMM)中,解码问题是指给定一个观测序列和模型参数,找出最有可能产生这些观测的隐状态序列。这个问题的核心是如何从已知的观测数据中推断出隐含的状态序列,这在许多应用场景中非常有用,如语音识别、自然语言处理、生物信息学等。解决这一问题最常用的算法是维特比算法,一种动态规划方法,它通过计算并记录达到每个状态的最大概率路径,从而找到最可能的状态序列。
import numpy as np
def viterbi(obs, states, start_p, trans_p, emit_p):
"""
Viterbi Algorithm for solving the decoding problem of HMM
obs: 观测序列
states: 隐状态集合
start_p: 初始状态概率
trans_p: 状态转移概率矩阵
emit_p: 观测概率矩阵
"""
V = [{}]
path = {}
# 初始化
for y in states:
V[0][y] = start_p[y] * emit_p[y][obs[0]]
path[y] = [y]
# 对序列从第二个观测开始进行运算
for t in range(1, len(obs)):
V.append({})
newpath = {}
for cur_state in states:
# 选择最可能的前置状态
(prob, state) = max((V[t-1][y0] * trans_p[y0][cur_state] * emit_p[cur_state][obs[t]], y0) for y0 in states)
V[t][cur_state] = prob
newpath[cur_state] = path[state] + [cur_state]
# 不更新path
path = newpath
# 返回最终路径和概率
(prob, state) = max((V[len(obs) - 1][y], y) for y in states)
return (prob, path[state])
# 定义状态、观测序列及模型参数
states = ('Rainy', 'Sunny')
observations = ('walk', 'shop', 'clean')
start_probability = {'Rainy': 0.6, 'Sunny': 0.4}
transition_probability = {
'Rainy' : {'Rainy': 0.7, 'Sunny': 0.3},
'Sunny' : {'Rainy': 0.4, 'Sunny': 0.6},
}
emission_probability = {
'Rainy' : {'walk': 0.1, 'shop': 0.4, 'clean': 0.5},
'Sunny' : {'walk': 0.6, 'shop': 0.3, 'clean': 0.1},
}
# 应用维特比算法
result = viterbi(observations,
states,
start_probability,
transition_probability,
emission_probability)
print(result)
3、学习问题
理解隐马尔可夫模型(HMM)的模型学习问题关键在于确定模型参数,以最大化给定观测序列的出现概率。解决这一学习问题的常用方法是鲍姆-韦尔奇算法,这是一种迭代算法,通过交替执行期望步骤(E步骤)和最大化步骤(M步骤)来找到最大化观测序列概率的参数。E步骤计算隐状态的期望值,而M步骤则更新模型参数以最大化观测序列的概率。这一过程会持续重复,直至满足一定的收敛条件,如参数变化量低于特定阈值或达到预设的迭代次数。通过这种方式解决学习问题,我们可以获得一组能够很好解释给定观测数据的模型参数,这表明模型能够捕捉到观测数据中的统计规律,用于生成观测序列、预测未来观测值或识别新观测序列中的模式。
import numpy as np
from hmmlearn import hmm
# 假设我们有一组观测数据,这里我们随机生成一些数据作为示例
# 实际应用中,你应该使用真实的观测数据
n_samples = 1000
n_components = 3 # 假设我们有3个隐状态
obs_dim = 2 # 观测数据的维度,例如二维的观测空间
# 随机生成观测数据
np.random.seed(42)
obs_data = np.random.rand(n_samples, obs_dim)
# 初始化GaussianHMM模型
# 这里我们指定了n_components隐状态数量和covariance_type协方差类型
model = hmm.GaussianHMM(n_components=n_components, covariance_type='full', n_iter=100)
# 使用观测数据训练模型
# 注意:实际应用中的数据可能需要更复杂的预处理步骤
model.fit(obs_data)
# 打印学习到的模型参数
print("学习到的转移概率矩阵:")
print(model.transmat_)
print("\n学习到的均值:")
print(model.means_)
print("\n学习到的协方差:")
print(model.covars_)
深入理解隐马尔可夫模型(HMM)处理的三种经典问题——评估问题、解码问题和学习问题,可以将通过一个完整的示例来展示这些问题的应用和解决方案。如有一个简单的天气模型,其中的状态(隐藏状态)包括晴天(Sunny)和雨天(Rainy),观测(可见状态)包括人们的三种活动:散步(Walk)、购物(Shop)和清洁(Clean)。可以使用HMM来处理评估问题、解码问题和学习问题。
from hmmlearn import hmm
import numpy as np
# 定义模型参数
states = ["Rainy", "Sunny"]
n_states = len(states)
observations = ["walk", "shop", "clean"]
n_observations = len(observations)
start_probability = np.array([0.6, 0.4])
transition_probability = np.array([
[0.7, 0.3],
[0.4, 0.6],
])
emission_probability = np.array([
[0.1, 0.4, 0.5],
[0.6, 0.3, 0.1],
])
# 创建模型
model = hmm.MultinomialHMM(n_components=n_states)
model.startprob_ = start_probability
model.transmat_ = transition_probability
model.emissionprob_ = emission_probability
model.n_trials = 4
# 观测序列
obs_seq = np.array([[0], [1], [2]]).T # 对应于观测序列 ['walk', 'shop', 'clean']
# 计算观测序列的概率
logprob = model.score(obs_seq)
print(f"Observation sequence probability: {np.exp(logprob)}")
# 继续使用上面的模型参数和观测序列
# 使用Viterbi算法找出最可能的状态序列
logprob, seq = model.decode(obs_seq, algorithm="viterbi")
print(f"Sequence of states: {', '.join(map(lambda x: states[x], seq))}")
# 假设我们只有观测序列,不知道模型参数
obs_seq = np.array([[0], [1], [2], [0], [1], [2]]).T # 扩展的观测序列
# 初始化模型
model = hmm.MultinomialHMM(n_components=n_states, n_iter=100)
model.fit(obs_seq)
# 打印学习到的模型参数
print("Start probabilities:", model.startprob_)
print("Transition probabilities:", model.transmat_)
print("Emission probabilities:", model.emissionprob_)
8.6. 2条件随机场
条件随机场(Conditional Random Field)是 马尔可夫随机场 + 隐状态的特例。
区别于生成式的隐马尔可夫模型,CRF是判别式的。CRF 试图对多个随机变量(代表状态序列)在给定观测序列的值之后的条件概率进行建模:
给定观测序列X={X1,X2,...,Xn}X={X1,X2,...,Xn},以及隐状态序列Y={y1,y2,...,yn}Y={y1,y2,...,yn}的情况下,构建条件概率模型P(Y∣X)P(Y∣X)。若随机变量Y构成的是一个马尔科夫随机场,则 P(Y∣X)P(Y∣X)为CRF。
借助 sklearn_crfsuite
库实现
import sklearn_crfsuite
X_train = ...
y_train = ...
crf = sklearn_crfsuite.CRF(
algorithm='lbfgs',
c1=0.1,
c2=0.1,
max_iterations=100,
all_possible_transitions=True
)
crf.fit(X_train, y_train)
# CPU times: user 32 s, sys: 108 ms, total: 32.1 s
# Wall time: 32.3 s
y_pred = crf.predict(X_test)
metrics.flat_f1_score(y_test, y_pred,
average='weighted', labels=labels)