如何解决R语言fGarch包中stdFit与sstdFit拟合收敛问题
学生t分布与偏态学生t分布拟合优化问题
我需要将学生t分布和偏态学生t分布拟合到对数收益率数据上,目前使用R语言fGarch包中的stdFit和sstdFit函数(若有更优的替代工具也可推荐)。
问题在于多数情况下拟合无法收敛,示例代码如下:
set.seed(123) require(xts) require(rugarch) require(fGarch) data(sp500ret) spx = as.xts(sp500ret[1000:nrow(sp500ret),,drop=F]) hist(spx,200) fit_std = stdFit(spx) if(fit_std$convergence != 0){ print("stdFit did not converge") } fit_sstd = sstdFit(spx) if(fit_sstd$code != 0){ print("sstdFit did not converge") }
目前仅能向stdFit和sstdFit传递优化器nlm的参数,我更希望能设置初始值和/或参数边界。此外,我未找到sstdFit$code取值(至少包含0、1、2、3)的含义说明。
请问如何优化拟合效果?我需要自动重复执行超百万次不同的拟合操作。
附sessionInfo()信息用于复现:
R version 4.2.3 (2023-03-15 ucrt) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 19045) Matrix products: default locale: [1] LC_COLLATE=German_Germany.utf8 LC_CTYPE=German_Germany.utf8 LC_MONETARY=German_Germany.utf8 LC_NUMERIC=C [5] LC_TIME=German_Germany.utf8 attached base packages: [1] parallel stats graphics grDevices utils datasets methods base other attached packages: [1] fGarch_4022.89 rugarch_1.4-9 xts_0.13.1 zoo_1.8-12 loaded via a namespace (and not attached): [1] tidyselect_1.2.0 remotes_2.4.2 ks_1.14.0 reshape2_1.4.4 [5] lattice_0.20-45 colorspace_2.1-0 vctrs_0.6.2 generics_0.1.3 [9] SkewHyperbolic_0.4-0 utf8_1.2.3 rlang_1.1.0 pracma_2.4.2 [13] gbutils_0.5 pillar_1.9.0 glue_1.6.2 cvar_0.5 [17] lifecycle_1.0.3 plyr_1.8.8 stringr_1.5.0 timeDate_4022.108 [21] munsell_0.5.0 fBasics_4022.94 gtable_0.3.3 timeSeries_4021.105 [25] mvtnorm_1.1-3 fansi_1.0.4 Rcpp_1.0.10 KernSmooth_2.23-20 [29] scales_1.2.1 DistributionUtils_0.6-0 truncnorm_1.0-9 spd_2.0-1 [33] ggplot2_3.4.2 stringi_1.7.12 dplyr_1.1.1 rbibutils_2.2.13 [37] numDeriv_2016.8-1.1 cowplot_1.1.1 grid_4.2.3 Rdpack_2.4 [41] cli_3.6.1 tools_4.2.3 magrittr_2.0.3 Rsolnp_1.16 [45] tibble_3.2.1 pacman_0.5.1 spatial_7.3-16 pkgconfig_2.0.3 [49] GeneralizedHyperbolic_0.8-4 MASS_7.3-58.2 Matrix_1.5-3 rstudioapi_0.14 [53] R6_2.5.1 mclust_6.0.0 compiler_4.2.3
一、替代工具推荐
rugarch包:你已加载该包,其fitdist函数支持自定义分布(含学生t、偏态学生t),允许设置初始值、参数边界,还支持多种优化器(如nlminb、solnp),灵活性远超fGarch。fitdistrplus包:通用分布拟合工具,支持几乎所有常见分布,可自由指定优化方法、初始值和参数约束,适配批量处理场景。
二、优化拟合效果的方法
1. 自定义初始值与参数边界
若坚持使用fGarch,可手动编写对数似然函数,调用支持边界的优化器(如nlminb),示例代码如下:
# 学生t分布对数似然函数 ll_std <- function(params, data) { mu <- params[1] sigma <- params[2] nu <- params[3] -sum(dstd(data, mean = mu, sd = sigma, nu = nu, log = TRUE)) } # 偏态学生t分布对数似然函数 ll_sstd <- function(params, data) { mu <- params[1] sigma <- params[2] nu <- params[3] xi <- params[4] -sum(dsstd(data, mean = mu, sd = sigma, nu = nu, xi = xi, log = TRUE)) } # 拟合学生t分布:设置初始值和边界 init_std <- c(mu = mean(spx), sigma = sd(spx), nu = 5) bounds_std <- list(lower = c(-Inf, 1e-6, 2.01), upper = c(Inf, Inf, Inf)) fit_std_custom <- nlminb(start = init_std, objective = ll_std, data = spx, lower = bounds_std$lower, upper = bounds_std$upper) # 拟合偏态学生t分布:设置初始值和边界 init_sstd <- c(mu = mean(spx), sigma = sd(spx), nu = 5, xi = 1) # xi=1对应对称分布 bounds_sstd <- list(lower = c(-Inf, 1e-6, 2.01, 0.01), upper = c(Inf, Inf, Inf, 10)) fit_sstd_custom <- nlminb(start = init_sstd, objective = ll_sstd, data = spx, lower = bounds_sstd$lower, upper = bounds_sstd$upper)
2. 更换优化器
fGarch的stdFit和sstdFit默认使用nlm,可尝试传递optim.method = "BFGS"参数,但nlm本身不支持边界约束,更推荐使用上述自定义似然函数+nlminb/optim(选择L-BFGS-B方法支持边界)。- 批量任务中,
optim的L-BFGS-B方法在效率和稳定性上表现更优。
3. 数据预处理
对数收益率数据的极端值易导致拟合不收敛,可尝试:
- 缩尾处理:截断上下0.1%的极端值,避免似然函数陷入局部最优。
- 标准化:先将数据转换为均值0、标准差1的标准化数据,简化参数搜索空间,拟合完成后再还原参数。
4. sstdFit$code含义说明
sstdFit的code直接继承自nlm的返回码,对应含义:
- 0:收敛成功
- 1:迭代次数达到设定上限
- 2:梯度绝对值小于收敛阈值,但未达到迭代次数上限
- 3:参数变化量小于收敛阈值,但未达到迭代次数上限
三、百万次批量拟合的效率优化
- 并行计算:使用
parallel包的mclapply(Windows系统用parLapply),将拟合任务分配到多个CPU核心,大幅提升处理速度。 - 预编译似然函数:用
Rcpp编写对数似然函数并编译,运行速度比纯R实现快数倍,适配超大规模批量任务。 - 统一初始值:对所有拟合任务使用合理的统一初始值(如均值、标准差、nu=5、xi=1),减少优化器的搜索时间。
- 过滤无效数据:提前筛选掉不符合分布特征的数据(如全为0、极端值占比过高),避免无效计算。
内容的提问来源于stack exchange,提问作者smaica
相关产品推荐
相关产品推荐

