Trong các hướng dẫn trước, chúng ta đã trình bày cách trực quan hóa và thao tác với dữ liệu chuỗi thời gian, cũng như cách tận dụng phương pháp ARIMA để tạo dự báo từ dữ liệu chuỗi thời gian. Chúng ta đã lưu ý rằng việc thiết lập tham số chính xác cho mô hình ARIMA có thể là một quá trình thủ công phức tạp, đòi hỏi một khoảng thời gian nhất định.

Các ngôn ngữ lập trình thống kê khác như R cung cấp giải pháp tự động để giải quyết vấn đề này, nhưng những phương pháp đó vẫn chưa được chính thức đưa sang Python. May mắn thay, nhóm Core Data Science trên Facebook gần đây đã công bố một phương pháp mới có tên là Prophet, cho phép các nhà phân tích dữ liệu và lập trình viên thực hiện dự báo trên quy mô lớn trong Python 3.
Điều kiện tiên quyết
Hướng dẫn này sẽ trình bày cách thực hiện dự báo chuỗi thời gian với Prophet trên cả máy tính cá nhân hoặc máy chủ từ xa. Làm việc với tập dữ liệu lớn có thể tiêu tốn nhiều bộ nhớ, vì vậy trong cả hai trường hợp, máy tính cần có ít nhất 2GB bộ nhớ để thực hiện một số phép tính trong hướng dẫn này.
Chúng 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 tham khảo hướng dẫn Cài đặt và thiết lập Jupyter Notebook cho Python 3.
Bước 1: Tải tập dữ liệu và cài đặt các gói
Để thiết lập môi trường cho dự báo chuỗi thời gian với Prophet, trước tiên chúng ta di chuyển vào môi trường lập trình cục bộ hoặc môi trường lập trình trên máy chủ:
cd environments
. my_env/bin/activate
Từ đây, hãy tạo một thư mục mới cho dự án. Chúng ta sẽ gọi nó là timeseries và sau đó di chuyển vào thư mục này. Nếu bạn đặt tên dự án khác, hãy thay thế tên đó cho timeseries trong toàn bộ hướng dẫn:
mkdir timeseries
cd timeseries
Chúng ta sẽ làm việc với tập dữ liệu Airline Passengers của Box và Jenkins (1976), trong đó chứa dữ liệu chuỗi thời gian về số lượng hành khách hàng tháng của các hãng hàng không từ năm 1949 đến 1960. Bạn có thể lưu dữ liệu bằng lệnh curl với cờ -O để ghi output vào tệp và tải xuống tệp CSV:
curl -O <https://assets.digitalocean.com/articles/eng_python/prophet/AirPassengers.csv>
Hướng dẫn này sẽ cần các thư viện pandas, matplotlib, numpy, cython và fbprophet. Giống như hầu hết các gói Python khác, chúng ta có thể cài đặt thư viện pandas, numpy, cython và matplotlib bằng pip:
pip install pandas matplotlib numpy cython
Để tính toán dự báo, thư viện fbprophet dựa trên ngôn ngữ lập trình STAN, được đặt tên để vinh danh nhà toán học Stanislaw Ulam. Trước khi cài đặt fbprophet, chúng ta cần đảm bảo đã cài đặt xong gói pystan (Python wrapper cho STAN):
pip install pystan
Khi hoàn tất, chúng ta có thể cài đặt Prophet bằng pip:
pip install fbprophet
Bây giờ mọi thứ đã được thiết lập xong, chúng ta có thể bắt đầu làm việc với các gói đã cài đặt.
Bước 2: Import các gói và tải dữ liệu
Để bắt đầu làm việc với dữ liệu, chúng ta khởi động Jupyter Notebook:
jupyter notebook
Để tạo một tệp notebook mới, chọn New > Python 3 từ menu thả xuống ở góc trên bên phải:

Tạo một notebook Python 3 mới
Thao tác này sẽ mở một notebook cho phép chúng ta tải các thư viện cần thiết.
Theo chuẩn tốt nhất, hãy bắt đầu bằng cách import các thư viện cần dùng ở đầu notebook (lưu ý các dạng viết tắt chuẩn để tham chiếu đến pandas, matplotlib và statsmodels):
%matplotlib inline
import pandas as pd
from fbprophet import Prophet
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
Lưu ý, chúng ta cũng đã định nghĩa style fivethirtyeight của matplotlib cho các biểu đồ.
Sau mỗi khối mã trong hướng dẫn này, bạn nên nhấn ALT + ENTER để chạy mã và chuyển sang một khối mã mới trong notebook.
Bắt đầu bằng cách đọc dữ liệu chuỗi thời gian. Chúng ta có thể tải tệp CSV và in ra 5 dòng đầu tiên với các lệnh sau:
df = pd.read_csv('AirPassengers.csv')
df.head(5)

DataFrame hiển thị 5 dòng đầu tiên
DataFrame của chúng ta rõ ràng có chứa cột Month và AirPassengers. Thư viện Prophet yêu cầu đầu vào là một DataFrame có một cột chứa thông tin thời gian và một cột chứa giá trị cần dự báo. Quan trọng là cột thời gian phải thuộc kiểu datetime, vì vậy chúng ta hãy kiểm tra kiểu dữ liệu của các cột:
df.dtypes
Output
Month object
AirPassengers int64
dtype: object
Vì cột Month không thuộc kiểu datetime, chúng ta sẽ cần chuyển đổi nó:
df['Month'] = pd.DatetimeIndex(df['Month'])
df.dtypes
Output
Month datetime64[ns]
AirPassengers int64
dtype: object
Bây giờ chúng ta thấy rằng cột Month đã thuộc kiểu datetime.
Prophet cũng đặt điều kiện bắt buộc rằng các cột đầu vào phải được đặt tên là ds (cột thời gian) và y (cột giá trị), vì vậy chúng ta hãy đổi tên các cột trong DataFrame:
df = df.rename(columns={'Month': 'ds',
'AirPassengers': 'y'})
df.head(5)

DataFrame sau khi đổi tên cột thành ds và y
Cách tốt nhất là trực quan hóa dữ liệu mà chúng ta sẽ làm việc, thế nên hãy vẽ biểu đồ chuỗi thời gian:
ax = df.set_index('ds').plot(figsize=(12, 8))
ax.set_ylabel('Monthly Number of Airline Passengers')
ax.set_xlabel('Date')
plt.show()

Biểu đồ chuỗi thời gian
Sau khi chuẩn bị xong dữ liệu, chúng ta có thể bắt đầu sử dụng thư viện Prophet để tạo dự báo cho chuỗi thời gian.
Bước 3: Dự báo chuỗi thời gian với Prophet
Trong phần này, chúng ta sẽ mô tả cách sử dụng thư viện Prophet để dự đoán các giá trị tương lai của chuỗi thời gian. Các tác giả của Prophet đã trừu tượng hóa nhiều độ phức tạp vốn có của dự báo chuỗi thời gian và giúp cho quá trình làm việc với dữ liệu chuỗi thời gian trở nên trực quan hơn đối với cả nhà phân tích dữ liệu lẫn lập trình viên.
Đầu tiên, chúng ta phải khởi tạo một đối tượng Prophet mới. Prophet cho phép chỉ định một số đối số. Ví dụ, chúng ta có thể chỉ định khoảng tin cậy mong muốn bằng cách thiết lập tham số interval_width.
# đặt khoảng tin cậy thành 95% (mặc định của Prophet là 80%)
my_model = Prophet(interval_width=0.95)
Bây giờ mô hình Prophet đã được khởi tạo, chúng ta có thể gọi phương thức fit với DataFrame làm đầu vào. Quá trình huấn luyện mô hình sẽ chỉ mất vài giây.
my_model.fit(df)
Bạn sẽ nhận được output tương tự như sau:
Output
<fbprophet.forecaster.Prophet at 0x110204080>
Để có được dự báo cho chuỗi thời gian, chúng ta phải cung cấp cho Prophet một DataFrame mới có cột ds chứa các ngày mà chúng ta muốn dự đoán. Tuy nhiên, chúng ta không cần tự tạo DataFrame này vì Prophet đã cung cấp hàm make_future_dataframe:
future_dates = my_model.make_future_dataframe(periods=36, freq='MS')
future_dates.tail()

DataFrame chứa các mốc thời gian trong tương lai
Trong đoạn code trên, chúng ta yêu cầu Prophet tạo 36 mốc thời gian trong tương lai.
Khi làm việc với Prophet, bạn phải xem xét tần suất của chuỗi thời gian. Vì chúng ta đang làm việc với dữ liệu hàng tháng, chúng ta đã chỉ rõ tần suất của các timestamp (trong trường hợp này, MS nghĩa là bắt đầu của tháng). Do đó, make_future_dataframe đã tạo ra 36 mốc thời gian theo tháng cho chúng ta. Nói cách khác, chúng ta đang muốn dự đoán giá trị tương lai của chuỗi thời gian trong 3 năm tới.
DataFrame chứa các ngày trong tương lai sau đó sẽ được sử dụng làm đầu vào cho phương thức predict của mô hình đã huấn luyện.
forecast = my_model.predict(future_dates)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()

DataFrame dự báo từ mô hình Prophet
Prophet trả về một DataFrame lớn với nhiều cột hữu ích, nhưng chúng ta chỉ lấy ra những cột liên quan nhất đến dự báo, bao gồm:
ds: mốc thời gian của giá trị dự báoyhat: giá trị dự báo của chỉ số (trong Thống kê,yhatlà ký hiệu truyền thống để biểu diễn giá trị dự đoán của một biếny)yhat_lower: giới hạn dưới của dự báoyhat_upper: giới hạn trên của dự báo
Việc có sự khác biệt về giá trị so với kết quả trình bày ở trên là bình thường, vì Prophet dựa trên các phương pháp Markov chain Monte Carlo (MCMC) để tạo ra dự báo. MCMC là một quá trình ngẫu nhiên, vì vậy các giá trị sẽ hơi khác nhau mỗi lần chạy.
Prophet cũng cung cấp một hàm tiện lợi để nhanh chóng vẽ kết quả dự báo:
my_model.plot(forecast,
uncertainty=True)

Biểu đồ dự báo chuỗi thời gian (Forecast Plot)
Prophet vẽ các giá trị quan sát được của chuỗi thời gian (các dấu chấm đen), giá trị dự báo (đường màu xanh lam) và khoảng tin cậy của dự báo (vùng xanh lam nhạt).
Một tính năng mạnh mẽ khác của Prophet là khả năng trả về các thành phần của dự báo. Điều này giúp làm rõ cách các mẫu hàng ngày, hàng tuần và hàng năm của chuỗi thời gian đóng góp vào giá trị dự báo tổng thể:
my_model.plot_components(forecast)

Biểu đồ các thành phần của dự báo
Biểu đồ trên mang lại nhiều thông tin thú vị. Biểu đồ đầu tiên cho thấy số lượng hành khách hàng tháng của hãng hàng không đã tăng tuyến tính theo thời gian. Biểu đồ thứ hai cho thấy số lượng hành khách hàng tuần đạt đỉnh vào cuối tuần và thứ Bảy, trong khi biểu đồ thứ ba cho thấy lượng khách cao nhất rơi vào các tháng nghỉ lễ là tháng 7 và tháng 8.
Kết luận
Trong hướng dẫn này, chúng ta đã dự báo chuỗi thời gian với Prophet trong Python. Chúng ta đã sử dụng các tham số mặc định, nhưng Prophet cho phép chỉ định thêm nhiều đối số khác. Đặc biệt, Prophet cung cấp khả năng để bạn đưa kiến thức sẵn có của mình về chuỗi thời gian vào mô hình.
Dưới đây là một vài điều bổ sung mà bạn có thể thử:
- Đánh giá tác động của các kỳ nghỉ bằng cách thêm kiến thức sẵn có của bạn về các tháng nghỉ lễ (ví dụ, chúng ta biết rằng tháng 12 là một tháng nghỉ lễ). Tài liệu chính thức về mô hình hóa ngày lễ sẽ hữu ích.
- Thay đổi phạm vi của khoảng tin cậy, hoặc dự báo xa hơn trong tương lai.
Để thực hành thêm, bạn cũng có thể thử tải một tập dữ liệu chuỗi thời gian khác để tạo dự báo riêng của mình.
Nhìn chung, Prophet mang lại nhiều tính năng hấp dẫn, bao gồm khả năng điều chỉnh mô hình dự báo phù hợp với yêu cầu của người dùng.