我正在尝试从 python 3 中的 statsmodels 库运行 X-13-ARIMA 模型。
我在 statsmodels 文档中找到了这个示例:
dta = sm.datasets.co2.load_pandas().data
dta.co2.interpolate(inplace=True)
dta = dta.resample('M').sum()
res = sm.tsa.x13_arima_select_order(dta.co2)
print(res.order, res.sorder)
results = sm.tsa.x13_arima_analysis(dta.co2)
fig = results.plot()
fig.set_size_inches(12, 5)
fig.tight_layout()
这工作得很好,但我还需要预测这个时间序列的未来值。
tsa.x13_arima_analysis()
函数包含forecast_years
参数,所以我认为它应该是可能的。然而;无论我选择什么值 results
参数,forecast_years
对象似乎都不会改变。
如何获得预测值?
现在您可能已经拥有了这个。我检索了一些截至 2012 年 7 月的每月天气数据。我输入此语句进行分析。
results = sm.tsa.x13_arima_analysis(s, forecast_years=3)
然后(发现
results.results
很长)我输入了这个。
open('c:/scratch/result.txt', 'w').write(results.results)
通过查看此文件的“预测”,我发现了以下部分。
FORECASTING
Origin 2012.Jul
Number 3
Forecasts and Standard Errors of the Prior Adjusted Data
------------------------------
Standard
Date Forecast Error
------------------------------
2012.Aug 33.02 2.954
2012.Sep 28.31 2.954
2012.Oct 21.54 2.954
------------------------------
Confidence intervals with coverage probability ( 0.95000
---------------------------------------
Date Lower Forecast Upper
---------------------------------------
2012.Aug 27.23 33.02 38.82
2012.Sep 22.52 28.31 34.10
2012.Oct 15.75 21.54 27.33
---------------------------------------
forecast_years=3
似乎意味着进行三个月的预测,在本例中是从 7 月之后开始。
forecast_years=x 为我工作。请注意您正在运行的 statsmodels 版本(“pip freeze | grep statsmodels”),对于版本 10.2,预测范围的正确参数是
一个简单的正则表达式应该可以找到你的预测值:
202\d.\w{3}\s{6}\d\d.\d\d\s{5}\d\d.\d\d\s{5}\d\d.\d\d
(在结果的每一行上运行)
将匹配:
2020.Feb 18.04 32.25 46.47
回复较晚,但希望有帮助。
result = x13_arima_analysis(df[dependent_var],
tempdir=output_directory,
forecast_periods=12)
然后要在
result.results
输出中查找预测表,您必须通过表名称 id=fct
的 id 进行搜索。
from bs4 import BeautifulSoup
import pandas as pd
result_string = result.results
soup = BeautifulSoup(result_string, 'lxml')
specific_section = soup.find('div', id='fct')
table = specific_section.find('table') if specific_section else None
这将为您提供表格的“字符串”版本。然后你就可以按照你想要的方式解析。我需要一个数据框(下面的示例)。
<table class="w70" summary="Confidence intervals with coverage probability
( 0.95000)">
<caption><strong>Confidence intervals with coverage probability ( 0.95000) <br/> On the Original Scale</strong></caption>
<tr>
<th scope="col">Date</th>
<th scope="col">Lower</th>
<th scope="col">Forecast</th>
<th scope="col">Upper</th>
</tr>
<tr>
<th scope="row">2023.Aug</th>
<td> 3560.68 </td>
<td> 3694.21 </td>
<td> 3832.74 </td>
</tr>
<tr>
<th scope="row">2023.Sep</th>
<td> 3393.61 </td>
<td> 3579.02 </td>
<td> 3774.55 </td>
</tr>
<tr>
<th scope="row">2023.Oct</th>
<td> 3275.37 </td>
<td> 3491.64 </td>
<td> 3722.18 </td>
示例:
if table:
dates, lowers, forecasts, uppers = [], [], [], []
for row in table.find_all('tr')[1:]: # skip the header row
columns = row.find_all('td')
date = row.find('th', scope='row').text
lower, forecast, upper = [col.text.strip() for col in columns]
dates.append(date.replace('.', '_'))
lowers.append(float(lower))
forecasts.append(float(forecast))
uppers.append(float(upper))
# Create a DataFrame
df = pd.DataFrame({
'Date': dates,
'Lower': lowers,
'Forecast': forecasts,
'Upper': uppers
})
>>
Date Lower Forecast Upper
0 2023_Aug 3560.68 3694.21 3832.74
1 2023_Sep 3393.61 3579.02 3774.55
2 2023_Oct 3275.37 3491.64 3722.18
3 2023_Nov 3070.97 3318.68 3586.36
4 2023_Dec 2895.54 3162.95 3455.05
5 2024_Jan 2884.05 3179.71 3505.69
6 2024_Feb 2901.60 3228.93 3593.18
7 2024_Mar 2979.65 3343.18 3751.07
8 2024_Apr 3008.83 3401.86 3846.23
9 2024_May 3068.21 3494.67 3980.41
10 2024_Jun 3089.83 3543.59 4064.00
11 2024_Jul 3066.04 3539.45 4085.96