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

如何编程获取SARIMAX模型p/q/m参数范围以缩短网格搜索耗时

SARIMAX参数自动取值范围实现方案

下面是对应参数的编程实现方案,不需要人工查看可视化结果,直接输出可用的取值范围:


差分阶数d自动计算

通过ADF单位根检验自动判断所需差分次数,不需要手动循环,且最优差分阶数通常唯一,不需要做网格搜索:

from statsmodels.tsa.stattools import adfuller

def get_optimal_d(ts, max_diff=2, sig_level=0.05):
    d = 0
    # 最多差分2次,差分会丢失信息,超过2次通常没有实际意义
    while d <= max_diff:
        adf_p = adfuller(ts)[1]
        if adf_p < sig_level:
            return d
        ts = ts.diff().dropna()
        d += 1
    return max_diff

p值取值范围计算

基于PACF的统计显著性判断最大p值,最小值默认取0即可:

from statsmodels.tsa.stattools import pacf
import numpy as np

def get_p_range(ts, max_p_limit=10, sig_level=0.05):
    # 计算pacf和对应的置信区间
    pacf_vals, conf_int = pacf(ts, nlags=max_p_limit, alpha=sig_level)
    # 找到所有显著不为0的滞后阶数(排除0阶自相关)
    sig_lags = np.where(np.abs(pacf_vals) > (conf_int[:,1] - pacf_vals))[0]
    max_p = sig_lags.max() if len(sig_lags) > 0 else 0
    # 限制上限避免搜索范围过大
    max_p = min(max_p, max_p_limit)
    return 0, max_p

返回的第一个值就是min_series_p,第二个值就是max_series_p。


q值取值范围计算

逻辑和p值完全一致,替换为ACF计算即可:

from statsmodels.tsa.stattools import acf

def get_q_range(ts, max_q_limit=10, sig_level=0.05):
    acf_vals, conf_int = acf(ts, nlags=max_q_limit, alpha=sig_level)
    sig_lags = np.where(np.abs(acf_vals) > (conf_int[:,1] - acf_vals))[0]
    max_q = sig_lags.max() if len(sig_lags) > 0 else 0
    max_q = min(max_q, max_q_limit)
    return 0, max_q

返回的第一个值就是min_series_q,第二个值就是max_series_q。


季节性周期m自动计算

可以根据你的数据特性选以下任意一种方案:

方案1:ACF峰值法(最常用)

def get_seasonal_m(ts, max_m_limit=365):
    acf_vals = acf(ts, nlags=max_m_limit)
    # 排除0阶,找ACF最大的峰值对应的滞后阶数
    acf_vals[0] = 0
    # 过滤掉小于0.2的峰值,避免噪声干扰
    acf_vals[acf_vals < 0.2] = 0
    m = acf_vals.argmax()
    return m if m > 0 else 1

方案2:已知采样频率直接赋值

如果你的数据采样频率是固定的,可以直接写规则,不需要计算:

def get_seasonal_m_by_freq(freq):
    # freq是pandas的时间频率,比如'H'是小时,'D'是天,'M'是月
    freq_map = {
        'H': 24,
        'D': 7,
        'W': 52,
        'M': 12,
        'Q': 4
    }
    return freq_map.get(freq, 1)

返回值就是sts_series_m。


搜索代码优化提示

你原来的网格搜索代码可以简化,不需要两层循环:

# 先计算所有参数
min_p, max_p = get_p_range(ts)
min_q, max_q = get_q_range(ts)
d = get_optimal_d(ts)
m = get_seasonal_m(ts)

p_range = range(min_p, max_p+1)
q_range = range(min_q, max_q+1)

for p in p_range:
    for q in q_range:
        param = (p, d, q)
        param_s = (p, d, q, m)
        mod = SARIMAX(ts.to_numpy(), order=param, seasonal_order=param_s)
        model_fit = mod.fit(iprint=0, disp=0, method_kwargs={"warn_convergence": False})

该方案可以直接把搜索范围缩小到合理区间,耗时至少能减少80%以上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:57:02