Khái niệm chung
Monte Carlo Simulation là một kỹ thuật toán học dùng để hiểu và đánh giá tác động của rủi ro và không chắc chắn trong các mô hình dự đoán và dự án. Phương pháp này sử dụng các biến ngẫu nhiên để mô phỏng nhiều kịch bản có thể xảy ra của một hệ thống hoặc quy trình, giúp chúng ta ước lượng phân phối của kết quả đầu ra.
Tên gọi “Monte Carlo” xuất phát từ thành phố Monte Carlo ở Monaco, nổi tiếng với các sòng bạc và hoạt động đánh bạc. Phương pháp này được phát triển kỹ thuật bởi các nhà khoa học làm việc tại Dự án Manhattan khi họ cần giải quyết các vấn đề phức tạp liên quan đến phản ứng hạt nhân và các tính toán liên quan đến vật lý. Hai nhà khoa học trong nhóm, Stanislaw Ulam và John von Neumann, đã phát triển và sử dụng kỹ thuật này và chọn tên “Monte Carlo” để phản ánh bản chất ngẫu nhiên và các phép thử mô phỏng nhiều lần của phương pháp như các sòng bạc hoạt động.
Một vài ví dụ thực tế
Ví dụ đầu tiên:
Bạn được giao làm một bài thuyết trình về Monte Carlo, để ước lượng được thời gian hoàn thành bài thuyết trình này, bạn chia thành các bước nhỏ hơn với các thời gian ngắn hơn như sau:
- Tìm hiểu các tài liệu liên quan đến Monte Carlo Simulation: 1 - 2h (1)
- Viết tài liệu lên Confluence: 2 - 3h (2)
- Làm slide: 1 - 2h (3)
- Luyện tập kịch bản present: 0.5 - 1h (4)
Dưới góc độ của một người làm dữ liệu, bạn đang cố gắng tìm hiểu xem tổng thời gian mình bỏ ra để làm bài thuyết trình này là bao nhiêu, và nếu chỉ giới hạn trong một khoảng thời gian ngắn thì khả năng bạn có thể làm được bao nhiêu. Dựa vào các khoảng thời gian cho các đầu việc ngắn hơn, chúng ta có thể ước lượng được rằng thời gian ngắn nhất có thể hoàn thành là 1h + 2h + 1h + 0.5h = 4.5h và thời gian dài nhất có thể hoàn thành bài thuyết trình là 2h + 3h + 2h + 1h = 8h.
Tuy nhiên, để trực quan hóa hơn, chúng ta sẽ sử dụng phương pháp Monte Carlo để mô phỏng các khoảng thời g ian từ 4.5h đến 8h để xem phân phối tổng thời gian có thể hoàn thành một bài thuyết trình là như thế nào. Để làm được điều này, với mỗi đầu công việc nhỏ, chúng ta sử dụng phương pháp tạo ngẫu nhiên dựa trên các phân phối đều. Phân phối đều là một cách đơn giản và trực quan để mô phỏng các biến ngẫu nhiên, trong đó tất cả các kết quả giữa một giá trị tối thiểu và tối đa đều có xác suất xảy ra như nhau. Sau đó chúng ta sẽ tính tổng các giá trị của từng đầu việc để được tổng thời gian hoàn thành bài thuyết trình.
Giờ chúng ta sẽ sử dụng máy tính để có thể chọn ngẫu nhiên thời gian hoàn thành từng đầu việc bé và tính tổng thời gian cần. Chúng ta sẽ mô phỏng chúng hàng ngàn, triệu lần như sau:
- Lần 1: 1.2h (1) + 2.8h (2) + 1.1h (3) + 0.5h (4) = 5.6h
- Lần 2: 1.25h (1) + 2.3h (2) + 1.4h (3) + 0.7h (4) = 5.65h
- Lần 3: 1.1h (1) + 2.2h (2) + 1.3h (3) + 0.8h (4) = 5.4h
- …
- Lần 100000: 1.7h (1) + 2.1h (2) + 1.5h (3) + 0.7h (4) = 6h
Sau rất nhiều lần mô phỏng, ta được một phân phối như sau:
Vậy nhìn vào biểu đồ này ta có thể dễ dàng nói rằng ta sẽ cần khoảng từ 4.5 - 8 tiếng để hoàn thành bài thuyết trình và thời gian trung bình để hoàn thành nó là 6.25.
Nhưng ta hãy mở rộng bài toán này ra một chút. Giả sử chúng ta chỉ dành được thời gian 7 tiếng để có thể hoàn thành được công việc này. Vậy khả năng bao nhiêu % là có thể hoàn thành được bài thuyết trình này.
Như vậy, ta có thể thấy xác suất chúng ta có thể làm đúng hạn là 92.26%
Ví dụ thứ hai:
Bạn tạo và viết một số bài blog trang web Data Science Dances. Sau một thời gian marketing, bạn nhận ra rằng trung bình sẽ có 24 lượt truy cập mỗi ngày. Bạn muốn biết xác suất rằng một ngày bất kỳ sẽ nhiều hơn 30 lượt truy cập xem là bao nhiêu để có thể đặt target phù hợp cho tương lai.
Chú ý, dạng phân phối cho việc quan sát số lượt truy cập theo một khoảng thời gian cụ thể thuộc dạng phân phối Poisson. Chúng ta sẽ dùng Monte Carlo Simulation để tính toán.
import numpy as np
import matplotlib.pyplot as plt
# Số lần mô phỏng
num_simulations = 100000
# Trung bình số lượt truy cập mỗi ngày
lambda_visits_per_day = 24
# Mô phỏng số lượt truy cập mỗi ngày theo phân phối Poisson
visits_per_day = np.random.poisson(lambda_visits_per_day, num_simulations)
# Vẽ biểu đồ histogram của số lượt truy cập mỗi ngày
plt.figure(figsize=(12, 6))
plt.hist(visits_per_day, bins=30, density=True, edgecolor='k', alpha=0.7)
plt.title("Number of Visits Per Day Using Poisson Distribution", fontsize=14)
plt.xlabel("Number of Visits", fontsize=12)
plt.ylabel("Frequency", fontsize=12)
# Hiển thị đường thẳng chỉ giá trị trung bình
mean_visits = np.mean(visits_per_day)
plt.axvline(mean_visits, color='r', linestyle='--', linewidth=2, label=f'Mean: {mean_visits:.2f} visits')
plt.legend()
# Hiển thị lưới và biểu đồ
plt.grid(True)
plt.show()
Từ phân phối này, ta có thể tính được xác suất để số lượt truy cập web mỗi ngày lớn hơn 30 là 9.53%. Vậy nếu muốn đặt mục tiêu là 30 lượt truy cập/ngày thì sẽ cần cố gắng rất nhiều mới có thể đạt được mục tiêu.