2014-07-30 16 views
8

Tôi đang cố gắng dự đoán một chuỗi thời gian trong python statsmodels gói ARIMA với sự bao gồm một biến ngoại sinh, nhưng không thể tìm ra cách chính xác để chèn biến ngoại sinh trong bước dự đoán. Xem here cho tài liệu.Python ARIMA biến ngoại sinh ra khỏi mẫu

import numpy as np 
from scipy import stats 
import pandas as pd 

import statsmodels.api as sm 

vals = np.random.rand(13) 
ts = pd.TimeSeries(vals) 
df = pd.DataFrame(ts, columns=["test"]) 
df.index = pd.Index(pd.date_range("2011/01/01", periods = len(vals), freq = 'Q')) 

fit1 = sm.tsa.ARIMA(df, (1,0,0)).fit() 
#this works fine: 
pred1 = fit1.predict(start=12, end = 16) 
print(pred1) 

Out[32]: 
2014-03-31 0.589121 
2014-06-30 0.747575 
2014-09-30 0.631322 
2014-12-31 0.654858 
2015-03-31 0.650093 
Freq: Q-DEC, dtype: float64 

bây giờ thêm trong một xu hướng ngoại sinh biến

exogx = np.array(range(1,14)) 
#to make this easy, let's look at the ols of the trend (arima(0,0,0)) 
fit2 = sm.tsa.ARIMA(df, (0,0,0),exog = exogx).fit() 
print(fit2.params) 

const 0.555226 
x1  0.013132 
dtype: float64 

print(fit2.fittedvalues) 

2011-03-31 0.568358 
2011-06-30 0.581490 
2011-09-30 0.594622 
2011-12-31 0.607754 
2012-03-31 0.620886 
2012-06-30 0.634018 
2012-09-30 0.647150 
2012-12-31 0.660282 
2013-03-31 0.673414 
2013-06-30 0.686546 
2013-09-30 0.699678 
2013-12-31 0.712810 
2014-03-31 0.725942 
Freq: Q-DEC, dtype: float64 

Thông báo, như chúng ta mong đợi, đây là một đường xu hướng, tăng 0,013132 với mỗi lần tăng đánh dấu trong thời gian (tất nhiên đây là dữ liệu ngẫu nhiên, vì vậy nếu bạn chạy nó các giá trị sẽ khác nhau, nhưng câu chuyện xu hướng tích cực hoặc tiêu cực sẽ giống nhau). Vì vậy, giá trị tiếp theo (cho thời gian = 14) phải là 0,555226 + 0,013132 * 14 = 0,7739074.

#out of sample exog should be (14,15,16) 
pred2 = fit2.predict(start = 12, end = 16, exog = np.array(range(13,17))) 
print(pred2) 
2014-03-31 0.725942 
2014-06-30 0.568358 
2014-09-30 0.581490 
2014-12-31 0.594622 
2015-03-31 0.765338 
Freq: Q-DEC, dtype: float64 

Vì vậy, 2014/03/31 dự đoán (các insample cuối cùng) một cách chính xác, nhưng 2014/06/30 bắt đầu lại ngay từ đầu (t = 1), nhưng nhận thấy 2015/03/31 (trên thực tế, luôn luôn quan sát cuối cùng của dự báo, bất kể đường chân trời) chọn t = 16 (nghĩa là, (giá trị - chặn)/beta = (0,765338 - 0,555226) /0.013132).

Để làm điều này rõ ràng hơn, hãy chú ý những gì xảy ra khi tôi thổi phồng giá trị của của x mat

fit2.predict(start = 12, end = 16, exog = np.array(range(13,17))*10000) 
Out[41]: 
2014-03-31  0.725942 
2014-06-30  0.568358 
2014-09-30  0.581490 
2014-12-31  0.594622 
2015-03-31 2101.680532 
Freq: Q-DEC, dtype: float64 

Thấy rằng 2015/03/31 phát nổ, nhưng không ai trong số các giá trị xmat khác được xem xét? Tôi làm gì sai ở đây???

Tôi đã cố gắng chơi xung quanh với mọi cách mà tôi biết cách truyền trong biến exog (thay đổi kích thước, làm cho exog một ma trận, làm cho exog miễn là đầu vào cộng với đường chân trời, v.v ...). Bất kỳ đề xuất nào cũng sẽ được đánh giá cao.

Tôi đang sử dụng 2,7 từ Anaconda2.1 NumPy 1.8.1 scipy 0.14.0 gấu trúc 0.14.0 statsmodels 0.5.0

và đã xác minh vấn đề trên windows 7 64 bit, và centos 64 bit.

Ngoài ra, một vài điều. Tôi đang sử dụng ARIMA cho các chức năng ARIMA và ở trên chỉ là để minh họa (có nghĩa là, tôi không thể "chỉ cần sử dụng OLS ...", như tôi tưởng tượng sẽ được đề nghị). Tôi cũng không thể "chỉ sử dụng R" do các hạn chế của dự án (và nói chung, thiếu sự hỗ trợ của R trong cơ sở Spark).

Dưới đây là những phần thú vị của mã tất cả cùng nhau trong trường hợp bạn muốn thử nó cho mình

import numpy as np 
from scipy import stats 
import pandas as pd 
import statsmodels.api as sm 

vals = np.random.rand(13) 
ts = pd.TimeSeries(vals) 
df = pd.DataFrame(ts, columns=["test"]) 
df.index = pd.Index(pd.date_range("2011/01/01", periods = len(vals), freq = 'Q')) 

exogx = np.array(range(1,14)) 
fit2 = sm.tsa.ARIMA(df, (0,0,0),exog = exogx).fit() 
print(fit2.fittedvalues) 
pred2 = fit2.predict(start = 12, end = 16, exog = np.array(range(13,17))*10000) 
print(pred2) 
+0

Chú ý rằng những vấn đề này được nhắc đến (nhưng không trực tiếp thảo luận) trong các bài viết sau: https://github.com/statsmodels/statsmodels/issues/1076 http://stackoverflow.com/questions/18721547/armax-model-forecasting-leads-to-valueerror-matrices-are-not-aligned-when-pas –

Trả lời

3

này có lẽ tốt hơn đăng tải trên github issue tracker. Tôi đã nộp một số ticket.

Tốt nhất là nên gửi vé tại đó, nếu không tôi có thể quên nó. Khá bận rộn những ngày này.

Đã xảy ra lỗi trong logic cho trường hợp đặc biệt của k_ar == 0. Hãy cho tôi biết nếu bạn có thể/không thể cung cấp cho miếng vá đó một spin. Nếu không, tôi có thể làm một số thử nghiệm nghiêm ngặt hơn và hợp nhất nó.

Thống kê mô-đun trên đầu trang của tia lửa? Tôi tò mò.

2

khi KẸP KIẾNG fit2 bạn đã mentionned biến exog, vì vậy không cần phải lặp lại nó:

exogx = np.array(range(1,5)) # I think you will need 4 exegeneous variables to perform an ARIMAX(0,0,0) since you want out of sample forecast with 4 steps ahead 
fit2 = sm.tsa.ARIMA(df, (0,0,0),exog = exogx).fit() 
# if you want to do an out-of-sample-forecast use fit2.forecast(steps) instead 
#I would do this 
pred = fit2.forecast(steps = 4) 
fcst_index = pd.date_range(start = df.shift(1,'10T').index[-1] , periods = 4, freq = '10T') 
fcst_serie = pd.Series(data = pred1[0], index = fcst_index) 
print fcst_serie 

Hy vọng rằng nó sẽ giúp! Đây là một bài đăng tuyệt vời.Tôi chưa bao giờ thử các biến ngoại lai trên ARIMA trước đây nhưng các bài báo cho biết nó không thực sự phù hợp với bất kỳ trường nào bạn đang sử dụng (sẽ tìm kiếm các giấy tờ nếu cần hoặc bạn có thể google)

+0

Có ai quản lý để thực hiện công việc này không? Đối mặt với cùng một vấn đề. – user3861925

0

Nếu bất kỳ ai đang sử dụng chức năng dự báo này làm việc cho tôi cho một dự đoán bước.

lịch sử là mảng đào tạo

exog là biến mảng bên ngoài

Y_exog_test là ra khỏi mẫu tương ứng với biến bên ngoài. Thay đổi nó thành ARIMAX và nó cũng làm việc

model = sm.tsa.statespace.SARIMAX(history, trend='c', order=(1,1,1),seasonal_order=(0,1,0,24),exog=yexog) 

model_fit = model.fit() 

predicted = model_fit.forecast(step=1,exog=[[Y_exog_test]], dynamic=True) 
Các vấn đề liên quan