You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

伽马分布下GARCH(1,1)极大似然估计omega参数偏大问题求助

Gamma-GARCH(1,1)参数估计异常排查与修复

你的代码存在4个核心问题,直接导致omega估计值偏离合理范围,逐一修复即可得到符合预期的结果:


核心错误点

  1. 变量名拼写错误:对数似然函数最后一项写的是- nu*np.log(mu),但你计算得到的条件均值序列变量名为mu_t,未定义的mu会直接读取内存中残留的无关变量,导致似然计算完全失效。
  2. 数值稳定性问题:用np.log(gamma(nu))计算对数伽马值,当nu取值较大时伽马函数会超出浮点数精度范围返回inf,必须使用scipy内置的gammaln()函数直接计算对数伽马,避免数值溢出。
  3. 约束冗余且逻辑混乱:定义的cons1约束仅重复了参数非负要求,而该限制已经通过bounds参数实现,多余约束会干扰优化器的搜索路径。
  4. 初始值偏离合理区间:形状参数nu的初始值设为0.5,和你预期的4差距过大,带约束的非线性优化很容易收敛到局部极值点。

修复后代码

import numpy as np
import pandas as pd
import scipy.optimize as opt
from scipy.special import gammaln  # 替换gamma,直接计算对数伽马保证数值稳定

df_aex = pd.read_excel('/Users/jr/Desktop/Data_complete.xlsx', sheet_name=0)
rv = df_aex["rv5"].values * 100  # 直接转numpy数组减少冗余操作


def garch_filter(omega, alpha1, beta, rv):
    irv = len(rv)
    mu_t = np.zeros(irv)
    persistence = alpha1 + beta
    # 非平稳序列直接返回惩罚值,避免优化器进入无效参数区间
    if persistence >= 1:
        return np.full(irv, 1e10)
    mu_t[0] = omega / (1 - persistence)
    for i in range(1, irv):
        mu_t[i] = omega + alpha1 * rv[i-1] + beta * mu_t[i-1]
        # 避免条件均值为0导致对数计算报错
        if mu_t[i] <= 1e-8:
            mu_t[i] = 1e-8
    return mu_t


def neg_gamma_loglike(vP, rv):
    omega, alpha1, beta, nu = vP
    # 提前拦截不符合边界要求的参数
    if omega <= 0 or alpha1 < 0 or beta <0 or nu <=0 or alpha1+beta >=1:
        return 1e10
    mu_t = garch_filter(omega, alpha1, beta, rv)
    # 直接计算负对数似然,避免多层负号嵌套导致逻辑错误
    log_density = (
        -gammaln(nu)
        + nu * np.log(nu)
        + (nu - 1) * np.log(rv)
        - nu * np.log(mu_t)
        - nu * rv / mu_t
    )
    return -np.sum(log_density)


# 仅保留平稳性约束:alpha + beta < 1
cons = ({'type': 'ineq', 'fun': lambda x: 1 - x[1] - x[2]})

# 初始值向预期区间靠拢,降低优化收敛难度
vP0 = np.array([0.01, 0.05, 0.7, 4])

# 给omega设置合理上界,避免参数跑飞
bounds = (
    (1e-6, 1),
    (1e-6, 0.999),
    (1e-6, 0.999),
    (1e-4, 20)
)

res = opt.minimize(
    neg_gamma_loglike,
    vP0,
    args=(rv,),
    bounds=bounds,
    constraints=cons,
    method='SLSQP',
    options={'disp': True, 'maxiter': 1000}
)

o_est, a_est, b_est, nu_est = res.x
print([o_est, a_est, b_est, nu_est])

优化建议

  • 如果数据中存在0值的已实现波动率观测,需要提前做微小值偏移处理,否则np.log(rv)会返回nan中断计算。
  • 如果全参数估计仍然不稳定,可以先固定nu=4,仅估计GARCH的三个参数,拿到收敛结果后再放开nu联合估计,分步估计能大幅降低收敛难度。

内容的提问来源于stack exchange,提问作者zjos020

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 03:39:23