Python中auto.arima()的等效函数
我正在尝试用ARIMA模型来预测每周的销售情况。可是我找不到一个可以调整(p,d,q)顺序的函数,statsmodels
这个库里没有。目前,R语言有一个函数叫forecast::auto.arima()
,可以自动调整(p,d,q)这些参数。
我该如何选择适合我模型的顺序呢?在Python中有没有类似的库可以用来做这个?
10 个回答
我写了这些工具函数,可以直接计算pdq值。get_PDQ_parallel这个函数需要三个输入数据,这些数据是以时间戳(日期时间)为索引的序列。n_jobs参数用来指定并行处理器的数量。输出结果将是一个数据框,里面包含了aic和bic值,索引是(P,D,Q)的顺序。p和q的范围是[0,12],而d的范围是[0,1]。
import statsmodels
from statsmodels import api as sm
from sklearn.metrics import r2_score,mean_squared_error
from sklearn.utils import check_array
from functools import partial
from multiprocessing import Pool
def get_aic_bic(order,series):
aic=np.nan
bic=np.nan
#print(series.shape,order)
try:
arima_mod=statsmodels.tsa.arima_model.ARIMA(series,order=order,freq='H').fit(transparams=True,method='css')
aic=arima_mod.aic
bic=arima_mod.bic
print(order,aic,bic)
except:
pass
return aic,bic
def get_PDQ_parallel(data,n_jobs=7):
p_val=13
q_val=13
d_vals=2
pdq_vals=[ (p,d,q) for p in range(p_val) for d in range(d_vals) for q in range(q_val)]
get_aic_bic_partial=partial(get_aic_bic,series=data)
p = Pool(n_jobs)
res=p.map(get_aic_bic_partial, pdq_vals)
p.close()
return pd.DataFrame(res,index=pdq_vals,columns=['aic','bic'])
def evaluate_arima_model(X, arima_order):
# prepare training dataset
train_size = int(len(X) * 0.90)
train, test = X[0:train_size], X[train_size:]
history = [x for x in train]
# make predictions
predictions = list()
for t in range(len(test)):
model = ARIMA(history, order=arima_order)
model_fit = model.fit(disp=0)
yhat = model_fit.forecast()[0]
predictions.append(yhat)
history.append(test[t])
# calculate out of sample error
error = mean_squared_error(test, predictions)
return error
# evaluate combinations of p, d and q values for an ARIMA model
def evaluate_models(dataset, p_values, d_values, q_values):
dataset = dataset.astype('float32')
best_score, best_cfg = float("inf"), None
for p in p_values:
for d in d_values:
for q in q_values:
order = (p,d,q)
try:
mse = evaluate_arima_model(dataset, order)
if mse < best_score:
best_score, best_cfg = mse, order
print('ARIMA%s MSE=%.3f' % (order,mse))
except:
continue
print('Best ARIMA%s MSE=%.3f' % (best_cfg, best_score))
# load dataset
def parser(x):
return datetime.strptime('190'+x, '%Y-%m')
import datetime
p_values = [4,5,6,7,8]
d_values = [0,1,2]
q_values = [2,3,4,5,6]
warnings.filterwarnings("ignore")
evaluate_models(train, p_values, d_values, q_values)
这段话的意思是,这个方法会给你 p、d、q 这三个值,然后你可以用这些值来建立你的 ARIMA 模型。
最简单的方法是通过 Nixtla 的 auto_arima
模型,使用 statsforecast
这个包来实现。这个包的功能和 R 语言里的 forecast::auto.arima
函数是一样的,但它经过了 numba
的优化,所以运行得更快,性能更好,比 R 和 pmdarima
的实现要强。
你只需要用 pip
安装这个库,命令是 pip install statsforecast
。然后,
from statsforecast.core import StatsForecast
from statsforecast.models import auto_arima
fcst = StatsForecast(
df, #your data
models=[auto_arima],
freq='W', # frequency of your data
n_jobs=7, # you can also define the number of cores used for parallelizing
)
forecasts = fcst.forecast(12) #your horizon
这里有一个 示例笔记本,里面有很多例子。
现在有一个专门的Python包可以用来自动进行ARIMA模型的分析。你可以在这里找到它:https://github.com/tgsmith61591/pmdarima
文档说明在这里: http://alkaline-ml.com/pmdarima
使用示例可以查看这里:https://github.com/tgsmith61591/pmdarima/blob/master/examples/quick_start_example.ipynb
你可以尝试几种方法:
ARIMAResults
包含aic
和bic
。根据它们的定义(可以查看 这里 和 这里),这些标准会对模型中的参数数量进行惩罚。因此,你可以用这些数字来比较不同的模型。此外,scipy 还提供了optimize.brute
,它可以在指定的参数空间中进行网格搜索。所以你可以按照这样的流程进行:def objfunc(order, exog, endog): from statsmodels.tsa.arima.model import ARIMA fit = ARIMA(endog, order, exog).fit() return fit.aic() from scipy.optimize import brute grid = (slice(1, 3, 1), slice(1, 3, 1), slice(1, 3, 1)) brute(objfunc, grid, args=(exog, endog), finish=None)
确保在调用 brute
时使用 finish=None
。
你可以从
ARIMAResults
中获取pvalues
。这样就可以很容易地实现一种逐步算法,根据增加的参数获得最低的 p 值来逐步增加模型的复杂度。使用
ARIMAResults.predict
来交叉验证不同的模型。最好的方法是将时间序列的尾部(比如最近的 5% 数据)留作测试样本,然后用这些数据来计算拟合模型的 测试误差。