Hướng dẫn Dự báo chuỗi thời gian với ARIMA bằng Python 3
Chuỗi thời gian cung cấp cơ hội để dự báo các giá trị trong tương lai. Dựa trên các giá trị trước đó, chuỗi thời gian được dùng để dự báo các xu hướng về kinh tế, thời tiết và lập kế hoạch năng lực, để kể tên một số. Các thuộc tính cụ thể của dữ liệu chuỗi thời gian nghĩa là các phương pháp thống kê chuyên biệt thường được yêu cầu.Trong hướng dẫn này, ta sẽ hướng tới việc đưa ra các dự báo tin cậy về chuỗi thời gian. Ta sẽ bắt đầu bằng cách giới thiệu và thảo luận các khái niệm về tự tương quan, tính ổn định và tính thời vụ, đồng thời tiến hành áp dụng một trong những phương pháp được sử dụng phổ biến nhất để dự báo chuỗi thời gian, được gọi là ARIMA.
Một trong những phương pháp có sẵn trong Python để lập mô hình và dự đoán các điểm trong tương lai của một chuỗi thời gian được gọi là SARIMAX , viết tắt của Seasonal AutoRegressive Integrated Moving A Average với hồi quy điện tử . Ở đây, ta sẽ chủ yếu tập trung vào thành phần ARIMA, được sử dụng để phù hợp với dữ liệu chuỗi thời gian để hiểu rõ hơn và dự báo các điểm trong tương lai trong chuỗi thời gian.
Yêu cầu
Hướng dẫn này sẽ trình bày cách thực hiện phân tích chuỗi thời gian trên máy tính local hoặc server từ xa. Làm việc với các tập dữ liệu lớn có thể tốn nhiều bộ nhớ, vì vậy trong cả hai trường hợp, máy tính cần ít nhất 2GB bộ nhớ để thực hiện một số phép tính trong hướng dẫn này.
Để tận dụng tối đa hướng dẫn này, một số thông tin quen thuộc với chuỗi thời gian và thống kê có thể hữu ích.
Đối với hướng dẫn này, ta sẽ sử dụng Jupyter Notebook để làm việc với dữ liệu. Nếu bạn chưa có, bạn nên làm theo hướng dẫn của ta để cài đặt và cài đặt Jupyter Notebook cho Python 3 .
Bước 1 - Cài đặt gói
Để cài đặt môi trường của ta cho dự báo chuỗi thời gian, trước tiên ta hãy chuyển sang môi trường lập trình local hoặc môi trường lập trình dựa trên server của ta :
- cd environments
- . my_env/bin/activate
Từ đây, hãy tạo một folder mới cho dự án của ta . Ta sẽ gọi nó là ARIMA
và sau đó chuyển vào folder . Nếu bạn gọi dự án bằng một tên khác, hãy đảm bảo thay thế tên của bạn cho ARIMA
trong suốt hướng dẫn
- mkdir ARIMA
- cd ARIMA
Hướng dẫn này sẽ yêu cầu các thư viện warnings
, itertools
, pandas
, numpy
, matplotlib
và statsmodels
. Các warnings
và thư viện itertools
đi kèm với bộ thư viện Python tiêu chuẩn, vì vậy bạn không cần phải cài đặt chúng.
Giống như với các gói Python khác, ta có thể cài đặt các yêu cầu này bằng pip
.
Bây giờ ta có thể cài đặt pandas
, statsmodels
và gói dữ liệu biểu đồ matplotlib
. Các phụ thuộc của chúng cũng sẽ được cài đặt:
- pip install pandas numpy statsmodels matplotlib
Đến đây, ta đã cài đặt để bắt đầu làm việc với các gói đã cài đặt.
Bước 2 - Nhập các gói và tải dữ liệu
Để bắt đầu làm việc với dữ liệu của ta , ta sẽ khởi động Jupyter Notebook:
- jupyter notebook
Để tạo file sổ tay mới, hãy chọn Mới > Python 3 từ trình đơn kéo xuống trên cùng bên phải:
Thao tác này sẽ mở một sổ ghi chép.
Thực tiễn tốt nhất, hãy bắt đầu bằng cách nhập các thư viện bạn cần ở đầu sổ ghi chép của bạn :
import warnings import itertools import pandas as pd import numpy as np import statsmodels.api as sm import matplotlib.pyplot as plt plt.style.use('fivethirtyeight')
Ta cũng đã xác định một phong cách matplotlib
là fivethirtyeight cho các lô của ta .
Ta sẽ làm việc với tập dữ liệu có tên “CO2 trong khí quyển từ các mẫu không khí liên tục tại Đài quan sát Mauna Loa, Hawaii, USA ,” thu thập các mẫu CO2 từ tháng 3 năm 1958 đến tháng 12 năm 2001. Ta có thể đưa ra dữ liệu này như sau:
data = sm.datasets.co2.load_pandas() y = data.data
Hãy xử lý trước dữ liệu của ta một chút trước khi tiếp tục. Dữ liệu hàng tuần có thể khó làm việc vì đó là khoảng thời gian ngắn hơn, vì vậy ta hãy sử dụng số liệu trung bình hàng tháng để thay thế. Ta sẽ thực hiện chuyển đổi với chức năng resample
. Để đơn giản hơn, ta cũng có thể sử dụng hàm fillna()
đảm bảo rằng ta không có giá trị nào bị thiếu trong chuỗi thời gian của bạn .
# The 'MS' string groups the data in buckets by start of the month y = y['co2'].resample('MS').mean() # The term bfill means that we use the value before filling in missing values y = y.fillna(y.bfill()) print(y)
Outputco2 1958-03-01 316.100000 1958-04-01 317.200000 1958-05-01 317.433333 ... 2001-11-01 369.375000 2001-12-01 371.020000
Hãy khám phá chuỗi thời gian e này dưới dạng trực quan hóa dữ liệu:
y.plot(figsize=(15, 6)) plt.show()
Một số mẫu có thể phân biệt xuất hiện khi ta vẽ biểu đồ dữ liệu. Chuỗi thời gian có một mô hình thời vụ rõ ràng, cũng như một xu hướng tăng tổng thể.
Để tìm hiểu thêm về xử lý trước chuỗi thời gian, vui lòng tham khảo “ Hướng dẫn trực quan hóa chuỗi thời gian với Python 3 ”, trong đó các bước ở trên được mô tả chi tiết hơn nhiều.
Bây giờ ta đã chuyển đổi và khám phá dữ liệu của bạn , hãy chuyển sang dự báo chuỗi thời gian với ARIMA.
Bước 3 - Mô hình chuỗi thời gian ARIMA
Một trong những phương pháp phổ biến nhất được sử dụng trong dự báo chuỗi thời gian được gọi là mô hình ARIMA, viết tắt của A utoreg R essive I ntegrated M oving A verage. ARIMA là một mô hình có thể được kết hợp với dữ liệu chuỗi thời gian để hiểu rõ hơn hoặc dự đoán các điểm trong tương lai trong chuỗi.
Có ba số nguyên riêng biệt ( p
, d
, q
) được sử dụng để tham số hóa mô hình ARIMA. Do đó, các mô hình ARIMA được ký hiệu với ký hiệu ARIMA(p, d, q)
. Ba thông số này kết hợp với nhau tính theo mùa, xu hướng và nhiễu trong tập dữ liệu:
-
p
là phần tự động hồi quy của mô hình. Nó cho phép ta kết hợp ảnh hưởng của các giá trị trong quá khứ vào mô hình của ta . Về mặt trực quan, điều này tương tự như nói rằng trời có khả năng sẽ ấm vào ngày mai nếu trời ấm trong 3 ngày qua. -
d
là phần tích hợp của mô hình. Điều này bao gồm các điều khoản trong mô hình kết hợp số lượng chênh lệch (tức là số điểm thời gian trong quá khứ cần trừ khỏi giá trị hiện tại) để áp dụng cho chuỗi thời gian. Về mặt trực giác, điều này tương tự như việc nói rằng có thể sẽ có cùng nhiệt độ vào ngày mai nếu sự khác biệt về nhiệt độ trong ba ngày qua là rất nhỏ. -
q
là phần trung bình động của mô hình. Điều này cho phép ta đặt lỗi của mô hình của ta dưới dạng kết hợp tuyến tính của các giá trị lỗi được quan sát tại các thời điểm trước đó trong quá khứ.
Khi xử lý các hiệu ứng theo mùa, ta sử dụng ARIMA theo mùa , được ký hiệu là ARIMA(p,d,q)(P,D,Q)s
. Ở đây, (p, d, q)
là các tham số không theo mùa được mô tả ở trên, trong khi (P, D, Q)
theo cùng một định nghĩa nhưng được áp dụng cho thành phần theo mùa của chuỗi thời gian. Thuật ngữ s
là chu kỳ của chuỗi thời gian ( 4
cho khoảng thời gian hàng quý, 12
cho khoảng thời gian hàng năm, v.v.).
Phương pháp ARIMA theo mùa có thể gây khó khăn vì có nhiều thông số điều chỉnh liên quan. Trong phần tiếp theo, ta sẽ mô tả cách tự động hóa quá trình xác định bộ thông số tối ưu cho mô hình chuỗi thời gian ARIMA theo mùa.
Bước 4 - Lựa chọn tham số cho mô hình chuỗi thời gian ARIMA
Khi tìm cách khớp dữ liệu chuỗi thời gian với mô hình ARIMA theo mùa, mục tiêu đầu tiên của ta là tìm các giá trị của ARIMA(p,d,q)(P,D,Q)s
để tối ưu hóa số liệu quan tâm. Có nhiều hướng dẫn và phương pháp hay nhất để đạt được mục tiêu này, tuy nhiên việc tham số hóa chính xác các mô hình ARIMA có thể là một quy trình thủ công vất vả, đòi hỏi thời gian và kiến thức chuyên môn về domain . Các ngôn ngữ lập trình thống kê khác như R
cung cấp các cách tự động để giải quyết vấn đề này , nhưng chúng vẫn chưa được chuyển sang Python.Trong phần này, ta sẽ giải quyết vấn đề này bằng cách viết mã Python để lập trình chọn các giá trị tham số tối ưu cho mô hình chuỗi thời gian ARIMA(p,d,q)(P,D,Q)s
.
Ta sẽ sử dụng "tìm kiếm lưới" để khám phá lặp đi lặp lại các kết hợp thông số khác nhau. Đối với mỗi sự kết hợp của các thông số, ta phù hợp với một mô hình ARIMA mùa mới với SARIMAX()
chức năng từ statsmodels
module và đánh giá chất lượng tổng thể của nó. Khi ta đã khám phá toàn bộ bối cảnh thông số, bộ thông số tối ưu của ta sẽ là bộ thông số mang lại hiệu suất tốt nhất cho tiêu chí quan tâm của ta . Hãy bắt đầu bằng cách tạo ra sự kết hợp khác nhau của các thông số mà ta muốn đánh giá:
# Define the p, d and q parameters to take any value between 0 and 2 p = d = q = range(0, 2) # Generate all different combinations of p, q and q triplets pdq = list(itertools.product(p, d, q)) # Generate all different combinations of seasonal p, q and q triplets seasonal_pdq = [(x[0], x[1], x[2], 12) for x in list(itertools.product(p, d, q))] print('Examples of parameter combinations for Seasonal ARIMA...') print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[1])) print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[2])) print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[3])) print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[4]))
OutputExamples of parameter combinations for Seasonal ARIMA... SARIMAX: (0, 0, 1) x (0, 0, 1, 12) SARIMAX: (0, 0, 1) x (0, 1, 0, 12) SARIMAX: (0, 1, 0) x (0, 1, 1, 12) SARIMAX: (0, 1, 0) x (1, 0, 0, 12)
Bây giờ ta có thể sử dụng bộ ba tham số được xác định ở trên để tự động hóa quá trình đào tạo và đánh giá mô hình ARIMA trên các tổ hợp khác nhau. Trong Thống kê và Học máy, quá trình này được gọi là tìm kiếm lưới (hoặc tối ưu hóa siêu tham số) để lựa chọn mô hình.
Khi đánh giá và so sánh các mô hình thống kê được trang bị các tham số khác nhau, mỗi mô hình có thể được xếp hạng với nhau dựa trên mức độ phù hợp của nó với dữ liệu hoặc khả năng dự đoán chính xác các điểm dữ liệu trong tương lai. Ta sẽ sử dụng giá trị AIC
(Tiêu chí thông tin Akaike), giá trị này được trả về một cách thuận tiện với các mô hình ARIMA được trang bị bằng cách sử dụng mô hình statsmodels
. AIC
đo lường mức độ phù hợp của một mô hình với dữ liệu trong khi tính đến độ phức tạp tổng thể của mô hình. Một mô hình phù hợp với dữ liệu rất tốt trong khi sử dụng nhiều tính năng sẽ được chỉ định điểm AIC lớn hơn so với một mô hình sử dụng ít tính năng hơn để đạt được cùng độ phù hợp. Do đó, ta quan tâm đến việc tìm kiếm mô hình mang lại giá trị AIC
thấp nhất.
Mã đoạn dưới đây lặp thông qua sự kết hợp của các thông số và sử dụng các SARIMAX
chức năng từ statsmodels
để phù hợp với mô hình tương ứng theo mùa ARIMA. Ở đây, order
lập luận xác định (p, d, q)
các thông số, trong khi seasonal_order
quy định cụ thể đối số (P, D, Q, S)
thành phần theo mùa của mô hình ARIMA mùa. Sau khi lắp từng SARIMAX()
, mã sẽ in ra điểm AIC
tương ứng.
warnings.filterwarnings("ignore") # specify to ignore warning messages for param in pdq: for param_seasonal in seasonal_pdq: try: mod = sm.tsa.statespace.SARIMAX(y, order=param, seasonal_order=param_seasonal, enforce_stationarity=False, enforce_invertibility=False) results = mod.fit() print('ARIMA{}x{}12 - AIC:{}'.format(param, param_seasonal, results.aic)) except: continue
Bởi vì một số kết hợp tham số có thể dẫn đến sai số, ta đã tắt thông báo cảnh báo một cách rõ ràng để tránh quá tải thông báo cảnh báo. Những sai sót này cũng có thể dẫn đến lỗi và tạo ra một ngoại lệ, vì vậy ta đảm bảo nắm bắt những ngoại lệ này và bỏ qua các tổ hợp tham số gây ra những vấn đề này.
Đoạn mã trên sẽ mang lại các kết quả sau, quá trình này có thể mất một chút thời gian:
OutputSARIMAX(0, 0, 0)x(0, 0, 1, 12) - AIC:6787.3436240402125 SARIMAX(0, 0, 0)x(0, 1, 1, 12) - AIC:1596.711172764114 SARIMAX(0, 0, 0)x(1, 0, 0, 12) - AIC:1058.9388921320026 SARIMAX(0, 0, 0)x(1, 0, 1, 12) - AIC:1056.2878315690562 SARIMAX(0, 0, 0)x(1, 1, 0, 12) - AIC:1361.6578978064144 SARIMAX(0, 0, 0)x(1, 1, 1, 12) - AIC:1044.7647912940095 ... ... ... SARIMAX(1, 1, 1)x(1, 0, 0, 12) - AIC:576.8647112294245 SARIMAX(1, 1, 1)x(1, 0, 1, 12) - AIC:327.9049123596742 SARIMAX(1, 1, 1)x(1, 1, 0, 12) - AIC:444.12436865161305 SARIMAX(1, 1, 1)x(1, 1, 1, 12) - AIC:277.7801413828764
Đầu ra mã của ta gợi ý rằng SARIMAX(1, 1, 1)x(1, 1, 1, 12)
mang lại giá trị AIC
thấp nhất là 277,78. Do đó, ta nên coi đây là lựa chọn tối ưu trong số tất cả các mô hình ta đã xem xét.
Bước 5 - Phù hợp với mô hình chuỗi thời gian ARIMA
Sử dụng tìm kiếm lưới, ta đã xác định được tập hợp các tham số tạo ra mô hình phù hợp nhất với dữ liệu chuỗi thời gian của ta . Ta có thể tiến hành phân tích mô hình cụ thể này sâu hơn.
Ta sẽ bắt đầu bằng cách cắm các giá trị tham số tối ưu vào một mô hình SARIMAX
mới:
mod = sm.tsa.statespace.SARIMAX(y, order=(1, 1, 1), seasonal_order=(1, 1, 1, 12), enforce_stationarity=False, enforce_invertibility=False) results = mod.fit() print(results.summary().tables[1])
Output============================================================================== coef std err z P>|z| [0.025 0.975] ------------------------------------------------------------------------------ ar.L1 0.3182 0.092 3.443 0.001 0.137 0.499 ma.L1 -0.6255 0.077 -8.165 0.000 -0.776 -0.475 ar.S.L12 0.0010 0.001 1.732 0.083 -0.000 0.002 ma.S.L12 -0.8769 0.026 -33.811 0.000 -0.928 -0.826 sigma2 0.0972 0.004 22.634 0.000 0.089 0.106 ==============================================================================
Thuộc tính summary
là kết quả từ kết quả của SARIMAX
trả về một lượng thông tin đáng kể, nhưng ta sẽ tập trung sự chú ý vào bảng hệ số. Cột coef
hiển thị trọng số (tức là tầm quan trọng) của từng tính năng và cách mỗi tính năng tác động đến chuỗi thời gian. P>|z|
cho ta biết tầm quan trọng của từng trọng số đối tượng địa lý. Ở đây, mỗi trọng số có giá trị p thấp hơn hoặc gần bằng 0.05
, vì vậy sẽ hợp lý để giữ lại tất cả chúng trong mô hình của ta .
Khi lắp các mô hình ARIMA theo mùa (và bất kỳ mô hình nào khác cho vấn đề đó), điều quan trọng là phải chạy chẩn đoán mô hình đảm bảo rằng không có giả định nào do mô hình đưa ra bị vi phạm. Đối tượng plot_diagnostics
cho phép ta nhanh chóng tạo ra chẩn đoán mô hình và điều tra xem có bất kỳ hành vi bất thường nào không.
results.plot_diagnostics(figsize=(15, 12)) plt.show()
Mối quan tâm chính của ta là đảm bảo phần dư của mô hình của ta không tương quan và được phân phối bình thường với giá trị trung bình bằng 0. Nếu mô hình ARIMA theo mùa không đáp ứng các đặc tính này, thì đó là một dấu hiệu tốt cho thấy nó có thể được cải thiện hơn nữa.
Trong trường hợp này, chẩn đoán mô hình của ta gợi ý rằng phần dư của mô hình được phân phối bình thường dựa trên những điều sau:
Trong biểu đồ trên cùng bên phải, ta thấy rằng đường
KDE
màu đỏ theo sát với đườngN(0,1)
(trong đóN(0,1)
) là ký hiệu chuẩn cho phân phối chuẩn với giá trị trung bình là0
và độ lệch chuẩn là1
) . Đây là một dấu hiệu tốt cho thấy phần dư được phân phối bình thường.Biểu đồ qq ở phía dưới bên trái cho thấy phân phối có thứ tự của phần dư (chấm màu xanh) tuân theo xu hướng tuyến tính của các mẫu được lấy từ phân phối chuẩn chuẩn với
N(0, 1)
. , đây là một dấu hiệu mạnh mẽ cho thấy phần dư được phân phối bình thường.Phần dư theo thời gian (ô trên cùng bên trái) không hiển thị bất kỳ tính thời vụ rõ ràng nào và có vẻ là nhiễu trắng. Điều này được xác nhận bởi biểu đồ tự tương quan (tức là tương quan) ở phía dưới bên phải, cho thấy rằng phần dư của chuỗi thời gian có mối tương quan thấp với các version trễ của chính nó.
Những quan sát đó giúp ta kết luận rằng mô hình của ta tạo ra sự phù hợp thỏa đáng có thể giúp ta hiểu dữ liệu chuỗi thời gian của bạn và dự báo các giá trị trong tương lai.
Mặc dù ta có một sự phù hợp ưng ý, một số thông số của mô hình ARIMA theo mùa của ta có thể được thay đổi để cải thiện sự phù hợp với mô hình của ta . Ví dụ: tìm kiếm lưới của ta chỉ được coi là một tập hợp giới hạn các kết hợp tham số, vì vậy ta có thể tìm thấy các mô hình tốt hơn nếu ta mở rộng tìm kiếm lưới.
Bước 6 - Xác thực dự báo
Ta đã có được một mô hình cho chuỗi thời gian của bạn và hiện được dùng để đưa ra dự báo. Ta bắt đầu bằng cách so sánh các giá trị dự đoán với giá trị thực của chuỗi thời gian, điều này sẽ giúp ta hiểu được độ chính xác của các dự báo của bạn . Các get_prediction()
và conf_int()
cho phép ta lấy các giá trị và khoảng tin cậy liên quan cho các dự báo của chuỗi thời gian.
pred = results.get_prediction(start=pd.to_datetime('1998-01-01'), dynamic=False) pred_ci = pred.conf_int()
Đoạn mã trên yêu cầu các dự báo bắt đầu từ tháng 1 năm 1998.
Đối số dynamic=False
đảm bảo ta tạo ra các dự báo trước một bước, nghĩa là các dự báo tại mỗi thời điểm được tạo bằng cách sử dụng toàn bộ lịch sử cho đến thời điểm đó.
Ta có thể vẽ biểu đồ các giá trị thực và dự báo của chuỗi thời gian CO2 để đánh giá mức độ ta đã làm. Lưu ý cách ta phóng to vào cuối chuỗi thời gian bằng cách cắt index ngày.
ax = y['1990':].plot(label='observed') pred.predicted_mean.plot(ax=ax, label='One-step ahead Forecast', alpha=.7) ax.fill_between(pred_ci.index, pred_ci.iloc[:, 0], pred_ci.iloc[:, 1], color='k', alpha=.2) ax.set_xlabel('Date') ax.set_ylabel('CO2 Levels') plt.legend() plt.show()
Nhìn chung, các dự báo của ta rất phù hợp với các giá trị thực, cho thấy xu hướng tăng tổng thể.
Nó cũng hữu ích để định lượng độ chính xác của các dự báo của ta . Ta sẽ sử dụng MSE (Mean Squared Error), tóm tắt sai số trung bình trong các dự báo của ta . Đối với mỗi giá trị dự đoán, ta tính khoảng cách của nó với giá trị thực và bình phương kết quả. Kết quả cần được bình phương để các khác biệt dương / âm không triệt tiêu lẫn nhau khi ta tính giá trị trung bình tổng thể.
y_forecasted = pred.predicted_mean y_truth = y['1998-01-01':] # Compute the mean square error mse = ((y_forecasted - y_truth) ** 2).mean() print('The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
OutputThe Mean Squared Error of our forecasts is 0.07
MSE của dự báo đi trước một bước của ta mang lại giá trị là 0.07
, rất thấp vì nó gần bằng 0. MSE bằng 0 sẽ cho thấy công cụ ước tính dự đoán các quan sát của tham số với độ chính xác hoàn hảo, đây sẽ là một kịch bản lý tưởng nhưng nó thường không thể.
Tuy nhiên, có thể thu được bản trình bày tốt hơn về khả năng dự đoán thực sự của ta bằng cách sử dụng dự báo động. Trong trường hợp này, ta chỉ sử dụng thông tin từ chuỗi thời gian cho đến một thời điểm nhất định và sau đó, dự báo được tạo bằng cách sử dụng các giá trị từ các mốc thời gian dự báo trước đó.
Trong đoạn mã dưới đây, ta chỉ định bắt đầu tính toán các dự báo động và khoảng tin cậy từ tháng 1 năm 1998 trở đi.
pred_dynamic = results.get_prediction(start=pd.to_datetime('1998-01-01'), dynamic=True, full_results=True) pred_dynamic_ci = pred_dynamic.conf_int()
Vẽ biểu đồ các giá trị được quan sát và dự báo của chuỗi thời gian, ta thấy rằng các dự báo tổng thể đều chính xác ngay cả khi sử dụng dự báo động. Tất cả các giá trị được dự báo (đường màu đỏ) khá trùng với sự thật cơ bản (đường màu xanh lam) và nằm trong repository ảng tin cậy của dự báo của ta .
ax = y['1990':].plot(label='observed', figsize=(20, 15)) pred_dynamic.predicted_mean.plot(label='Dynamic Forecast', ax=ax) ax.fill_between(pred_dynamic_ci.index, pred_dynamic_ci.iloc[:, 0], pred_dynamic_ci.iloc[:, 1], color='k', alpha=.25) ax.fill_betweenx(ax.get_ylim(), pd.to_datetime('1998-01-01'), y.index[-1], alpha=.1, zorder=-1) ax.set_xlabel('Date') ax.set_ylabel('CO2 Levels') plt.legend() plt.show()
, ta xác định hiệu suất dự đoán của các dự báo bằng cách tính toán MSE:
# Extract the predicted and true values of our time series y_forecasted = pred_dynamic.predicted_mean y_truth = y['1998-01-01':] # Compute the mean square error mse = ((y_forecasted - y_truth) ** 2).mean() print('The Mean Squared Error of our forecasts is {}'.format(round(mse, 2)))
OutputThe Mean Squared Error of our forecasts is 1.01
Các giá trị dự đoán thu được từ các dự báo động mang lại MSE là 1,01. Con số này cao hơn một chút so với con số đi trước một bước, dự kiến là ta đang dựa vào ít dữ liệu lịch sử hơn từ chuỗi thời gian.
Cả dự báo trước một bước và dự báo động đều xác nhận mô hình chuỗi thời gian này là hợp lệ. Tuy nhiên, phần lớn mối quan tâm xung quanh dự báo chuỗi thời gian là khả năng dự báo các giá trị tương lai một cách kịp thời.
Bước 7 - Sản xuất và hình dung các dự báo
Trong bước cuối cùng của hướng dẫn này, ta mô tả cách tận dụng mô hình chuỗi thời gian ARIMA theo mùa của ta để dự báo các giá trị trong tương lai. Thuộc tính get_forecast()
của đối tượng chuỗi thời gian của ta có thể tính toán các giá trị dự báo cho một số bước cụ thể phía trước.
# Get forecast 500 steps ahead in future pred_uc = results.get_forecast(steps=500) # Get confidence intervals of forecasts pred_ci = pred_uc.conf_int()
Ta có thể sử dụng kết quả của mã này để vẽ chuỗi thời gian và dự báo các giá trị trong tương lai của nó.
ax = y.plot(label='observed', figsize=(20, 15)) pred_uc.predicted_mean.plot(ax=ax, label='Forecast') ax.fill_between(pred_ci.index, pred_ci.iloc[:, 0], pred_ci.iloc[:, 1], color='k', alpha=.25) ax.set_xlabel('Date') ax.set_ylabel('CO2 Levels') plt.legend() plt.show()
Cả dự báo và khoảng tin cậy liên quan mà ta đã tạo hiện được dùng để hiểu thêm về chuỗi thời gian và dự đoán những gì sẽ xảy ra. Dự báo của ta cho thấy chuỗi thời gian dự kiến sẽ tiếp tục tăng với tốc độ ổn định.
Khi ta dự báo xa hơn về tương lai, điều tự nhiên là ta trở nên thiếu tự tin hơn vào giá trị của bạn . Điều này được phản ánh bởi các khoảng tin cậy do mô hình của ta tạo ra, các khoảng này ngày càng lớn hơn khi ta tiến xa hơn trong tương lai.
Kết luận
Trong hướng dẫn này, ta đã mô tả cách triển khai mô hình ARIMA theo mùa bằng Python. Ta đã sử dụng rộng rãi thư viện pandas
và mô hình statsmodels
và chỉ ra cách chạy chẩn đoán mô hình, cũng như cách tạo dự báo về chuỗi thời gian CO2.
Dưới đây là một số cách khác mà bạn có thể thử:
- Thay đổi ngày bắt đầu dự báo động của bạn để xem điều này ảnh hưởng như thế nào đến chất lượng tổng thể của dự báo.
- Hãy thử kết hợp nhiều tham số hơn để xem liệu bạn có thể cải thiện mức độ phù hợp của mô hình của bạn hay không.
- Chọn một số liệu khác để chọn mô hình tốt nhất. Ví dụ: ta đã sử dụng thước đo
AIC
để tìm ra mô hình tốt nhất, nhưng thay vào đó, bạn có thể tìm cách tối ưu hóa sai số bình phương trung bình ngoài mẫu.
Để thực hành nhiều hơn, bạn cũng có thể thử tải một tập dữ liệu chuỗi thời gian khác để đưa ra dự báo của bạn .
Các tin liên quan
Cách tạo lớp và xác định đối tượng trong Python 32017-03-17
Hướng dẫn về image hóa chuỗi thời gian với Python 3
2017-03-14
Cách viết comment bằng Python 3
2017-03-03
Cách xác định hàm trong Python 3
2017-02-28
Phân tích và trực quan hóa dữ liệu với pandas và notebook Jupyter bằng Python 3
2017-02-23
Cách vẽ biểu đồ tần suất từ bằng matplotlib với Python 3
2017-02-17
Cách cài đặt gói pandas và làm việc với cấu trúc dữ liệu trong Python 3
2017-02-10
Cách cài đặt gói pandas và làm việc với cấu trúc dữ liệu trong Python 3
2017-02-10
Cách cài đặt gói pandas và làm việc với cấu trúc dữ liệu trong Python 3
2017-02-10
Cách viết module trong Python 3
2017-02-03