对于确定性趋势的参数估计,大致有五种:常均值模型、线性模型、二次式模型、季节均值模型、余弦模型。虽然每种模型各有特点和要求,但对于参数求解,一般都是使用OLSE。其区别仅在与设计矩阵的构造。本文将介绍这五种模型参数估计的R语言自编程序的实现。
注:
1、本人最近正在学习《时间序列分析及应用》一书,本文的相关理论也来自于此书,水平有限,如有错误,还请多批评指正;
2、本文未贴出运行结果,有需要的朋友可以自行运行。(数据来源R包:TSA)
常均值模型
- 参数估计的R语言函数
常均值模型为:
Y
t
=
μ
+
X
t
Y_t=\mu+X_t
Yt=μ+Xt其中对所有的
t
t
t有
E
(
X
)
=
0
E(X)=0
E(X)=0。使用观测到的时间序列
Y
1
,
Y
2
,
…
,
Y
n
Y_1,Y_2,…,Y_n
Y1,Y2,…,Yn来估计
μ
\mu
μ。则可由
O
L
S
E
OLSE
OLSE得出
μ
\mu
μ的估计为样本均值或平均数,定义为
Y
ˉ
=
1
n
∑
t
=
1
n
Y
t
\bar{Y}=\frac{1}{n}\sum_{t=1}^n Y_t
Yˉ=n1t=1∑nYt在模型假设成立的前提下,可以看出
E
(
Y
ˉ
)
=
μ
E(\bar{Y})=\mu
E(Yˉ)=μ,基于此常均值模型的参数估计算法函数ConReg()
如下:
ConReg <- function(Y){
mu = sum(Y) / length(Y)
out = list(Y=Y, mu=mu)
}
- 参数估计的R语言函数检验
由于课本并未给出相关数据,下面人为生成一组数据进行验证,做法如下:令模型中的
μ
=
2
\mu=2
μ=2,
X
t
∼
N
(
0
,
1
)
X_t\sim N(0,1)
Xt∼N(0,1),通过模型生成一组
Y
t
,
t
=
1
,
…
,
100
Y_t,t=1,…,100
Yt,t=1,…,100,以此使用上述函数ConReg()
估计
μ
\mu
μ的值,比较真实的
μ
=
2
\mu=2
μ=2,判断算法的正确性。代码如下:
set.seed(1)
mu = 2
X <- rnorm(100,0,1)
Y <- mu + X + rnorm(100, 0, .2)
muest <- ConReg(Y)
muest$mu
可以计算得估计
μ
=
2.101
\mu=2.101
μ=2.101,与真实值相差不大,可以认为函数ConReg()
是合理的。
线性模型
- 参数估计的R语言函数
对于线性模型
μ
t
=
β
0
+
β
1
t
+
β
2
t
+
…
+
,
β
n
t
\mu_t=\beta_0+\beta_1t+\beta_2t+…+,\beta_nt
μt=β0+β1t+β2t+…+,βnt ,类似的可通过
O
L
S
E
OLSE
OLSE,计算得起参数估计
β
\beta
β应该为:
β
=
(
X
′
X
)
−
1
X
Y
\beta=(X'X)^{-1}XY
β=(X′X)−1XY基于此给出线性模型参数估计的模型LinReg()
代码如下:
LinReg <- function(X, y, lambda = 0, intercept = T){
n = dim(X)[1]
p = dim(X)[2]
#Coefficients
if(intercept == T){
X. = cbind(rep(1,n), X)
}else{
X. = X
}
beta = solve(t(X.)%*%X. + lambda*diag(dim(X.)[2]), t(X.)%*%y)
if (intercept == T){
beta1 = beta[2:(p+1)]
beta0 = beta[1]
}else{
beta1 = beta
beta0 =NULL
}
out = list(X=X, y=y, beta=beta1, beta0 = beta0,
intercept = intercept )
}
- 参数估计的R语言函数检验
类似于常均值模型,人为产生数据进行验证,代码如下:
n <- 100
p <- 6
set.seed(1)
X <- matrix(rnorm(n*p), n, p)
beta = c(3, 1, rep(0,p-2))
beta0 = 0
set.seed(1)
y = X%*%beta + beta0 + rnorm(100, 0, .2)
result <- LinReg(X, y)
result$beta
result$beta0
可以看出估计的参数 β ^ \hat\beta β^与真实值非常接近,认为该函数没有问题。
二次模型
- 参数估计的R语言函数
对于二次模型我们可以将其转化为线性模型进行参数估计,一般的二次模型如下: μ t = β 0 + β 1 t 2 \mu_t=\beta_0+\beta_1t^2 μt=β0+β1t2我们可以令 X 0 = 1 , X 1 = t 2 X_0=1,X_1=t^2 X0=1,X1=t2,这样将其转为,设计矩阵为 X = ( X 0 X 1 ) X=(\begin{matrix}X_0&X_1 \end{matrix}) X=(X0X1)的线性模型,为方便以后的函数调用,在设计R语言函数时推广为多项式模型,代码如下:
PolyDes <- function(t){
n <- length(t[, 1])
p <- length(t[1, ])
X <- matrix(nrow = n, ncol = p)
for (i in 1:p) {
X[, i] <- t[, i]^i
}
out = X
}
- 参数估计的R语言函数检验
函数PolyDes()
仅给出多项式模型的设计矩阵,要求其参数估计可再次调用线性模型函数LinRes()
。以下给出模型的验证:
beta <- c(5, 4, 3, 2, 1)
beta0 <- 0
t <- matrix(nrow = 100, ncol = 5)
set.seed(1)
r <- matrix(rnorm(100*5), 100, 5)
for (i in 1:5) {
t[, i] = 6-i + r[, i]
}
y = beta0 + t[,1]*beta[1] + t[,2]^2*beta[2] + t[,3]^3*beta[3] + t[,4]^4*beta[4] + t[,5]^5*beta[5]+rnorm(100, 0, .2)
X <- PolyDes(t)
result <- LinReg(X,y)
result$beta
result$beta0
对比估计的参数和真实的参数 β \beta β是很接近的,可以认为函数是有效的。
季节趋势模型
- 参数估计的R语言函数
对季节性趋势模型,其观测到的数据可表示为
Y
t
=
μ
t
+
X
t
Y_t=\mu_t+X_t
Yt=μt+Xt,其中,对所有t,
E
(
X
t
)
=
0
E(X_t)=0
E(Xt)=0。对于月度季节新数据,对
μ
t
\mu_t
μt最常用的假设是存在12个常数(参数)
β
1
,
β
2
,
⋯
,
β
12
\beta_1,\beta_2,\cdots,\beta_{12}
β1,β2,⋯,β12,它们给出了12个月的期望平均气温。可以记为:
μ
=
{
β
1
t
=
1
,
13
,
15
,
…
β
2
t
=
2
,
14
,
16
,
…
⋮
β
12
t
=
12
,
24
,
36
,
…
\mu=\begin{cases}\beta_1&t=1,13,15,…\\ \beta_2&t=2,14,16,…\\ \vdots \\ \beta_{12}&t=12,24,36,…\end{cases}
μ=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧β1β2⋮β12t=1,13,15,…t=2,14,16,…t=12,24,36,…该模型有时被称为季节均值模型。
对于季节均值模型的估计,关键点在于将模型按月进行参数估计,这需要对设计矩阵
X
X
X进行特殊处理。这里的处理是,设计矩阵
X
X
X是大小为
n
×
12
n×12
n×12的示性矩阵,n为季节性时间序列的长度。
X
X
X的每一行就为一个示性函数,仅有唯一一个位置为1,即对于确定的
i
i
i,
X
i
j
X_{ij}
Xij表示第
i
i
i个数据是第
j
j
j月的。值得注意的是对于有截距项的模型如下:
μ
t
=
β
0
+
β
2
I
(
t
%
12
=
2
)
+
⋯
+
β
12
I
(
t
%
12
=
0
)
\mu_t=\beta_0+\beta_2I(t\%12=2)+\cdots+\beta_{12}I(t\%12=0)
μt=β0+β2I(t%12=2)+⋯+β12I(t%12=0)参考前面的线性参数进估计,季节均值模型参数估计代码如下:
SeaReg <- function(y, intercept = F){
if (!is.ts(y))
stop("y need to be a time series")
n <- length(y)
X <- matrix(ncol = 12, nrow = n)
month <-c("January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December")
month.y <- as.character(season(y))
for (i in 1:n) {
for (j in 1:12) {
if(month.y[i]==month[j]){
X[i,j] = 1
}else{
X[i,j] = 0
}
}
}
if(intercept == F){
X. = X
}else{
X[, 1]=rep(1, n)
X. = X
}
beta = solve(t(X.)%*%X., t(X.)%*%y)
out = list(y=y, X=X., beta=beta,intercept = intercept )
}
- 参数估计的R语言函数检验
为对季节性趋势模型函数SeaReg()
进行检验,采用TSA
包中的tempdub
数据进行检验。代码如下:
library(TSA)
data("tempdub")
#无截距项
result1 <- SeaReg(tempdub)
result1$beta
#有截距项
result2 <- SeaReg(tempdub, intercept = T)
result2$beta
对比《时间序列》P24页的数据可知,有截距项和无截距项的参数估计的结果是基本一致的,故而该函数是可以接受的。
余弦趋势模型
- 参数估计的R语言函数
余弦趋势模型的最简单形式可表示为: μ t = β 0 + β 1 c o s ( 2 π f t ) + β 2 s i n ( 2 π f t ) \mu_t=\beta_0+\beta_1cos(2\pi ft)+\beta_2sin(2\pi ft) μt=β0+β1cos(2πft)+β2sin(2πft)类比二项式模型可知,其可也转换为线性模型求解,只不过需要对其设计矩阵做一定的设置,代码如下:
CosDes <- function(y, f=1){
if (!is.ts(y))
stop("y need to be a time series")
n = length(y)
t = as.numeric(time(y))
X1 = cos(2*pi*f*t)
X2 = sin(2*pi*f*t)
X = cbind(X1, X2)
out = X
}
- 参数估计的R语言函数检验
采用TSA
包中的tempdub
数据进行检验。使用默认频率f=1
,代码如下:
library(TSA)
data("tempdub")
X <- CosDes(tempdub, 1)
result<-LinReg(X,tempdub)
result$beta
result$beta0
可以看到其参数估计的结果与课本P25页表3-5的数据一致,说明该函数的确可以完成余弦趋势模型的设计矩阵变换。