[AIviVN 5 - Bandwidth Prediction 2] 2nd place solution

bandwidth_prediction

#1

Xin chào các anh chị và các bạn, mình xin chia sẻ solution của mình cho cuộc thi số 5 của AIviVN: Dự đoán lưu lượng server 2 (team jojo).

Source code đã đưa lên Github tại đây.

Hướng giải quyết

Mình đã thử một vài phương pháp cho bài toán này, các baseline dưới đây đều cho kết quả public LB tốt.

  • Baseline 0 (Moving average): Mấu chốt của cách này là tính theo từng zone và từng giờ: Với mỗi zone và mỗi giờ, mình tính moving average của x ngày gần nhất trên tập train và dùng kết quả để dự đoán trên tập test cho zone và giờ tương ứng. Xem thêm code ví dụ tại đây.
  • Baseline #1 (Median of medians): Tương tự với moving avg/median, nhưng lần này mình tính moving median của nhiều hơn 1 window khác nhau và lấy median của tất cả các median tính được.
  • Baseline #2 - XGBoost (Đọc thêm về XGBoost ở phần Tham khảo). Với cả 2 biến target (bandwidth_total và max_user), mình đều dùng XGBoost làm model duy nhất.

Final model của mình (cho kết quả public LB cao nhất) là kết hợp của Baseline #1 và Baseline #2 (final_prediction = 0.8 * XGBoost + 0.2 * median_of_medians).

Missing values

Tập train có một số thời điểm không có dữ liệu. Mình thêm vào bằng cách lấy dữ liệu cùng ngày cùng giờ của tuần trước (Ví dụ nếu dữ liệu bị mất vào 4h sáng thứ 4 thì mình sẽ lấy dữ liệu 4h sáng thứ 4 tuần trước).

Features

Time features (các đặc trưng về thời gian)

Các feature dưới đây có thể lấy dễ dàng dựa vào 2 cột update_time và hour_id

  • Hour (giờ)
  • Day (ngày)
  • Week (tuần)
  • Day of week (ngày trong tuần)
  • Month (tháng)
  • Day of year (ngày trong nằm)
  • Year (năm)

Special event features (Đặc trưng cho những sự kiện ‘đặc biệt’)

Abnormal events (sự kiện bất thường)

Khi vẽ các time series của từng zone lên mình thấy có 2 khoảng thời gian đáng lưu ý, khi mà:

  1. ZONE01: Total bandwidth và max users giảm đột biến.
  2. ZONE02: Total bandwidth và max users tăng đột biến.
  3. ZONE03: Total bandwidth tăng rất nhẹ không đáng kể, max users hơi tăng hơn so với bình thường (độ tăng nhỏ hơn so với ZONE02).

Cả 2 khoảng thời gian này đều rơi vào đầu năm (2018 và 2019). Từ đó, mình tạo thêm 2 feature mới là abnormal_bw và abnormal_u để ‘đo’ mức độ ảnh hưởng của những khoảng tăng/giảm đột biến này đối với total bandwidth và max users (Lúc đầu mình dùng boolean - 1 cho những ngày đặc biệt, 0 cho những ngày còn lại - nhưng cho kết quả không tốt bằng).

  • Với ZONE01, do cả total bandwidth và max users giảm đột biến, mình cho abnormal_bw và abnormal_u bằng -1 trong những ngày đặc biệt, 0 cho các ngày khác.
  • Tương tự với ZONE02, các biến sẽ lần lượt là 0.8 vào ngày đặc biệt và 0 cho ngày khác.
  • Với ZONE03, mình cho abnormal_bw bằng 0.2 do total bandwidth chỉ tăng rất nhẹ (gần như không tăng đột biến), nhưng cho abnormal_u bằng 0.6 vì max users tăng rõ rệt hơn.

(Các weight ở trên mình chọn khá random, không dựa trên công thức nào. Hiện tại mình nghĩ có thể áp dụng grid search để tìm bộ weight tối ưu).

Holiday events (Ngày lễ)

Mình dùng biến boolean holiday để ghi nhận các ngày lễ của Việt Nam. Mình có thêm cả 3 ngày từ 23/12/2017 đến 25/12/2017 vào danh sách holidays, do total bandwidth và max user của ZONE01 tăng đột biến.

Zone features (Đặc trưng từng zone)

Median (trung vị)

Từ dữ liệu train, mình lấy được median của total bandwidth và max users cho từng zone, với các khoảng thời gian: 1 tháng gần nhất, 3 tháng gần nhất, 6 tháng gần nhất, 1 năm gần nhất:

  • median_user_1m
  • median_bw_1m
  • median_user_3m
  • median_bw_3m
  • median_user_6m
  • median_bw_6m
  • median_user_1y
  • median_bw_1y
  • median_bw_per_user_6m
  • median_bw_per_user_3m
  • median_bw_per_user_1m
  • median_bw_per_user_1y
Autocorrelation features (Đặc trưng tự tương quan)

Với 3 tháng gần nhất trong tập train, mình tính độ tự tương quan cho mỗi zone với các độ trễ (lag) lần lượt là 1,3,7 ngày.

Linear regression prediction features

Cuối cùng, mình dùng linear regression để fit tập train (dùng các feature về thời gian, sự kiện đặc biệt và median của zone) và sau đó dùng chính dự đoán của model đó (trên cả tập train và test) để làm feature mới cho XGBoost (ridge_bw và ridge_u). Mình đã thử 2 model của sklearn là Ridge và Lasso (dùng các thông số mặc định) thì Ridge cho kết quả public tốt hơn nên mình chọn Ridge.

Kết quả

Final model cho kết quả sMAPE = 5.12708 trên public LB, và sMAPE = 5.18001 trên bảng tổng sắp (2nd place).

Cảm ơn mọi người đã đọc. Rất mong chia sẻ solution từ các đội khác để có thể học hỏi thêm các phương pháp mới.

Tham khảo


#2

Cảm ơn bạn đã chia sẻ :smiley: