Skip to content

Commit 2e4a72f

Browse files
committed
Deploying to gh-pages from @ 3ee5015 🚀
1 parent 590a3d6 commit 2e4a72f

9 files changed

Lines changed: 170 additions & 44 deletions

File tree

-123 Bytes
Loading
1 Byte
Loading
-22 Bytes
Loading

articles/Chapter09.html

Lines changed: 80 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

articles/Chapter09.md

Lines changed: 88 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,10 @@ Now we can compute their empirical quantiles, and those of the data.
206206

207207
``` r
208208

209-
quants <- c(0.01, 0.05, 0.25, 0.4, 0.5, 0.6, 0.75, 0.95, 0.99)
210-
q_normal <- quantile(yf_normal, quants)
211-
q_t <- quantile(yf_t, quants)
212-
q_y <- quantile(y, quants)
209+
thesequants <- c(0.01, 0.05, 0.25, 0.4, 0.5, 0.6, 0.75, 0.95, 0.99)
210+
q_normal <- quantile(yf_normal, thesequants)
211+
q_t <- quantile(yf_t, thesequants)
212+
q_y <- quantile(y, thesequants)
213213

214214
knitr::kable(round(t(cbind("Data" = q_y, "Student t" = q_t,
215215
"Gaussian" = q_normal)), 3))
@@ -732,7 +732,7 @@ abline(h = 0, lty = 3)
732732

733733
![](Chapter09_files/figure-html/unnamed-chunk-34-1.png)
734734

735-
### Section 2.5.3: Forecasting Volatility via GARCH(1,1) Models
735+
### Section 10.5.3: Forecasting Volatility via GARCH(1,1) Models
736736

737737
We start by defining the parameter transformation.
738738

@@ -757,7 +757,7 @@ loglik <- function(y, theta) {
757757
pars <- unrestricted2restricted(theta)
758758
sigma2 <- rep(NA_real_, length(y))
759759

760-
# initialize at unconditional variance
760+
# Initialize at unconditional variance
761761
sigma2[1] <- pars[1] / (1 - pars[2] - pars[3])
762762

763763
for (i in 2:length(y)) {
@@ -783,28 +783,32 @@ Finally, we define our random walk MH posterior sampler.
783783
``` r
784784

785785
sampler <- function(y, M = 20000L, nburn = 2000L, propsds = rep(0.15, 3)) {
786-
# allocate storage
786+
# Allocate storage
787787
thetas <- matrix(NA_real_, M, 3)
788788
sigma2s <- matrix(NA_real_, M, length(y))
789789

790-
# starting values
790+
# Starting values
791791
theta <- rep(0, 3)
792792
currentlogpost <- loglik(y, theta) + logprior(theta)
793793

794794
naccepts <- 0L
795795
for (m in seq_len(nburn + M)) {
796-
if (m > nburn) sigma2s[m - nburn, ] <- attr(currentlogpost, "sigma2")
797796
prop <- rnorm(3, theta, propsds)
798797
proplogpost <- loglik(y, prop) + logprior(prop)
799798
logR <- proplogpost - currentlogpost
800799

800+
# Accept / reject
801801
if (log(runif(1)) < logR) {
802802
theta <- prop
803803
currentlogpost <- proplogpost
804804
if (m > nburn) naccepts <- naccepts + 1L
805805
}
806806

807-
if (m > nburn) thetas[m - nburn, ] <- theta
807+
# Store
808+
if (m > nburn) {
809+
thetas[m - nburn, ] <- theta
810+
sigma2s[m - nburn, ] <- attr(currentlogpost, "sigma2")
811+
}
808812
}
809813

810814
# Transform back to the usual parameterization
@@ -852,10 +856,10 @@ myhist <- function(dat, breaks = 30, freq = FALSE, ...) {
852856
main = "", ylab = "", ...)
853857
}
854858

855-
layout(matrix(c(1, 1, 1, 2, 3, 4), nrow = 2, byrow = TRUE))
856-
ts.plot(y, col = "gray")
859+
ts.plot(y, col = "gray", ylab = "")
857860
lines(colMeans(sqrt(res$sigma2)))
858-
lines(-colMeans(sqrt(res$sigma2)))
861+
legend("topright", legend = c("Data", bquote(E(sigma[t] ~ "|" ~ bold(y)))),
862+
lty = 1, col = c("gray", 1))
859863
myhist(res$para$alpha0, xlab = expression(alpha[0]))
860864
myhist(res$para$alpha1, xlab = expression(alpha[1]))
861865
myhist(res$para$gamma1, xlab = expression(gamma[1]))
@@ -868,25 +872,88 @@ a function that predicts a number of steps ahead.
868872

869873
``` r
870874

871-
prediction <- function(obj, nahead = 1L) {
872-
sigma2f <- yf <- matrix(NA_real_, obj$ndraws, nahead)
873-
sigma2f[, 1] <- obj$para$alpha0 + obj$para$alpha1 * tail(obj$y, 1)^2 +
874-
obj$para$gamma1 * obj$sigma2[, ncol(obj$sigma2)]
875-
yf[, 1] <- rnorm(obj$ndraws, 0, sqrt(sigma2f[, 1]))
875+
prediction <- function(obj, nahead = 1L, drawsmult = 1L) {
876+
# Allocate storage space
877+
sigma2f <- yf <- matrix(NA_real_, obj$ndraws * drawsmult, nahead)
878+
879+
# Predict one step ahead
880+
sigma2f[, 1] <- rep(obj$para$alpha0 + obj$para$alpha1 * tail(obj$y, 1)^2 +
881+
obj$para$gamma1 * obj$sigma2[, ncol(obj$sigma2)], drawsmult)
882+
yf[, 1] <- rnorm(obj$ndraws * drawsmult, 0, sqrt(sigma2f[, 1]))
883+
884+
# Predict two and more steps ahead
876885
if (nahead > 1L) {
877886
for (i in 2:nahead) {
878887
sigma2f[, i] <- obj$para$alpha0 + obj$para$alpha1 * yf[, i - 1]^2 +
879888
obj$para$gamma1 * sigma2f[, i - 1]
880-
yf[, i] <- rnorm(obj$ndraws, 0, sqrt(sigma2f[, i]))
889+
yf[, i] <- rnorm(obj$ndraws * drawsmult, 0, sqrt(sigma2f[, i]))
881890
}
882891
}
892+
893+
# Return
883894
list(y = yf, sigma2 = sigma2f)
884895
}
885896
```
886897

887-
Let’s try it out.
898+
Let’s try it out. We cut the data a some point, re-estimate and predict.
899+
900+
``` r
901+
902+
cutoff <- 2990
903+
nahead <- 50
904+
ytrain <- head(y, cutoff)
905+
restrain <- sampler(ytrain)
906+
predstatic <- prediction(restrain, nahead, drawsmult = 10)
907+
predstaticquants <- apply(predstatic$y, 2, quantile, thesequants)
908+
```
909+
910+
Alternatively, we might want to do sequential one-step-ahead
911+
predictions. Note that this amounts to re-estimating the model very
912+
often, thus we reduce the number of posterior draws.
888913

889914
``` r
890915

891-
pred <- prediction(res, 2)
916+
predquants <- matrix(NA_real_, nrow = length(thesequants), nahead)
917+
predsigmamean <- rep(NA_real_, nahead)
918+
longrunsdmean <- rep(NA_real_, nahead)
919+
for (i in seq_len(nahead)) {
920+
y1 <- head(y, cutoff - 1 + i)
921+
res1 <- sampler(y1, M = 2000)
922+
longrunsdmean[i] <- mean(sqrt(res1$para$alpha0 /
923+
(1 - res1$para$alpha1 - res1$para$gamma1)))
924+
pred1 <- prediction(res1, 1, drawsmult = 100)
925+
predsigmamean[i] <- mean(sqrt(pred1$sigma2[, 1]))
926+
predquants[, i] <- quantile(pred1$y[, 1], thesequants)
927+
}
892928
```
929+
930+
And visualize.
931+
932+
``` r
933+
934+
plotwindow <- (cutoff - nahead):(cutoff + nahead)
935+
plot(plotwindow, y[plotwindow], xlab = "", ylab = "", col = "gray", type = "l",
936+
main = "Static predictions", ylim = range(predstaticquants, y[plotwindow]))
937+
abline(h = 0, lty = 3, col = "gray")
938+
abline(v = cutoff, lty = 3)
939+
lines((cutoff - nahead):cutoff, colMeans(sqrt(restrain$sigma2[, (cutoff - nahead):cutoff])))
940+
lines(cutoff + 1:nahead, colMeans(sqrt(predstatic$sigma2)))
941+
abline(h = mean(sqrt(restrain$para$alpha0 / (1 - restrain$para$alpha1 - restrain$para$gamma1))),
942+
lty = 2)
943+
for (i in seq_along(thesequants)) {
944+
lines(cutoff + 1:nahead, predstaticquants[i, ], col = 2)
945+
}
946+
947+
plot(plotwindow, y[plotwindow], xlab = "", ylab = "", col = "gray", type = "l",
948+
main = "Dynamic predictions", ylim = range(predstaticquants, y[plotwindow]))
949+
abline(h = 0, lty = 3, col = "gray")
950+
abline(v = cutoff, lty = 3)
951+
lines((cutoff - nahead):cutoff, colMeans(sqrt(restrain$sigma2[, (cutoff - nahead):cutoff])))
952+
lines(cutoff + 1:nahead, predsigmamean)
953+
lines(cutoff + 1:nahead, longrunsdmean, lty = 2)
954+
for (i in seq_along(thesequants)) {
955+
lines(cutoff + 1:nahead, predquants[i, ], col = 2)
956+
}
957+
```
958+
959+
![](Chapter09_files/figure-html/unnamed-chunk-43-1.png)
-15.1 KB
Loading
191 KB
Loading

pkgdown.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ articles:
1313
Chapter09: Chapter09.html
1414
Chapter10: Chapter10.html
1515
Chapter11: Chapter11.html
16-
last_built: 2026-05-22T02:54Z
16+
last_built: 2026-05-22T11:55Z
1717
urls:
1818
reference: https://gregorkastner.github.io/BayesianLearningCode/reference
1919
article: https://gregorkastner.github.io/BayesianLearningCode/articles

search.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)