经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » R语言 » 查看文章
在 R 中估计 GARCH 参数存在的问题(基于 rugarch 包)
来源:cnblogs  作者:xuruilong100  时间:2019/2/20 9:36:35  对本文有异议

在 R 中估计 GARCH 参数存在的问题(基于 rugarch 包)

本文翻译自《Problems in Estimating GARCH Parameters in R (Part 2; rugarch)》

原文链接:https://ntguardian.wordpress.com/2019/01/28/problems-estimating-garch-parameters-r-part-2-rugarch/

导论

这是一篇本应早就写完的博客文章。一年前我写了一篇文章,关于在 R 中估计 GARCH(1, 1) 模型参数时遇到的问题。我记录了参数估计的行为(重点是 \(\beta\)),以及使用 fGarch 计算这些估计值时发现的病态行为。我在 R 社区呼吁帮助,包括通过 R Finance 邮件列表发送我的博客文章。

反馈没有让我感到失望。你可以看到一些邮件列表反馈,并且一些来自 Reddit 的评论也很有帮助,但我认为我得到的最佳反馈来自于我自己的电子邮件。

Dr. Brian G. Peterson 作为 R 金融社区的一员,给我发送了一些发人深思的电子邮件。首先,他告诉我 fGarch 不再是处理 GARCH 模型的首选方案。RMetrics 套件包(包括 fGarch)由 ETH Zürich 的 Diethelm Würtz 教授维护。他在 2016 年的车祸中丧生

Dr. Peterson 建议我研究另外两个用于 GARCH 建模的现代软件包,rugarch(适用于单变量 GARCH 模型)和 rmgarch(适用于多变量 GARCH 模型)。之前我没有听说过这些包(我之所以知道 fGarch 的原因是因为它在由 Shumway 和 Stoffer 编写的时间序列教科书——Time Series Analysis and Its Applications with R Examples 中),所以我非常感谢这个建议。由于我现在对单变量时间序列感兴趣,所以我研究了 rugarch。该软件包似乎具有比 fGarch 更多的功能和函数,这可以解释为什么它似乎更难以使用。然而,包的 vignette 很有帮助,值得打印出来。

Dr. Peterson 对我提出的应用也有一些有趣的评论。他认为,日内数据应优于日间数据,并且模拟数据(包括模拟 GARCH 过程)具有在实际数据中看不到的特质。获取日间数据的便利性(特别是亚洲金融危机期间的 USD/JPY,这是我正在研究的检验统计量的预期应用)激发了我对日间数据的兴趣。不过,他的评论可能会让我重新考虑这个应用。1(我也许应该试图通过 EUR/USD 来检测 2010 年欧元区金融危机。为此,我可以从 HistData.com 获得免费的日内数据。)但是,如果对于小样本而言不能信任标准差的估计,我们的检验统计量仍然会遇到麻烦,因为它涉及小样本的参数估计。

他还警告说,模拟数据表现出在实际数据中看不到的行为。这可能是真的,但模拟数据很重要,因为它可以被认为是统计学家的最佳情景。另外,生成模拟数据的过程的属性是先验已知的,包括生成参数的值,以及哪些假设(例如序列中是否存在结构变化)是真的。这允许对估计器和检验进行健全的检查。这对现实世界来说是不可能的,因为我们没有所需的先验知识

Prof. André Portela Santos 要求我重复模拟,但使用 \(\alpha = 0.6\),因为这些值比我选择的 \(\alpha = \beta = 0.2\) 更常见。这是一个很好的建议,除了 \(\alpha = \beta = 0.2\) 之外,我还会在博文里考虑此范围内的参数。然而,我的模拟暗示当 \(\alpha = \beta = 0.2\) 时,估计算法似乎想要接近较大的 \(\beta\)。我也很惊讶,因为我的导师给我的印象是,\(\alpha\)\(\beta\) 大的 GARCH 过程更难以处理。最后,如果估计量严重有偏,我们可能会看到大多数估计参数位于该范围内,但这并不意味着“正确”值位于该范围内。我的模拟显示 fGarch 很难发现 \(\alpha = \beta = 0.2\),即使这些参数是“真的”。Prof. Santos 的评论让我想要做一个在真实世界中 GARCH 参数的估计是什么样子的元研究(metastudy)。(可能有也可能没有,我没有检查过。如果有人知道,请分享。)

我的导师联系了另一位 GARCH 模型的专家,并获得了一些反馈。据推测,\(\beta\) 的标准差很大,因此参数估计应该有很大的变动范围。即使对于小样本,我的一些模拟也认同这种行为,但同时显示出对 \(\beta = 0\)\(\beta = 1\) 令人不舒服的偏向。正如我假设的那样,这可能是优化程序的结果。

因此,鉴于此反馈,我将进行更多的模拟实验。我不会再研究 fGarchtseries 了,我将专门研究 rugarch。我将探讨包支持的不同优化程序。我不会像我在第一篇文章中那样画图,这些图只是为了表明存在的问题及其严重性。相反,我将考察由不同优化程序生成的估计器的特性。

rugarch 简介

如上所述,rugarch 是一个用于处理 GARCH 模型的软件包,一个主要的用例显然是估计模型的参数。在这里,我将演示如何指定 GARCH 模型、模拟模型的数据以及估计参数。在此之后,我们可以深入了解模拟研究。

  1. library(rugarch)
  1. ## Loading required package: parallel
  2. ##
  3. ## Attaching package: 'rugarch'
  4. ## The following object is masked from 'package:stats':
  5. ##
  6. ## sigma

指定一个 \(\text{GARCH}(1, 1)\) 模型

要使用 GARCH 模型,我们需要指定它。执行此操作的函数是 ugarchspec()。我认为最重要的参数是 variance.modelmean.model

variance.model 是一个命名列表,也许最感兴趣的两个元素是 modelgarchOrdermodel 是一个字符串,指定拟合哪种类型的 GARCH 模型。包支持许多主要的 GARCH 模型(例如 EGARCH、IGARCH 等),对于“普通”GARCH 模型,要将其设置为 sGARCH(或者只是忽略它,标准模型是默认的)。garchOrder 是模型中 ARCH 和 GARCH 部分的阶数向量。

mean.model 允许拟合 ARMA-GARCH 模型,并且像 variance.model 一样接受一个命名列表,最感兴趣的参数是 armaOrderinclude.meanarmaOrder 就像 garchOrder,它是一个指定 ARMA 模型阶数的向量。include.mean 是一个布尔值,如果为 true,则允许模型的 ARMA 部分具有非零均值。

在模拟过程时,我们需要设置参数的值。这是通过 fixed.pars 参数完成的,该参数接受命名列表,列表的元素是数字。它们需要符合函数对于参数的约定。例如,如果我们想设置 \(\text{GARCH}(1,1)\) 模型的参数,我们列表元素的名称应该是 alpha1beta1。如果计划是模拟一个模型,则应以这种方式设置模型中的每个参数。

还有其他有趣的参数,但我只关注这些,因为默认指定是 ARMA-GARCH 模型,ARMA 阶数为 \((1,1)\),非零均值,并且 GARCH 模型的阶数是 \((1, 1)\)。这不是我想要的普通 \(\text{GARCH}(1,1)\) 模型,所以我几乎总是要修改它。

  1. spec1 <- ugarchspec(
  2. mean.model = list(
  3. armaOrder = c(0,0), include.mean = FALSE),
  4. fixed.pars = list(
  5. "omega" = 0.2, "alpha1" = 0.2, "beta1" = 0.2))
  6. spec2 <- ugarchspec(
  7. mean.model = list(
  8. armaOrder = c(0,0), include.mean = FALSE),
  9. fixed.pars = list(
  10. "omega" = 0.2, "alpha1" = 0.1, "beta1" = 0.7))
  11. show(spec1)
  1. ##
  2. ## *---------------------------------*
  3. ## * GARCH Model Spec *
  4. ## *---------------------------------*
  5. ##
  6. ## Conditional Variance Dynamics
  7. ## ------------------------------------
  8. ## GARCH Model : sGARCH(1,1)
  9. ## Variance Targeting : FALSE
  10. ##
  11. ## Conditional Mean Dynamics
  12. ## ------------------------------------
  13. ## Mean Model : ARFIMA(0,0,0)
  14. ## Include Mean : FALSE
  15. ## GARCH-in-Mean : FALSE
  16. ##
  17. ## Conditional Distribution
  18. ## ------------------------------------
  19. ## Distribution : norm
  20. ## Includes Skew : FALSE
  21. ## Includes Shape : FALSE
  22. ## Includes Lambda : FALSE
  1. show(spec2)
  1. ##
  2. ## *---------------------------------*
  3. ## * GARCH Model Spec *
  4. ## *---------------------------------*
  5. ##
  6. ## Conditional Variance Dynamics
  7. ## ------------------------------------
  8. ## GARCH Model : sGARCH(1,1)
  9. ## Variance Targeting : FALSE
  10. ##
  11. ## Conditional Mean Dynamics
  12. ## ------------------------------------
  13. ## Mean Model : ARFIMA(0,0,0)
  14. ## Include Mean : FALSE
  15. ## GARCH-in-Mean : FALSE
  16. ##
  17. ## Conditional Distribution
  18. ## ------------------------------------
  19. ## Distribution : norm
  20. ## Includes Skew : FALSE
  21. ## Includes Shape : FALSE
  22. ## Includes Lambda : FALSE

模拟一个 GARCH 过程

函数 ugarchpath() 模拟由 ugarchspec() 指定的 GARCH 模型。该函数首先需要由 ugarchspec() 创建的指定对象。参数 n.simn.start 分别指定过程的大小和预热期的长度(分别默认为 1000 和 0。我强烈建议将预热期设置为至少 500,但我设置为 1000)。该函数创建的对象不仅包含模拟序列,还包含残差和 \(\sigma_t\)

rseed 参数控制函数用于生成数据的随机种子。请注意,此函数会有效地忽略 set.seed(),因此如果需要一致的结果,则需要设置此参数。

这些对象相应的 plot() 方法并不完全透明。它可以创建一些图,当在命令行中对 uGARCHpath 对象调用 plot() 时,系统会提示用户输入与所需图形对应的数字。这有时挺痛苦,所以不要忘记将所需的编号传递给 which 参数以避免提示,设置 which = 2 将正好给出序列的图。

  1. old_par <- par()
  2. par(mfrow = c(2, 2))
  3. x_obj <- ugarchpath(
  4. spec1, n.sim = 1000, n.start = 1000, rseed = 111217)
  5. show(x_obj)
  1. ##
  2. ## *------------------------------------*
  3. ## * GARCH Model Path Simulation *
  4. ## *------------------------------------*
  5. ## Model: sGARCH
  6. ## Horizon: 1000
  7. ## Simulations: 1
  8. ## Seed Sigma2.Mean Sigma2.Min Sigma2.Max Series.Mean
  9. ## sim1 111217 0.332 0.251 0.915 0.000165
  10. ## Mean(All) 0 0.332 0.251 0.915 0.000165
  11. ## Unconditional NA 0.333 NA NA 0.000000
  12. ## Series.Min Series.Max
  13. ## sim1 -1.76 1.62
  14. ## Mean(All) -1.76 1.62
  15. ## Unconditional NA NA
  1. for (i in 1:4)
  2. {
  3. plot(x_obj, which = i)
  4. }

  1. par(old_par)
  1. ## Warning in par(old_par): graphical parameter "cin" cannot be set
  2. ## Warning in par(old_par): graphical parameter "cra" cannot be set
  3. ## Warning in par(old_par): graphical parameter "csi" cannot be set
  4. ## Warning in par(old_par): graphical parameter "cxy" cannot be set
  5. ## Warning in par(old_par): graphical parameter "din" cannot be set
  6. ## Warning in par(old_par): graphical parameter "page" cannot be set
  1. # The actual series
  2. x1 <- x_obj@path$seriesSim
  3. plot.ts(x1)

拟合一个 \(\text{GARCH}(1,1)\) 模型

ugarchfit() 函数拟合 GARCH 模型。该函数需要指定和数据集。solver 参数接受一个字符串,说明要使用哪个数值优化器来寻找参数估计值。函数的大多数参数管理数值优化器的接口。特别是,solver.control 可以接受一个传递给优化器的参数列表。我们稍后会更详细地讨论这个问题。

用于生成模拟数据的指定将不适用于 ugarchfit(),因为它包含其参数的固定值。在我的情况下,我将需要创建第二个指定对象。

  1. spec <- ugarchspec(
  2. mean.model = list(armaOrder = c(0, 0), include.mean = FALSE))
  3. fit <- ugarchfit(spec, data = x1)
  4. show(fit)
  1. ##
  2. ## *---------------------------------*
  3. ## * GARCH Model Fit *
  4. ## *---------------------------------*
  5. ##
  6. ## Conditional Variance Dynamics
  7. ## -----------------------------------
  8. ## GARCH Model : sGARCH(1,1)
  9. ## Mean Model : ARFIMA(0,0,0)
  10. ## Distribution : norm
  11. ##
  12. ## Optimal Parameters
  13. ## ------------------------------------
  14. ## Estimate Std. Error t value Pr(>|t|)
  15. ## omega 0.000713 0.001258 0.56696 0.57074
  16. ## alpha1 0.002905 0.003714 0.78206 0.43418
  17. ## beta1 0.994744 0.000357 2786.08631 0.00000
  18. ##
  19. ## Robust Standard Errors:
  20. ## Estimate Std. Error t value Pr(>|t|)
  21. ## omega 0.000713 0.001217 0.58597 0.55789
  22. ## alpha1 0.002905 0.003661 0.79330 0.42760
  23. ## beta1 0.994744 0.000137 7250.45186 0.00000
  24. ##
  25. ## LogLikelihood : -860.486
  26. ##
  27. ## Information Criteria
  28. ## ------------------------------------
  29. ##
  30. ## Akaike 1.7270
  31. ## Bayes 1.7417
  32. ## Shibata 1.7270
  33. ## Hannan-Quinn 1.7326
  34. ##
  35. ## Weighted Ljung-Box Test on Standardized Residuals
  36. ## ------------------------------------
  37. ## statistic p-value
  38. ## Lag[1] 3.998 0.04555
  39. ## Lag[2*(p+q)+(p+q)-1][2] 4.507 0.05511
  40. ## Lag[4*(p+q)+(p+q)-1][5] 9.108 0.01555
  41. ## d.o.f=0
  42. ## H0 : No serial correlation
  43. ##
  44. ## Weighted Ljung-Box Test on Standardized Squared Residuals
  45. ## ------------------------------------
  46. ## statistic p-value
  47. ## Lag[1] 29.12 6.786e-08
  48. ## Lag[2*(p+q)+(p+q)-1][5] 31.03 1.621e-08
  49. ## Lag[4*(p+q)+(p+q)-1][9] 32.26 1.044e-07
  50. ## d.o.f=2
  51. ##
  52. ## Weighted ARCH LM Tests
  53. ## ------------------------------------
  54. ## Statistic Shape Scale P-Value
  55. ## ARCH Lag[3] 1.422 0.500 2.000 0.2331
  56. ## ARCH Lag[5] 2.407 1.440 1.667 0.3882
  57. ## ARCH Lag[7] 2.627 2.315 1.543 0.5865
  58. ##
  59. ## Nyblom stability test
  60. ## ------------------------------------
  61. ## Joint Statistic: 0.9518
  62. ## Individual Statistics:
  63. ## omega 0.3296
  64. ## alpha1 0.2880
  65. ## beta1 0.3195
  66. ##
  67. ## Asymptotic Critical Values (10% 5% 1%)
  68. ## Joint Statistic: 0.846 1.01 1.35
  69. ## Individual Statistic: 0.35 0.47 0.75
  70. ##
  71. ## Sign Bias Test
  72. ## ------------------------------------
  73. ## t-value prob sig
  74. ## Sign Bias 0.3946 6.933e-01
  75. ## Negative Sign Bias 3.2332 1.264e-03 ***
  76. ## Positive Sign Bias 4.2142 2.734e-05 ***
  77. ## Joint Effect 28.2986 3.144e-06 ***
  78. ##
  79. ##
  80. ## Adjusted Pearson Goodness-of-Fit Test:
  81. ## ------------------------------------
  82. ## group statistic p-value(g-1)
  83. ## 1 20 20.28 0.3779
  84. ## 2 30 26.54 0.5965
  85. ## 3 40 36.56 0.5817
  86. ## 4 50 47.10 0.5505
  87. ##
  88. ##
  89. ## Elapsed time : 2.60606
  1. par(mfrow = c(3, 4))
  2. for (i in 1:12)
  3. {
  4. plot(fit, which = i)
  5. }
  1. ##
  2. ## please wait...calculating quantiles...

  1. par(old_par)
  1. ## Warning in par(old_par): graphical parameter "cin" cannot be set
  2. ## Warning in par(old_par): graphical parameter "cra" cannot be set
  3. ## Warning in par(old_par): graphical parameter "csi" cannot be set
  4. ## Warning in par(old_par): graphical parameter "cxy" cannot be set
  5. ## Warning in par(old_par): graphical parameter "din" cannot be set
  6. ## Warning in par(old_par): graphical parameter "page" cannot be set

注意估计的参数和标准差?即使对于 1000 的样本大小,估计也与“正确”数字相去甚远,并且基于估计标准差的合理置信区间不包含正确的值。看起来我在上一篇文章中记录的问题并没有消失。

出于好奇,在 Prof. Santos 建议范围的其他指定会发生什么?

  1. x_obj <- ugarchpath(
  2. spec2, n.start = 1000, rseed = 111317)
  3. x2 <- x_obj@path$seriesSim
  4. fit <- ugarchfit(spec, x2)
  5. show(fit)
  1. ##
  2. ## *---------------------------------*
  3. ## * GARCH Model Fit *
  4. ## *---------------------------------*
  5. ##
  6. ## Conditional Variance Dynamics
  7. ## -----------------------------------
  8. ## GARCH Model : sGARCH(1,1)
  9. ## Mean Model : ARFIMA(0,0,0)
  10. ## Distribution : norm
  11. ##
  12. ## Optimal Parameters
  13. ## ------------------------------------
  14. ## Estimate Std. Error t value Pr(>|t|)
  15. ## omega 0.001076 0.002501 0.43025 0.66701
  16. ## alpha1 0.001992 0.002948 0.67573 0.49921
  17. ## beta1 0.997008 0.000472 2112.23364 0.00000
  18. ##
  19. ## Robust Standard Errors:
  20. ## Estimate Std. Error t value Pr(>|t|)
  21. ## omega 0.001076 0.002957 0.36389 0.71594
  22. ## alpha1 0.001992 0.003510 0.56767 0.57026
  23. ## beta1 0.997008 0.000359 2777.24390 0.00000
  24. ##
  25. ## LogLikelihood : -1375.951
  26. ##
  27. ## Information Criteria
  28. ## ------------------------------------
  29. ##
  30. ## Akaike 2.7579
  31. ## Bayes 2.7726
  32. ## Shibata 2.7579
  33. ## Hannan-Quinn 2.7635
  34. ##
  35. ## Weighted Ljung-Box Test on Standardized Residuals
  36. ## ------------------------------------
  37. ## statistic p-value
  38. ## Lag[1] 0.9901 0.3197
  39. ## Lag[2*(p+q)+(p+q)-1][2] 1.0274 0.4894
  40. ## Lag[4*(p+q)+(p+q)-1][5] 3.4159 0.3363
  41. ## d.o.f=0
  42. ## H0 : No serial correlation
  43. ##
  44. ## Weighted Ljung-Box Test on Standardized Squared Residuals
  45. ## ------------------------------------
  46. ## statistic p-value
  47. ## Lag[1] 3.768 0.05226
  48. ## Lag[2*(p+q)+(p+q)-1][5] 4.986 0.15424
  49. ## Lag[4*(p+q)+(p+q)-1][9] 7.473 0.16272
  50. ## d.o.f=2
  51. ##
  52. ## Weighted ARCH LM Tests
  53. ## ------------------------------------
  54. ## Statistic Shape Scale P-Value
  55. ## ARCH Lag[3] 0.2232 0.500 2.000 0.6366
  56. ## ARCH Lag[5] 0.4793 1.440 1.667 0.8897
  57. ## ARCH Lag[7] 2.2303 2.315 1.543 0.6686
  58. ##
  59. ## Nyblom stability test
  60. ## ------------------------------------
  61. ## Joint Statistic: 0.3868
  62. ## Individual Statistics:
  63. ## omega 0.2682
  64. ## alpha1 0.2683
  65. ## beta1 0.2669
  66. ##
  67. ## Asymptotic Critical Values (10% 5% 1%)
  68. ## Joint Statistic: 0.846 1.01 1.35
  69. ## Individual Statistic: 0.35 0.47 0.75
  70. ##
  71. ## Sign Bias Test
  72. ## ------------------------------------
  73. ## t-value prob sig
  74. ## Sign Bias 0.5793 0.5625
  75. ## Negative Sign Bias 1.3358 0.1819
  76. ## Positive Sign Bias 1.5552 0.1202
  77. ## Joint Effect 5.3837 0.1458
  78. ##
  79. ##
  80. ## Adjusted Pearson Goodness-of-Fit Test:
  81. ## ------------------------------------
  82. ## group statistic p-value(g-1)
  83. ## 1 20 24.24 0.1871
  84. ## 2 30 30.50 0.3894
  85. ## 3 40 38.88 0.4753
  86. ## 4 50 48.40 0.4974
  87. ##
  88. ##
  89. ## Elapsed time : 2.841597

没有更好。现在让我们看看当我们使用不同的优化算法时会发生什么。

rugarch 中的优化与参数估计

优化器的选择

ugarchfit() 的默认参数很好地找到了我称之为模型 2 的适当参数(其中 \(\alpha = 0.1\)\(\beta = 0.7\)),但不适用于模型 1(\(\alpha = \beta = 0.2\))。我想知道的是何时一个求解器能击败另一个求解器。

正如 Vivek Rao2R-SIG-Finance 邮件列表中所说,“最佳”估计是最大化似然函数(或等效地,对数似然函数)的估计,在上一篇文章中我忽略了检查对数似然函数值。在这里,我将看到哪些优化程序导致最大对数似然。

下面是一个辅助函数,它简化了拟合 GARCH 模型参数、提取对数似然、参数值和标准差的过程,同时允许将不同的值传递给 solversolver.control

  1. evalSolverFit <- function(spec, data,
  2. solver = "solnp",
  3. solver.control = list())
  4. {
  5. # Calls ugarchfit(spec, data, solver, solver.control), and returns a vector
  6. # containing the log likelihood, parameters, and parameter standard errors.
  7. # Parameters are equivalent to those seen in ugarchfit(). If the solver fails
  8. # to converge, NA will be returned
  9. vec <- NA
  10. tryCatch(
  11. {
  12. fit <- ugarchfit(
  13. spec = spec,
  14. data = data,
  15. solver = solver,
  16. solver.control = solver.control)
  17. coef_se_names <- paste(
  18. "se", names(fit@fit$coef), sep = ".")
  19. se <- fit@fit$se.coef
  20. names(se) <- coef_se_names
  21. robust_coef_se_names <- paste(
  22. "robust.se", names(fit@fit$coef), sep = ".")
  23. robust.se <- fit@fit$robust.se.coef
  24. names(robust.se) <- robust_coef_se_names
  25. vec <- c(fit@fit$coef, se, robust.se)
  26. vec["LLH"] <- fit@fit$LLH
  27. },
  28. error = function(w) { NA })
  29. return(vec)
  30. }

下面我列出将要考虑的所有优化方案。我只使用 solver.control,但可能有其他参数可以帮助数值优化算法,即 numderiv.control,它们作为控制参数传递给负责标准差计算的数值算法。这利用了包含 numDeriv 的包,它执行数值微分。

  1. solvers <- list(
  2. # A list of lists where each sublist contains parameters to
  3. # pass to a solver
  4. list("solver" = "nlminb", "solver.control" = list()),
  5. list("solver" = "solnp", "solver.control" = list()),
  6. list("solver" = "lbfgs", "solver.control" = list()),
  7. list("solver" = "gosolnp",
  8. "solver.control" = list("n.restarts" = 100, "n.sim" = 100)),
  9. list("solver" = "hybrid", "solver.control" = list()),
  10. list("solver" = "nloptr", "solver.control" = list("solver" = 1)), # COBYLA
  11. list("solver" = "nloptr", "solver.control" = list("solver" = 2)), # BOBYQA
  12. list("solver" = "nloptr", "solver.control" = list("solver" = 3)), # PRAXIS
  13. list("solver" = "nloptr",
  14. "solver.control" = list("solver" = 4)), # NELDERMEAD
  15. list("solver" = "nloptr", "solver.control" = list("solver" = 5)), # SBPLX
  16. list("solver" = "nloptr",
  17. "solver.control" = list("solver" = 6)), # AUGLAG+COBYLA
  18. list("solver" = "nloptr",
  19. "solver.control" = list("solver" = 7)), # AUGLAG+BOBYQA
  20. list("solver" = "nloptr",
  21. "solver.control" = list("solver" = 8)), # AUGLAG+PRAXIS
  22. list("solver" = "nloptr",
  23. "solver.control" = list("solver" = 9)), # AUGLAG+NELDERMEAD
  24. list("solver" = "nloptr",
  25. "solver.control" = list("solver" = 10)) # AUGLAG+SBPLX
  26. )
  27. tags <- c(
  28. # Names for the above list
  29. "nlminb",
  30. "solnp",
  31. "lbfgs",
  32. "gosolnp",
  33. "hybrid",
  34. "nloptr+COBYLA",
  35. "nloptr+BOBYQA",
  36. "nloptr+PRAXIS",
  37. "nloptr+NELDERMEAD",
  38. "nloptr+SBPLX",
  39. "nloptr+AUGLAG+COBYLA",
  40. "nloptr+AUGLAG+BOBYQA",
  41. "nloptr+AUGLAG+PRAXIS",
  42. "nloptr+AUGLAG+NELDERMEAD",
  43. "nloptr+AUGLAG+SBPLX"
  44. )
  45. names(solvers) <- tags

现在让我们进行优化计算选择的交叉射击(gauntlet),看看哪个算法产生的估计在模型 1 生成的数据上达到最大的对数似然。遗憾的是,lbfgs 方法(Broyden-Fletcher-Goldfarb-Shanno 方法的低存储版本)在这个序列上没有收敛,所以我省略了它。

  1. optMethodCompare <- function(data,
  2. spec,
  3. solvers)
  4. {
  5. # Runs all solvers in a list for a dataset
  6. #
  7. # Args:
  8. # data: An object to pass to ugarchfit's data parameter containing the data
  9. # to fit
  10. # spec: A specification created by ugarchspec to pass to ugarchfit
  11. # solvers: A list of lists containing strings of solvers and a list for
  12. # solver.control
  13. #
  14. # Return:
  15. # A matrix containing the result of the solvers (including parameters, se's,
  16. # and LLH)
  17. model_solutions <- lapply(
  18. solvers,
  19. function(s)
  20. {
  21. args <- s
  22. args[["spec"]] <- spec
  23. args[["data"]] <- data
  24. res <- do.call(evalSolverFit, args = args)
  25. return(res)
  26. })
  27. model_solutions <- do.call(
  28. rbind, model_solutions)
  29. return(model_solutions)
  30. }
  31. round(
  32. optMethodCompare(
  33. x1, spec, solvers[c(1:2, 4:15)]), digits = 4)
  1. ## omega alpha1 beta1 se.omega se.alpha1 se.beta1 robust.se.omega robust.se.alpha1 robust.se.beta1 LLH
  2. ## ------------------------- ------- ------- ------- --------- ---------- --------- ---------------- ----------------- ---------------- ----------
  3. ## nlminb 0.2689 0.1774 0.0000 0.0787 0.0472 0.2447 0.0890 0.0352 0.2830 -849.6927
  4. ## solnp 0.0007 0.0029 0.9947 0.0013 0.0037 0.0004 0.0012 0.0037 0.0001 -860.4860
  5. ## gosolnp 0.2689 0.1774 0.0000 0.0787 0.0472 0.2446 0.0890 0.0352 0.2828 -849.6927
  6. ## hybrid 0.0007 0.0029 0.9947 0.0013 0.0037 0.0004 0.0012 0.0037 0.0001 -860.4860
  7. ## nloptr+COBYLA 0.0006 0.0899 0.9101 0.0039 0.0306 0.0370 0.0052 0.0527 0.0677 -871.5006
  8. ## nloptr+BOBYQA 0.0003 0.0907 0.9093 0.0040 0.0298 0.0375 0.0057 0.0532 0.0718 -872.3436
  9. ## nloptr+PRAXIS 0.2689 0.1774 0.0000 0.0786 0.0472 0.2444 0.0888 0.0352 0.2823 -849.6927
  10. ## nloptr+NELDERMEAD 0.0010 0.0033 0.9935 0.0013 0.0039 0.0004 0.0013 0.0038 0.0001 -860.4845
  11. ## nloptr+SBPLX 0.0010 0.1000 0.9000 0.0042 0.0324 0.0386 0.0055 0.0536 0.0680 -872.2736
  12. ## nloptr+AUGLAG+COBYLA 0.0006 0.0899 0.9101 0.0039 0.0306 0.0370 0.0052 0.0527 0.0677 -871.5006
  13. ## nloptr+AUGLAG+BOBYQA 0.0003 0.0907 0.9093 0.0040 0.0298 0.0375 0.0057 0.0532 0.0718 -872.3412
  14. ## nloptr+AUGLAG+PRAXIS 0.1246 0.1232 0.4948 0.0620 0.0475 0.2225 0.0701 0.0439 0.2508 -851.0547
  15. ## nloptr+AUGLAG+NELDERMEAD 0.2689 0.1774 0.0000 0.0786 0.0472 0.2445 0.0889 0.0352 0.2826 -849.6927
  16. ## nloptr+AUGLAG+SBPLX 0.0010 0.1000 0.9000 0.0042 0.0324 0.0386 0.0055 0.0536 0.0680 -872.2736

根据最大似然准则,“最优”结果是由 gosolnp 实现的。结果有一个不幸的属性——\(\beta \approx 0\),这当然不是正确的,但至少 \(\beta\) 的标准差会创建一个包含 \(\beta\) 真值的置信区间。其中,我的首选估计是由 AUGLAG + PRAXIS 生成的,因为 \(\beta\) 似乎是合理的,事实上估计都接近事实(至少在置信区间包含真值的意义上),但不幸的是,即使它们是最合理的,估计并没有最大化对数似然。

如果我们看一下模型 2,我们会看到什么?同样,lbfgs 没有收敛,所以我省略忽略了它。不幸的是,nlminb 也没有收敛,因此也必须省略。

  1. round(
  2. optMethodCompare(
  3. x2, spec, solvers[c(2, 4:15)]), digits = 4)
  1. ## omega alpha1 beta1 se.omega se.alpha1 se.beta1 robust.se.omega robust.se.alpha1 robust.se.beta1 LLH
  2. ## ------------------------- ------- ------- ------- --------- ---------- --------- ---------------- ----------------- ---------------- ----------
  3. ## solnp 0.0011 0.0020 0.9970 0.0025 0.0029 0.0005 0.0030 0.0035 0.0004 -1375.951
  4. ## gosolnp 0.0011 0.0020 0.9970 0.0025 0.0029 0.0005 0.0030 0.0035 0.0004 -1375.951
  5. ## hybrid 0.0011 0.0020 0.9970 0.0025 0.0029 0.0005 0.0030 0.0035 0.0004 -1375.951
  6. ## nloptr+COBYLA 0.0016 0.0888 0.9112 0.0175 0.0619 0.0790 0.0540 0.2167 0.2834 -1394.529
  7. ## nloptr+BOBYQA 0.0010 0.0892 0.9108 0.0194 0.0659 0.0874 0.0710 0.2631 0.3572 -1395.310
  8. ## nloptr+PRAXIS 0.5018 0.0739 0.3803 0.3178 0.0401 0.3637 0.2777 0.0341 0.3225 -1373.632
  9. ## nloptr+NELDERMEAD 0.0028 0.0026 0.9944 0.0028 0.0031 0.0004 0.0031 0.0035 0.0001 -1375.976
  10. ## nloptr+SBPLX 0.0029 0.1000 0.9000 0.0146 0.0475 0.0577 0.0275 0.1108 0.1408 -1395.807
  11. ## nloptr+AUGLAG+COBYLA 0.0016 0.0888 0.9112 0.0175 0.0619 0.0790 0.0540 0.2167 0.2834 -1394.529
  12. ## nloptr+AUGLAG+BOBYQA 0.0010 0.0892 0.9108 0.0194 0.0659 0.0874 0.0710 0.2631 0.3572 -1395.310
  13. ## nloptr+AUGLAG+PRAXIS 0.5018 0.0739 0.3803 0.3178 0.0401 0.3637 0.2777 0.0341 0.3225 -1373.632
  14. ## nloptr+AUGLAG+NELDERMEAD 0.0001 0.0000 1.0000 0.0003 0.0003 0.0000 0.0004 0.0004 0.0000 -1375.885
  15. ## nloptr+AUGLAG+SBPLX 0.0029 0.1000 0.9000 0.0146 0.0475 0.0577 0.0275 0.1108 0.1408 -1395.807

这里是 PRAXISAUGLAG + PRAXIS 给出了“最优”结果,只有这两种方法做到了。其他优化器给出了明显糟糕的结果。也就是说,“最优”解在参数为非零、置信区间包含正确值上是首选的。

如果我们将样本限制为 100,会发生什么?(lbfgs 仍然不起作用。)

  1. round(
  2. optMethodCompare(
  3. x1[1:100], spec, solvers[c(1:2, 4:15)]), digits = 4)
  1. ## omega alpha1 beta1 se.omega se.alpha1 se.beta1 robust.se.omega robust.se.alpha1 robust.se.beta1 LLH
  2. ## ------------------------- ------- ------- ------- --------- ---------- --------- ---------------- ----------------- ---------------- ---------
  3. ## nlminb 0.0451 0.2742 0.5921 0.0280 0.1229 0.1296 0.0191 0.0905 0.0667 -80.6587
  4. ## solnp 0.0451 0.2742 0.5921 0.0280 0.1229 0.1296 0.0191 0.0905 0.0667 -80.6587
  5. ## gosolnp 0.0451 0.2742 0.5921 0.0280 0.1229 0.1296 0.0191 0.0905 0.0667 -80.6587
  6. ## hybrid 0.0451 0.2742 0.5921 0.0280 0.1229 0.1296 0.0191 0.0905 0.0667 -80.6587
  7. ## nloptr+COBYLA 0.0007 0.1202 0.8798 0.0085 0.0999 0.0983 0.0081 0.1875 0.1778 -85.3121
  8. ## nloptr+BOBYQA 0.0005 0.1190 0.8810 0.0085 0.0994 0.0992 0.0084 0.1892 0.1831 -85.3717
  9. ## nloptr+PRAXIS 0.0451 0.2742 0.5921 0.0280 0.1229 0.1296 0.0191 0.0905 0.0667 -80.6587
  10. ## nloptr+NELDERMEAD 0.0451 0.2742 0.5920 0.0281 0.1230 0.1297 0.0191 0.0906 0.0667 -80.6587
  11. ## nloptr+SBPLX 0.0433 0.2740 0.5998 0.0269 0.1237 0.1268 0.0182 0.0916 0.0648 -80.6616
  12. ## nloptr+AUGLAG+COBYLA 0.0007 0.1202 0.8798 0.0085 0.0999 0.0983 0.0081 0.1875 0.1778 -85.3121
  13. ## nloptr+AUGLAG+BOBYQA 0.0005 0.1190 0.8810 0.0085 0.0994 0.0992 0.0084 0.1892 0.1831 -85.3717
  14. ## nloptr+AUGLAG+PRAXIS 0.0451 0.2742 0.5921 0.0280 0.1229 0.1296 0.0191 0.0905 0.0667 -80.6587
  15. ## nloptr+AUGLAG+NELDERMEAD 0.0451 0.2742 0.5921 0.0280 0.1229 0.1296 0.0191 0.0905 0.0667 -80.6587
  16. ## nloptr+AUGLAG+SBPLX 0.0450 0.2742 0.5924 0.0280 0.1230 0.1295 0.0191 0.0906 0.0666 -80.6587
  1. round(
  2. optMethodCompare(
  3. x2[1:100], spec, solvers[c(1:2, 4:15)]), digits = 4)
  1. ## omega alpha1 beta1 se.omega se.alpha1 se.beta1 robust.se.omega robust.se.alpha1 robust.se.beta1 LLH
  2. ## ------------------------- ------- ------- ------- --------- ---------- --------- ---------------- ----------------- ---------------- ----------
  3. ## nlminb 0.7592 0.0850 0.0000 2.1366 0.4813 3.0945 7.5439 1.7763 11.0570 -132.4614
  4. ## solnp 0.0008 0.0000 0.9990 0.0291 0.0417 0.0066 0.0232 0.0328 0.0034 -132.9182
  5. ## gosolnp 0.0537 0.0000 0.9369 0.0521 0.0087 0.0713 0.0430 0.0012 0.0529 -132.9124
  6. ## hybrid 0.0008 0.0000 0.9990 0.0291 0.0417 0.0066 0.0232 0.0328 0.0034 -132.9182
  7. ## nloptr+COBYLA 0.0014 0.0899 0.9101 0.0259 0.0330 0.1192 0.0709 0.0943 0.1344 -135.7495
  8. ## nloptr+BOBYQA 0.0008 0.0905 0.9095 0.0220 0.0051 0.1145 0.0687 0.0907 0.1261 -135.8228
  9. ## nloptr+PRAXIS 0.0602 0.0000 0.9293 0.0522 0.0088 0.0773 0.0462 0.0015 0.0565 -132.9125
  10. ## nloptr+NELDERMEAD 0.0024 0.0000 0.9971 0.0473 0.0629 0.0116 0.0499 0.0680 0.0066 -132.9186
  11. ## nloptr+SBPLX 0.0027 0.1000 0.9000 0.0238 0.0493 0.1308 0.0769 0.1049 0.1535 -135.9175
  12. ## nloptr+AUGLAG+COBYLA 0.0014 0.0899 0.9101 0.0259 0.0330 0.1192 0.0709 0.0943 0.1344 -135.7495
  13. ## nloptr+AUGLAG+BOBYQA 0.0008 0.0905 0.9095 0.0221 0.0053 0.1145 0.0687 0.0907 0.1262 -135.8226
  14. ## nloptr+AUGLAG+PRAXIS 0.0602 0.0000 0.9294 0.0523 0.0090 0.0771 0.0462 0.0014 0.0565 -132.9125
  15. ## nloptr+AUGLAG+NELDERMEAD 0.0000 0.0000 0.9999 0.0027 0.0006 0.0005 0.0013 0.0004 0.0003 -132.9180
  16. ## nloptr+AUGLAG+SBPLX 0.0027 0.1000 0.9000 0.0238 0.0493 0.1308 0.0769 0.1049 0.1535 -135.9175

结果并不令人兴奋。多个求解器获得了模型 1 生成序列的“最佳”结果,同时 \(\omega\) 的 95% 置信区间(CI)不包含 \(\omega\) 的真实值,尽管其他的 CI 将包含其真实值。对于由模型 2 生成的序列,最佳结果是由 nlminb 求解器实现的,但参数值不合理,标准差很大。至少 CI 将包含正确值。

从这里开始,我们不应再仅仅关注两个序列,而是在两个模型生成的许多模拟序列中研究这些方法的表现。这篇文章中的模拟对于我的笔记本电脑而言计算量太大,因此我将使用我院系的超级计算机来执行它们,利用其多核进行并行计算。

  1. library(foreach)
  2. library(doParallel)
  3. logfile <- ""
  4. # logfile <- "outfile.log"
  5. # if (!file.exists(logfile)) {
  6. # file.create(logfile)
  7. # }
  8. cl <- makeCluster(
  9. detectCores() - 1, outfile = logfile)
  10. registerDoParallel(cl)
  11. optMethodSims <- function(
  12. gen_spec,
  13. n.sim = 1000,
  14. m.sim = 1000,
  15. fit_spec = ugarchspec(
  16. mean.model = list(
  17. armaOrder = c(0,0), include.mean = FALSE)),
  18. solvers = list(
  19. "solnp" = list(
  20. "solver" = "solnp", "solver.control" = list())),
  21. rseed = NA, verbose = FALSE)
  22. {
  23. # Performs simulations in parallel of GARCH processes via rugarch and returns
  24. # a list with the results of different optimization routines
  25. #
  26. # Args:
  27. # gen_spec: The specification for generating a GARCH sequence, produced by
  28. # ugarchspec
  29. # n.sim: An integer denoting the length of the simulated series
  30. # m.sim: An integer for the number of simulated sequences to generate
  31. # fit_spec: A ugarchspec specification for the model to fit
  32. # solvers: A list of lists containing strings of solvers and a list for
  33. # solver.control
  34. # rseed: Optional seeding value(s) for the random number generator. For
  35. # m.sim>1, it is possible to provide either a single seed to
  36. # initialize all values, or one seed per separate simulation (i.e.
  37. # m.sim seeds). However, in the latter case this may result in some
  38. # slight overhead depending on how large m.sim is
  39. # verbose: Boolean for whether to write data tracking the progress of the
  40. # loop into an output file
  41. # outfile: A string for the file to store verbose output to (relevant only
  42. # if verbose is TRUE)
  43. #
  44. # Return:
  45. # A list containing the result of calling optMethodCompare on each generated
  46. # sequence
  47. fits <- foreach(
  48. i = 1:m.sim,
  49. .packages = c("rugarch"),
  50. .export = c(
  51. "optMethodCompare", "evalSolverFit")) %dopar%
  52. {
  53. if (is.na(rseed))
  54. {
  55. newseed <- NA
  56. }
  57. else if (is.vector(rseed))
  58. {
  59. newseed <- rseed[i]
  60. }
  61. else
  62. {
  63. newseed <- rseed + i - 1
  64. }
  65. if (verbose)
  66. {
  67. cat(as.character(Sys.time()), ": Now on simulation ", i, "\n")
  68. }
  69. sim <- ugarchpath(
  70. gen_spec, n.sim = n.sim, n.start = 1000,
  71. m.sim = 1, rseed = newseed)
  72. x <- sim@path$seriesSim
  73. optMethodCompare(
  74. x, spec = fit_spec, solvers = solvers)
  75. }
  76. return(fits)
  77. }
  78. # Specification 1 first
  79. spec1_n100 <- optMethodSims(
  80. spec1, n.sim = 100, m.sim = 1000,
  81. solvers = solvers, verbose = TRUE)
  82. spec1_n500 <- optMethodSims(
  83. spec1, n.sim = 500, m.sim = 1000,
  84. solvers = solvers, verbose = TRUE)
  85. spec1_n1000 <- optMethodSims(
  86. spec1, n.sim = 1000, m.sim = 1000,
  87. solvers = solvers, verbose = TRUE)
  88. # Specification 2 next
  89. spec2_n100 <- optMethodSims(
  90. spec2, n.sim = 100, m.sim = 1000,
  91. solvers = solvers, verbose = TRUE)
  92. spec2_n500 <- optMethodSims(
  93. spec2, n.sim = 500, m.sim = 1000,
  94. solvers = solvers, verbose = TRUE)
  95. spec2_n1000 <- optMethodSims(
  96. spec2, n.sim = 1000, m.sim = 1000,
  97. solvers = solvers, verbose = TRUE)

以下是一组辅助函数,用于我要进行的分析。

  1. optMethodSims_getAllVals <- function(param,
  2. solver,
  3. reslist)
  4. {
  5. # Get all values for a parameter obtained by a certain solver after getting a
  6. # list of results via optMethodSims
  7. #
  8. # Args:
  9. # param: A string for the parameter to get (such as "beta1")
  10. # solver: A string for the solver for which to get the parameter (such as
  11. # "nlminb")
  12. # reslist: A list created by optMethodSims
  13. #
  14. # Return:
  15. # A vector of values of the parameter for each simulation
  16. res <- sapply(
  17. reslist,
  18. function(l)
  19. {
  20. return(l[solver, param])
  21. })
  22. return(res)
  23. }
  24. optMethodSims_getBestVals <- function(reslist,
  25. opt_vec = TRUE,
  26. reslike = FALSE)
  27. {
  28. # A function that gets the optimizer that maximized the likelihood function
  29. # for each entry in reslist
  30. #
  31. # Args:
  32. # reslist: A list created by optMethodSims
  33. # opt_vec: A boolean indicating whether to return a vector with the name of
  34. # the optimizers that maximized the log likelihood
  35. # reslike: A bookean indicating whether the resulting list should consist of
  36. # matrices of only one row labeled "best" with a structure like
  37. # reslist
  38. #
  39. # Return:
  40. # If opt_vec is TRUE, a list of lists, where each sublist contains a vector
  41. # of strings naming the opimizers that maximized the likelihood function and
  42. # a matrix of the parameters found. Otherwise, just the matrix (resembles
  43. # the list generated by optMethodSims)
  44. res <- lapply(
  45. reslist,
  46. function(l)
  47. {
  48. max_llh <- max(l[, "LLH"], na.rm = TRUE)
  49. best_idx <- (l[, "LLH"] == max_llh) & (!is.na(l[, "LLH"]))
  50. best_mat <- l[best_idx, , drop = FALSE]
  51. if (opt_vec)
  52. {
  53. return(
  54. list(
  55. "solvers" = rownames(best_mat), "params" = best_mat))
  56. }
  57. else
  58. {
  59. return(best_mat)
  60. }
  61. })
  62. if (reslike)
  63. {
  64. res <- lapply(
  65. res,
  66. function(l)
  67. {
  68. mat <- l$params[1, , drop = FALSE]
  69. rownames(mat) <- "best"
  70. return(mat)
  71. })
  72. }
  73. return(res)
  74. }
  75. optMethodSims_getCaptureRate <- function(param,
  76. solver,
  77. reslist,
  78. multiplier = 2,
  79. spec,
  80. use_robust = TRUE)
  81. {
  82. # Gets the rate a confidence interval for a parameter captures the true value
  83. #
  84. # Args:
  85. # param: A string for the parameter being worked with
  86. # solver: A string for the solver used to estimate the parameter
  87. # reslist: A list created by optMethodSims
  88. # multiplier: A floating-point number for the multiplier to the standard
  89. # error, appropriate for the desired confidence level
  90. # spec: A ugarchspec specification with the fixed parameters containing the
  91. # true parameter value
  92. # use_robust: Use robust standard errors for computing CIs
  93. #
  94. # Return:
  95. # A float for the proportion of times the confidence interval captured the
  96. # true parameter value
  97. se_string <- ifelse(
  98. use_robust, "robust.se.", "se.")
  99. est <- optMethodSims_getAllVals(
  100. param, solver, reslist)
  101. moe_est <- multiplier * optMethodSims_getAllVals(
  102. paste0(se_string, param), solver, reslist)
  103. param_val <- spec@model$fixed.pars[[param]]
  104. contained <- (param_val <= est + moe_est) & (param_val >= est - moe_est)
  105. return(mean(contained, na.rm = TRUE))
  106. }
  107. optMethodSims_getMaxRate <- function(solver,
  108. maxlist)
  109. {
  110. # Gets how frequently a solver found a maximal log likelihood
  111. #
  112. # Args:
  113. # solver: A string for the solver
  114. # maxlist A list created by optMethodSims_getBestVals with entries
  115. # containing vectors naming the solvers that maximized the log
  116. # likelihood
  117. #
  118. # Return:
  119. # The proportion of times the solver maximized the log likelihood
  120. maxed <- sapply(
  121. maxlist,
  122. function(l)
  123. {
  124. solver %in% l$solvers
  125. })
  126. return(mean(maxed))
  127. }
  128. optMethodSims_getFailureRate <- function(solver,
  129. reslist)
  130. {
  131. # Computes the proportion of times a solver failed to converge.
  132. #
  133. # Args:
  134. # solver: A string for the solver
  135. # reslist: A list created by optMethodSims
  136. #
  137. # Return:
  138. # Numeric proportion of times a solver failed to converge
  139. failed <- sapply(
  140. reslist,
  141. function(l)
  142. {
  143. is.na(l[solver, "LLH"])
  144. })
  145. return(mean(failed))
  146. }
  147. # Vectorization
  148. optMethodSims_getCaptureRate <- Vectorize(
  149. optMethodSims_getCaptureRate, vectorize.args = "solver")
  150. optMethodSims_getMaxRate <- Vectorize(
  151. optMethodSims_getMaxRate, vectorize.args = "solver")
  152. optMethodSims_getFailureRate <- Vectorize(
  153. optMethodSims_getFailureRate, vectorize.args = "solver")

我首先为固定样本量和模型创建表:

  • 所有求解器中,某个求解器达到最高对数似然的频率
  • 某个求解器未能收敛的频率
  • 基于某个求解器的解,95% 置信区间包含每个参数真实值的频率(称为“捕获率”,并使用稳健标准差)
  1. solver_table <- function(reslist,
  2. tags,
  3. spec)
  4. {
  5. # Creates a table describing important solver statistics
  6. #
  7. # Args:
  8. # reslist: A list created by optMethodSims
  9. # tags: A vector with strings naming all solvers to include in the table
  10. # spec: A ugarchspec specification with the fixed parameters containing the
  11. # true parameter value
  12. #
  13. # Return:
  14. # A matrix containing metrics describing the performance of the solvers
  15. params <- names(spec1@model$fixed.pars)
  16. max_rate <- optMethodSims_getMaxRate(
  17. tags, optMethodSims_getBestVals(reslist))
  18. failure_rate <- optMethodSims_getFailureRate(
  19. tags, reslist)
  20. capture_rate <- lapply(
  21. params,
  22. function(p)
  23. {
  24. optMethodSims_getCaptureRate(
  25. p, tags, reslist, spec = spec)
  26. })
  27. return_mat <- cbind(
  28. "Maximization Rate" = max_rate,
  29. "Failure Rate" = failure_rate)
  30. capture_mat <- do.call(cbind, capture_rate)
  31. colnames(capture_mat) <- paste(
  32. params, "95% CI Capture Rate")
  33. return_mat <- cbind(
  34. return_mat, capture_mat)
  35. return(return_mat)
  36. }
  • Model 1, \(n=100\)
  1. as.data.frame(
  2. round(
  3. solver_table(spec1_n100, tags, spec1) * 100,
  4. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ------------------------- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## nlminb 16.2 20.0 21.8 29.2 24.0
  4. ## solnp 0.1 0.0 13.7 24.0 15.4
  5. ## lbfgs 15.1 35.2 56.6 67.9 58.0
  6. ## gosolnp 20.3 0.0 20.3 32.6 21.9
  7. ## hybrid 0.1 0.0 13.7 24.0 15.4
  8. ## nloptr+COBYLA 0.0 0.0 6.3 82.6 19.8
  9. ## nloptr+BOBYQA 0.0 0.0 5.4 82.1 18.5
  10. ## nloptr+PRAXIS 15.8 0.0 42.1 54.5 44.1
  11. ## nloptr+NELDERMEAD 0.4 0.0 5.7 19.3 8.1
  12. ## nloptr+SBPLX 0.1 0.0 7.7 85.7 24.1
  13. ## nloptr+AUGLAG+COBYLA 0.0 0.0 6.1 84.5 19.9
  14. ## nloptr+AUGLAG+BOBYQA 0.1 0.0 6.5 83.2 19.4
  15. ## nloptr+AUGLAG+PRAXIS 22.6 0.0 41.2 54.6 44.1
  16. ## nloptr+AUGLAG+NELDERMEAD 11.1 0.0 7.5 18.8 9.7
  17. ## nloptr+AUGLAG+SBPLX 0.6 0.0 7.9 86.5 23.0
  • Model 1, \(n=500\)
  1. as.data.frame(
  2. round(
  3. solver_table(spec1_n500, tags, spec1) * 100,
  4. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ------------------------- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## nlminb 21.2 0.4 63.3 67.2 63.8
  4. ## solnp 0.1 0.2 32.2 35.6 32.7
  5. ## lbfgs 4.5 41.3 85.0 87.6 85.7
  6. ## gosolnp 35.1 0.0 69.0 73.2 69.5
  7. ## hybrid 0.1 0.0 32.3 35.7 32.8
  8. ## nloptr+COBYLA 0.0 0.0 3.2 83.3 17.8
  9. ## nloptr+BOBYQA 0.0 0.0 3.5 81.5 18.1
  10. ## nloptr+PRAXIS 18.0 0.0 83.9 87.0 84.2
  11. ## nloptr+NELDERMEAD 0.0 0.0 16.4 20.7 16.7
  12. ## nloptr+SBPLX 0.1 0.0 3.7 91.4 15.7
  13. ## nloptr+AUGLAG+COBYLA 0.0 0.0 3.2 83.3 17.8
  14. ## nloptr+AUGLAG+BOBYQA 0.0 0.0 3.5 81.5 18.1
  15. ## nloptr+AUGLAG+PRAXIS 21.9 0.0 80.2 87.4 83.4
  16. ## nloptr+AUGLAG+NELDERMEAD 0.6 0.0 20.0 24.0 20.5
  17. ## nloptr+AUGLAG+SBPLX 0.0 0.0 3.7 91.4 15.7
  • Model 1, \(n=1000\)
  1. as.data.frame(
  2. round(
  3. solver_table(spec1_n1000, tags, spec1) * 100,
  4. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ------------------------- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## nlminb 21.5 0.1 88.2 86.1 87.8
  4. ## solnp 0.4 0.2 54.9 53.6 54.6
  5. ## lbfgs 1.1 44.8 91.5 88.0 91.8
  6. ## gosolnp 46.8 0.0 87.2 85.1 87.0
  7. ## hybrid 0.5 0.0 55.0 53.6 54.7
  8. ## nloptr+COBYLA 0.0 0.0 4.1 74.5 15.0
  9. ## nloptr+BOBYQA 0.0 0.0 3.6 74.3 15.9
  10. ## nloptr+PRAXIS 17.7 0.0 92.6 90.2 92.2
  11. ## nloptr+NELDERMEAD 0.0 0.0 30.5 29.6 30.9
  12. ## nloptr+SBPLX 0.0 0.0 3.0 82.3 11.6
  13. ## nloptr+AUGLAG+COBYLA 0.0 0.0 4.1 74.5 15.0
  14. ## nloptr+AUGLAG+BOBYQA 0.0 0.0 3.6 74.3 15.9
  15. ## nloptr+AUGLAG+PRAXIS 13.0 0.0 83.4 93.9 86.7
  16. ## nloptr+AUGLAG+NELDERMEAD 0.0 0.0 34.6 33.8 35.0
  17. ## nloptr+AUGLAG+SBPLX 0.0 0.0 3.0 82.3 11.6
  • Model 2, \(n=100\)
  1. as.data.frame(
  2. round(
  3. solver_table(spec2_n100, tags, spec2) * 100,
  4. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ------------------------- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## nlminb 8.2 24.2 22.3 34.7 23.9
  4. ## solnp 0.3 0.0 21.1 32.6 21.3
  5. ## lbfgs 11.6 29.5 74.9 73.2 70.4
  6. ## gosolnp 19.0 0.0 31.9 41.2 30.8
  7. ## hybrid 0.3 0.0 21.1 32.6 21.3
  8. ## nloptr+COBYLA 0.0 0.0 20.5 94.7 61.7
  9. ## nloptr+BOBYQA 0.2 0.0 19.3 95.8 62.2
  10. ## nloptr+PRAXIS 16.0 0.0 70.2 57.2 52.8
  11. ## nloptr+NELDERMEAD 0.2 0.0 7.8 27.8 14.1
  12. ## nloptr+SBPLX 0.1 0.0 24.9 91.0 65.0
  13. ## nloptr+AUGLAG+COBYLA 0.0 0.0 21.2 95.1 62.5
  14. ## nloptr+AUGLAG+BOBYQA 0.9 0.0 20.1 96.2 62.5
  15. ## nloptr+AUGLAG+PRAXIS 38.8 0.0 70.4 57.2 52.7
  16. ## nloptr+AUGLAG+NELDERMEAD 14.4 0.0 10.7 26.0 16.1
  17. ## nloptr+AUGLAG+SBPLX 0.1 0.0 25.8 91.9 65.5
  • Model 2, \(n=500\)
  1. as.data.frame(
  2. round(
  3. solver_table(spec2_n500, tags, spec2) * 100,
  4. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ------------------------- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## nlminb 1.7 1.6 35.0 37.2 34.2
  4. ## solnp 0.1 0.2 46.2 48.6 45.3
  5. ## lbfgs 2.2 38.4 85.2 88.1 82.3
  6. ## gosolnp 5.2 0.0 74.9 77.8 72.7
  7. ## hybrid 0.1 0.0 46.1 48.5 45.2
  8. ## nloptr+COBYLA 0.0 0.0 8.2 100.0 40.5
  9. ## nloptr+BOBYQA 0.0 0.0 9.5 100.0 41.0
  10. ## nloptr+PRAXIS 17.0 0.0 83.8 85.1 81.0
  11. ## nloptr+NELDERMEAD 0.0 0.0 26.9 38.2 27.0
  12. ## nloptr+SBPLX 0.0 0.0 8.2 100.0 40.2
  13. ## nloptr+AUGLAG+COBYLA 0.0 0.0 8.2 100.0 40.5
  14. ## nloptr+AUGLAG+BOBYQA 0.0 0.0 9.5 100.0 41.0
  15. ## nloptr+AUGLAG+PRAXIS 77.8 0.0 84.4 85.4 81.3
  16. ## nloptr+AUGLAG+NELDERMEAD 1.1 0.0 32.5 40.3 32.3
  17. ## nloptr+AUGLAG+SBPLX 0.0 0.0 8.2 100.0 40.2
  • Model 2, \(n=1000\)
  1. as.data.frame(
  2. round(
  3. solver_table(spec2_n1000, tags, spec2) * 100,
  4. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ------------------------- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## nlminb 2.7 0.7 64.1 68.0 63.8
  4. ## solnp 0.0 0.0 70.1 73.8 69.8
  5. ## lbfgs 0.0 43.4 90.6 91.5 89.9
  6. ## gosolnp 3.2 0.0 87.5 90.3 86.9
  7. ## hybrid 0.0 0.0 70.1 73.8 69.8
  8. ## nloptr+COBYLA 0.0 0.0 2.3 100.0 20.6
  9. ## nloptr+BOBYQA 0.0 0.0 2.5 100.0 22.6
  10. ## nloptr+PRAXIS 14.1 0.0 89.1 91.3 88.5
  11. ## nloptr+NELDERMEAD 0.0 0.0 46.3 55.6 45.4
  12. ## nloptr+SBPLX 0.0 0.0 2.2 100.0 19.5
  13. ## nloptr+AUGLAG+COBYLA 0.0 0.0 2.3 100.0 20.6
  14. ## nloptr+AUGLAG+BOBYQA 0.0 0.0 2.5 100.0 22.6
  15. ## nloptr+AUGLAG+PRAXIS 85.5 0.0 89.1 91.3 88.5
  16. ## nloptr+AUGLAG+NELDERMEAD 0.3 0.0 51.9 58.2 51.3
  17. ## nloptr+AUGLAG+SBPLX 0.0 0.0 2.2 100.0 19.5

这些表已经揭示了很多信息。一般来说,NLOpt 中提供的 AUGLAG-PRAXIS 方法(使用主轴求解器的增广拉格朗日方法)似乎对模型 2 最有效,特别是对于大样本;而对于模型 1,gosolnp 方法(使用 Yinyu Ye 的 solnp 求解器,但使用随机初始化和重启)似乎在大样本上胜出。

然而,更大的故事是任何方法都不能成为“最佳”,特别是在样本量较小的情况下。有些优化器始终未能达到最大对数似然,没有优化器能够始终如一地获得最佳结果。此外,不同的优化器似乎在不同的模型下表现更好。真实世界的数据——真正的模型参数从未被知道——暗示了要尝试每个优化器(或至少那些有可能最大化对数似然的),并选择产生最大对数似然的结果。没有算法值得信赖,都无法成为首选算法。

现在让我们看一下参数估计的分布图。首先是辅助函数。

  1. library(ggplot2)
  2. solver_density_plot <- function(param,
  3. tags,
  4. list_reslist,
  5. sample_sizes,
  6. spec)
  7. {
  8. # Given a parameter, creates a density plot for each solver's distribution
  9. # at different sample sizes
  10. #
  11. # Args:
  12. # param: A string for the parameter to plot
  13. # tags: A character vector containing the solver names
  14. # list_reslist: A list of lists created by optMethodSimsf, one for each
  15. # sample size
  16. # sample_sizes: A numeric vector identifying the sample size corresponding
  17. # to each object in the above list
  18. # spec: A ugarchspec object containing the specification that generated the
  19. # datasets
  20. #
  21. # Returns:
  22. # A ggplot object containing the plot generated
  23. p <- spec@model$fixed.pars[[param]]
  24. nlist <- lapply(
  25. list_reslist,
  26. function(l)
  27. {
  28. optlist <- lapply(
  29. tags,
  30. function(t)
  31. {
  32. return(
  33. na.omit(
  34. optMethodSims_getAllVals(param, t, l)))
  35. })
  36. names(optlist) <- tags
  37. df <- stack(optlist)
  38. names(df) <- c("param", "optimizer")
  39. return(df)
  40. })
  41. ndf <- do.call(rbind, nlist)
  42. ndf$n <- rep(
  43. sample_sizes, times = sapply(nlist, nrow))
  44. ggplot(
  45. ndf, aes(x = param)) +
  46. geom_density(
  47. fill = "black", alpha = 0.5) +
  48. geom_vline(
  49. xintercept = p, color = "blue") +
  50. facet_grid(
  51. optimizer ~ n, scales = "free_y")
  52. }

开始画图。

  • \(\omega\) 估计,model 1
  1. solver_density_plot(
  2. "omega", tags,
  3. list(spec1_n100, spec1_n500, spec1_n1000),
  4. c(100, 500, 1000), spec1)

  • \(\alpha\) 估计,model 1
  1. solver_density_plot(
  2. "alpha1", tags,
  3. list(spec1_n100, spec1_n500, spec1_n1000),
  4. c(100, 500, 1000), spec1)

  • \(\beta\) 估计,model 1
  1. solver_density_plot(
  2. "beta1", tags,
  3. list(spec1_n100, spec1_n500, spec1_n1000),
  4. c(100, 500, 1000), spec1)

请记住,只有 1000 个模拟序列,并且优化器为每个序列生成解,因此原则上优化器结果不应该是独立的,但优化器运行得非常糟糕的时候,这些密度图才看起来是相同的。但即使优化器的表现不是很糟糕(就像 gosolnpPRAXISAUGLAG-PRAXIS 方法的情况一样),有证据表明估计 \(\omega\)\(\alpha\) 的估计错误地接近 0,并且 \(\beta\) 的估计错误地接近 1。对于较小的样本,这些错误更明显。也就是说,对于更好的优化器,估计应该看起来几乎无偏,特别是对于 \(\omega\)\(\alpha\),但是即使对于大样本,它们的变动范围也很大,特别是对于 \(\beta\) 的估计。但是,对于 AUGLAG-PRAXIS 优化器来说情况并非如此,它似乎产生有偏的估计。

让我们看看模型 2 的图。

  • \(\omega\) 估计,model 2
  1. solver_density_plot(
  2. "omega", tags,
  3. list(spec2_n100, spec2_n500, spec2_n1000),
  4. c(100, 500, 1000), spec2)

  • alpha$ 估计,model 2
  1. solver_density_plot(
  2. "alpha1", tags,
  3. list(spec2_n100, spec2_n500, spec2_n1000),
  4. c(100, 500, 1000), spec2)

  • \(\beta\) 估计,model 2
  1. solver_density_plot(
  2. "beta1", tags,
  3. list(spec2_n100, spec2_n500, spec2_n1000),
  4. c(100, 500, 1000), spec2)

对于模型 2 来说估计器并没有那么费力,但是图显示仍然不太乐观。PRAXISAUGLAG-PRAXIS 方法似乎表现良好,但对于小样本量来说远非吸引人。

到目前为止,我的实验表明,从业者不应该依赖任何一个优化器,而是应该尝试不同的优化器,并选择具有最大对数似然的结果。假设我们将此优化算法称为“最佳”优化器。这个优化器执行效果如何?

我们来看看。

  • Model 1,\(n=100\)
  1. as.data.frame(
  2. round(
  3. solver_table(
  4. optMethodSims_getBestVals(
  5. spec1_n100, reslike = TRUE),
  6. "best", spec1) * 100,
  7. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ----- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## best 100 0 49.5 63.3 52.2
  • Model 1,\(n=500\)
  1. as.data.frame(
  2. round(
  3. solver_table(
  4. optMethodSims_getBestVals(
  5. spec1_n500, reslike = TRUE),
  6. "best", spec1) * 100,
  7. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ----- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## best 100 0 86 88.8 86.2
  • Model 1,\(n=1000\)
  1. as.data.frame(
  2. round(
  3. solver_table(
  4. optMethodSims_getBestVals(
  5. spec1_n1000, reslike = TRUE),
  6. "best", spec1) * 100,
  7. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ----- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## best 100 0 92.8 90.3 92.4
  • Model 2,\(n=100\)
  1. as.data.frame(
  2. round(
  3. solver_table(
  4. optMethodSims_getBestVals(
  5. spec2_n100, reslike = TRUE),
  6. "best", spec2) * 100,
  7. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ----- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## best 100 0 55.2 63.2 52.2
  • Model 2,\(n=500\)
  1. as.data.frame(
  2. round(
  3. solver_table(
  4. optMethodSims_getBestVals(
  5. spec2_n500, reslike = TRUE),
  6. "best", spec2) * 100,
  7. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ----- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## best 100 0 83 86.3 80.5
  • Model 2,\(n=1000\)
  1. as.data.frame(
  2. round(
  3. solver_table(
  4. optMethodSims_getBestVals(
  5. spec2_n1000, reslike = TRUE),
  6. "best", spec2) * 100,
  7. digits = 1))
  1. ## Maximization Rate Failure Rate omega 95% CI Capture Rate alpha1 95% CI Capture Rate beta1 95% CI Capture Rate
  2. ## ----- ------------------ ------------- -------------------------- --------------------------- --------------------------
  3. ## best 100 0 88.7 91.4 88.1

请记住,我们通过 CI 捕获率来评估“最佳”优化器的表现,该捕获率应该在 95% 左右。“最佳”优化器显然具有良好的表现,但并不优于所有优化器。这令人失望。我曾希望“最佳”优化器具有捕获率 95% 的理想特性。除了较大的样本量外,表现远不及预期。标准差被低估,或者对于小样本,正态分布很难描述估计量的实际分布(这意味着标准差乘以 2 不会导致置信区间具有所需置信水平)。

有趣的是,对于这种“最佳”估计器,两种模型之间的表现没有明显差异。这启示我,在实际数据中常见模型看似更好的结果可能正在利用优化器的偏差。

让我们看一下估计参数的分布。

  • \(\omega\) 估计,model 1
  1. solver_density_plot(
  2. "omega", "best",
  3. lapply(
  4. list(spec1_n100, spec1_n500, spec1_n1000),
  5. function(l)
  6. {
  7. optMethodSims_getBestVals(
  8. l, reslike = TRUE)
  9. }),
  10. c(100, 500, 1000), spec1)

  • \(\alpha\) 估计,model 1
  1. solver_density_plot(
  2. "alpha1", "best",
  3. lapply(
  4. list(spec1_n100, spec1_n500, spec1_n1000),
  5. function(l)
  6. {
  7. optMethodSims_getBestVals(
  8. l, reslike = TRUE)
  9. }),
  10. c(100, 500, 1000), spec1)

  • \(\beta\) 估计,model 1
  1. solver_density_plot(
  2. "beta1", "best",
  3. lapply(
  4. list(spec1_n100, spec1_n500, spec1_n1000),
  5. function(l)
  6. {
  7. optMethodSims_getBestVals(
  8. l, reslike = TRUE)
  9. }),
  10. c(100, 500, 1000), spec1)

  • \(\omega\) 估计,model 2
  1. solver_density_plot(
  2. "omega", "best",
  3. lapply(
  4. list(spec2_n100, spec2_n500, spec2_n1000),
  5. function(l)
  6. {
  7. optMethodSims_getBestVals(
  8. l, reslike = TRUE)
  9. }),
  10. c(100, 500, 1000), spec2)

  • \(\alpha\) 估计,model 2
  1. solver_density_plot(
  2. "alpha1", "best",
  3. lapply(
  4. list(spec2_n100, spec2_n500, spec2_n1000),
  5. function(l)
  6. {
  7. optMethodSims_getBestVals(
  8. l, reslike = TRUE)
  9. }),
  10. c(100, 500, 1000), spec2)

  • \(\beta\) 估计,model 2
  1. solver_density_plot(
  2. "beta1", "best",
  3. lapply(
  4. list(spec2_n100, spec2_n500, spec2_n1000),
  5. function(l)
  6. {
  7. optMethodSims_getBestVals(
  8. l, reslike = TRUE)
  9. }),
  10. c(100, 500, 1000), spec2)

这些图表明,“最佳”估计器仍然显示出一些病态,即使它的表现不如其他估计器差。无论模型选择如何,我都没有看到参数估计有偏的证据,但我不相信“最佳”估计器真正最大化对数似然,特别是对于较小的样本量。\(\beta\) 的估计值特别糟糕。即使 \(\beta\) 的标准差应该很大,我也不认为它应该像图中揭示的那样向 0 或 1 倾斜。

结论

我最初在一年前写过这篇文章,直到现在才发表。中断的原因是因为我想得到一个关于估计 GARCH 模型参数替代方法的文献综述。不幸的是,我从未完成过这样的综述,而且我已经决定发布这篇文章。

那就是说,我会分享我正在读的东西。Gilles Zumbach 的一篇文章试图解释为什么估计 GARCH 参数很难。他指出,求解器试图最大化的准似然方程具有不良特性,例如非凸,且具有可能让算法陷入困境的“平坦”区域。他提出了另一种寻找 GARCH 模型参数的方法,在一个替代参数空间中找到最佳拟合(假设它具有比所使用 GARCH 模型的原始参数空间更好的属性),并且使用例如矩方法估计其中一个参数,而没有任何优化算法。另一篇由 Fiorentini、Calzolari 和 Panattoni 撰写的文章表明,GARCH 模型的解析梯度可以明确计算,因此这里看到的优化算法所使用的无梯度方法实际上并不是必需的。由于数值微分通常是一个难题,这可以帮助确保不会引入导致这些算法无法收敛的额外数值误差。我还想探索其他估计方法,看看它们是否能够以某种方式完全避免数值技术,或具有更好的数值属性,例如通过矩估计。我想阅读Andersen、Chung 和 S?rensen 撰写的文章,以了解有关这种估计方法的更多信息。

然而,生活正在继续,我没有完成这篇综述。项目继续进行,基本上很好地避免了估计 GARCH 模型参数的问题。也就是说,我想重新审视这一点,或许可以探索模拟退火等技术如何用于估计 GARCH 模型参数。

所以现在,如果你是一名从业者,在估计 GARCH 模型时你应该怎么做?我想说不要理所当然地认为你的包使用的默认估计算法会起作用。你应该探索不同的算法和不同的参数选择,并使用导致最大对数似然的结果。我展示了如何以自动化方式完成这项工作,但你应该准备手动选择最佳的模型(由对数似然确定)。如果你不这样做,你估计的模型实际上可能不是理论可行的模型。

我将在本文的最后再次说一遍,特别强调:不要将数值技术和结果视为理所当然的!

  1. sessionInfo()
  1. ## R version 3.4.2 (2017-09-28)
  2. ## Platform: i686-pc-linux-gnu (32-bit)
  3. ## Running under: Ubuntu 16.04.2 LTS
  4. ##
  5. ## Matrix products: default
  6. ## BLAS: /usr/lib/libblas/libblas.so.3.6.0
  7. ## LAPACK: /usr/lib/lapack/liblapack.so.3.6.0
  8. ##
  9. ## locale:
  10. ## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
  11. ## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
  12. ## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
  13. ## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
  14. ## [9] LC_ADDRESS=C LC_TELEPHONE=C
  15. ## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
  16. ##
  17. ## attached base packages:
  18. ## [1] parallel stats graphics grDevices utils datasets methods
  19. ## [8] base
  20. ##
  21. ## other attached packages:
  22. ## [1] ggplot2_2.2.1 rugarch_1.3-8 printr_0.1
  23. ##
  24. ## loaded via a namespace (and not attached):
  25. ## [1] digest_0.6.16 htmltools_0.3.6
  26. ## [3] SkewHyperbolic_0.3-2 expm_0.999-2
  27. ## [5] scales_0.5.0 DistributionUtils_0.5-1
  28. ## [7] Rsolnp_1.16 rprojroot_1.2
  29. ## [9] grid_3.4.2 stringr_1.3.1
  30. ## [11] knitr_1.17 numDeriv_2016.8-1
  31. ## [13] GeneralizedHyperbolic_0.8-1 munsell_0.4.3
  32. ## [15] pillar_1.3.0 tibble_1.4.2
  33. ## [17] compiler_3.4.2 highr_0.6
  34. ## [19] lattice_0.20-35 labeling_0.3
  35. ## [21] Matrix_1.2-8 KernSmooth_2.23-15
  36. ## [23] plyr_1.8.4 xts_0.10-0
  37. ## [25] spd_2.0-1 zoo_1.8-0
  38. ## [27] stringi_1.2.4 magrittr_1.5
  39. ## [29] reshape2_1.4.2 rlang_0.2.2
  40. ## [31] rmarkdown_1.7 evaluate_0.10.1
  41. ## [33] gtable_0.2.0 colorspace_1.3-2
  42. ## [35] yaml_2.1.14 tools_3.4.2
  43. ## [37] mclust_5.4.1 mvtnorm_1.0-6
  44. ## [39] truncnorm_1.0-7 ks_1.11.3
  45. ## [41] nloptr_1.0.4 lazyeval_0.2.1
  46. ## [43] crayon_1.3.4 backports_1.1.1
  47. ## [45] Rcpp_1.0.0

  1. 当我最初写这篇文章时,我的导师和他的前学生开发了一个检验统计量,应该检测时间序列中的早期或晚期变点,包括 GARCH 模型参数的变化。我对我们所撰写论文的贡献包括证明,当应用于真实世界数据时,检验统计量比其他检验统计量更快地检测到结构变化。为了说服审阅者,我们的检验统计量应检测到另一个统计量在获得更多数据之前无法检测到的变化。这意味着变化应该存在,但不会太强,以至于两个统计数据都可以立即通过微小的 \(p\)-value 检测到变化。?

  2. 我链接到的 LinkedIn 上的个人资料可能是也可能不是正确的人,我猜这是基于列出的职业和历史。如果我找错了人,我很抱歉。?

原文链接:http://www.cnblogs.com/xuruilong100/p/10404054.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号