Phương pháp Monte Carlo: Dự đoán tương lai bằng mô phỏng Python
Phương pháp Monte Carlo đã cách mạng hóa lĩnh vực lập trình và kỹ thuật. Những phương pháp này khai thác sức mạnh của tính ngẫu nhiên, biến chúng thành công cụ hiệu quả, giúp các nhà phát triển giải quyết các vấn đề phức tạp trong nhiều lĩnh vực. Phương pháp Monte Carlo đã được áp dụng trong vật lý, tài chính, kỹ thuật và nhiều lĩnh vực khác, nơi các phương pháp xác định thường không thực tế để giải quyết vấn đề.
Với phương pháp Monte Carlo, các mô phỏng và phép tính rất phức tạp trong Python đã trở nên hiệu quả và dễ quản lý. Có nhiều biến thể của phương pháp Monte Carlo. Nhưng tất cả chúng đều có chung ý tưởng sử dụng tính ngẫu nhiên để tính gần đúng các giải pháp cho các bài toán khó. Trong bài viết này, bạn sẽ tìm hiểu tất cả về phương pháp Monte Carlo.
Hiểu về phương pháp Monte Carlo qua một ví dụ
Hãy tưởng tượng bạn muốn tìm chiều cao trung bình của cây cối trong một khu rừng rộng lớn. Việc đo đạc từng cây là bất khả thi và không thực tế. Nhưng với phương pháp Monte Carlo, có thể chọn ngẫu nhiên một vài điểm trong rừng và đo chiều cao của tất cả các cây trong những điểm đó. Bằng cách thực hiện việc này nhiều lần và lấy trung bình tất cả các phép đo này, chúng ta có thể ước tính chiều cao trung bình của tất cả các cây trong rừng. Bằng cách này, có thể đưa ra những ước tính tuyệt vời trong các quần thể lớn và phức tạp bằng cách tìm các mẫu nhỏ và có thể quản lý được và tính trung bình chúng.
Phương pháp Monte Carlo là gì? Định nghĩa đơn giản nhất Phương pháp Monte Carlo là một loại thuật toán máy tính sử dụng các phép đo ngẫu nhiên lặp đi lặp lại để thu được kết quả gần đúng cho một bài toán nhất định. Chúng là một phần của lĩnh vực toán học được gọi là phân tích số - việc sử dụng các phương pháp xấp xỉ để tìm giải pháp khi các phương pháp xác định là không thực tế. Ý tưởng chính là tìm các giải pháp gần đúng đủ tốt để giải quyết các vấn đề quá khó hoặc không thể giải quyết trực tiếp. Các giải pháp này thu được bằng cách lấy trung bình cộng của nhiều mẫu được chọn ngẫu nhiên từ tập hợp các vấn đề hiện có. Bằng cách này, trong các hệ thống có nhiều yếu tố không chắc chắn và các bộ phận tương tác, phương pháp Monte Carlo có thể cung cấp thông tin chi tiết về cách hệ thống hoạt động và thực hiện. Chúng dựa trên ý tưởng toán học của Định luật số lớn trong lý thuyết xác suất:
Trung bình của nhiều biến ngẫu nhiên phân phối độc lập, giống hệt nhau hội tụ về giá trị kỳ vọng, nếu nó tồn tại.
Vấn đề chính của phương pháp Monte Carlo là thiếu nguồn lực máy tính để thực hiện nhiều mô phỏng để có được kết quả tốt.
Tại sao chúng được gọi là "Monte Carlo"?
Phương pháp Monte Carlo, được đặt theo tên của Sòng bạc Monte Carlo ở Monaco, được các nhà toán học đặt ra trong Dự án Manhattan những năm 1940. Stanislaw Ulam, John von Neumann và những người khác đã tham gia vào dự án này, dự án đã phát triển bom nguyên tử của Mỹ. Cái tên phản ánh tính ngẫu nhiên trong các mô phỏng của họ, giống như kết quả ngẫu nhiên trong cờ bạc sòng bạc.
Ứng dụng trong thế giới thực của phương pháp Monte Carlo
1. Thiết kế mạch trong kỹ thuật điện
Mạch có nhiều thành phần. Dưới đây là một số trong số đó:
- Điện trở
- Cuộn cảm
- Tụ điện
- Điốt
- Bóng bán dẫn
Do nhiệt độ của môi trường chúng ở trong, đôi khi các mạch điện có thể không hoạt động.
Vì vậy, các kỹ sư thiết kế các mạch điện chịu nhiệt như thế nào?
Nói cách khác: làm cách nào chúng ta có thể kiểm tra hiệu suất của mạch ở các nhiệt độ khác nhau?
Nhờ có phương pháp Monte Carlo, chúng ta có thể mô phỏng nhiều khoảng thời gian của điều kiện nhiệt độ và xem ảnh hưởng của chúng đối với các thành phần mạch cũng như mức độ ảnh hưởng của chúng đối với hiệu suất mạch. Bằng cách này, chúng ta có thể thu thập dữ liệu về cách các thành phần nên hoạt động dưới các ứng suất nhiệt khác nhau. Bằng cách này, chúng ta có thể tối ưu hóa mạch - cho dù là thay đổi thiết kế mạch hay chọn các thành phần khác nhau - để hoạt động trong nhiều điều kiện môi trường.
2. Thiết kế tên lửa trong kỹ thuật hàng không vũ trụ
Thiết kế tên lửa liên quan đến nhiều biến số khác nhau, chẳng hạn như:
- Tính chất vật liệu
- Lực khí động học
- Hiệu quả đẩy
- Điều kiện môi trường.
Phương pháp Monte Carlo cho phép nhiều mô phỏng với các tính chất vật liệu khác nhau, hiệu quả đẩy và nhiều biến thiết kế hơn. Điều này giúp hiểu sâu về hành vi của tên lửa trong các điều kiện khác nhau. Về bản chất, cách giải quyết ngẫu nhiên này của một vấn đề lớn là chìa khóa để hiểu hành vi xác suất của hiệu suất bay của tên lửa, như:
- Quỹ đạo
- Sự ổn định
- Tính toàn vẹn cấu trúc
Bằng cách phân tích cách các biến thiết kế này ảnh hưởng đến hành vi xác suất của các chỉ số hiệu suất bay quan trọng của tên lửa, các kỹ sư có thể chế tạo tên lửa an toàn và đáng tin cậy hơn.
3. Tối ưu hóa danh mục đầu tư tài chính trong tài chính và đầu tư
Trong tối ưu hóa danh mục đầu tư tài chính, đâu là sự kết hợp tốt nhất các tài sản trong một danh mục đầu tư để tối đa hóa lợi nhuận đồng thời giảm thiểu rủi ro? Phương pháp Monte Carlo được sử dụng để mô phỏng mức độ tốt của một danh mục đầu tư trong việc tối đa hóa lợi nhuận đồng thời giảm thiểu rủi ro trong các điều kiện thị trường khác nhau. Bằng cách tạo ra nhiều kịch bản ngẫu nhiên cho giá tài sản và lợi nhuận, các ngân hàng và tổ chức tài chính có thể biết, trong các điều kiện khác nhau, kết quả danh mục đầu tư và quản lý rủi ro. Bằng cách này, có thể đưa ra các quyết định dựa trên dữ liệu để tìm kiếm sự cân bằng giữa rủi ro và phần thưởng.
Khám phá các loại phương pháp Monte Carlo khác nhau
Có nhiều biến thể của phương pháp Monte Carlo. Dưới đây là một số điều quan trọng nhất:
1. Monte Carlo cổ điển
Monte Carlo cổ điển sử dụng các mẫu ngẫu nhiên để ước tính giá trị và mô phỏng hệ thống. Nó hữu ích cho các nhiệm vụ mà các giải pháp trực tiếp khó tìm, như tích phân số.
2. Monte Carlo Bayes
Monte Carlo Bayes cải thiện ước tính bằng cách sử dụng thông tin hiện có với các quan sát mới để đưa ra dự đoán tốt hơn.
Nó được gọi là Monte Carlo Bayes vì nó sử dụng định lý Bayes. Định lý Bayes được tạo ra bởi nhà toán học Thomas Bayes và nó rất quan trọng trong lý thuyết xác suất. Ý tưởng chính của định lý là sửa đổi niềm tin hiện có bằng dữ liệu mới. Phương pháp này lý tưởng khi bạn có một số thông tin hiện có về vấn đề.
3. Monte Carlo Chuỗi Markov (MCMC)
Đối với các tập dữ liệu lớn, phương pháp Monte Carlo thường mất quá nhiều thời gian để tính toán kết quả.
Một cách để giải quyết vấn đề này là sử dụng phiên bản nhỏ hơn của tập dữ liệu lớn. Điều này cũng giống như cách một bản tóm tắt đại diện cho nội dung của một cuốn sách vì nó nhanh hơn để đọc. Phiên bản nhỏ hơn này được gọi là Chuỗi Markov. Nói một cách đơn giản, Chuỗi Markov là những mô hình cho thấy cách một hệ thống di chuyển giữa các trạng thái.
Một tập dữ liệu lớn có thể được xem như một hệ thống và các trạng thái như các mẫu dữ liệu. Bằng cách này, Chuỗi Markov là những mô hình đơn giản có thể đại diện cho một tập dữ liệu lớn vì chúng cho thấy mọi thứ thay đổi như thế nào từ trạng thái này sang trạng thái khác. Sự thay đổi trạng thái này có thể đại diện, với ít số hơn, các mẫu quan trọng trong dữ liệu.
Bằng cách này, từ Chuỗi Markov, phương pháp Monte Carlo sẽ tính toán kết quả của nó. Về cơ bản, Monte Carlo đưa ra dự đoán gián tiếp từ dữ liệu gốc. Chuỗi Markov hoạt động như một bước tiền xử lý dữ liệu để tính toán kết quả Monte Carlo.
Cuối cùng, MCMC chỉ là một phương pháp Monte Carlo thông thường nhưng hiệu quả hơn về mặt tính toán.
4. Các biến thể khác
Các phương pháp khác như Gradient, Semi-Gradient và Quasi Monte Carlo cũng tập trung vào hiệu quả tính toán. Nhưng trong bài viết này, tôi chỉ tìm cách nêu bật tầm quan trọng của phương pháp Monte Carlo trong khoa học, kỹ thuật và lập trình.
Triển khai thực hành: Phương pháp Monte Carlo trong Python
Trong đoạn mã bên dưới, bạn sẽ thấy cách triển khai một biến thể MCMC trong Python.
Tôi sẽ demo một biến thể phổ biến của MCMC được gọi là Hamiltonian Monte Carlo (HMC).
Nó được gọi là Hamiltonian vì nó sử dụng các khái niệm từ cơ học Hamiltonian để đề xuất các trạng thái mới cho chuỗi Markov trong bước xử lý trước dữ liệu.
1. Cơ học Hamilton là gì?
Để trả lời câu hỏi này, bạn cần biết một chút về cơ học cổ điển.
Cơ học cổ điển sử dụng các định luật chuyển động của Newton để giải thích cách các hệ thống vật chất hoạt động và thay đổi theo thời gian. Cơ học Hamilton là một cách khác để xem xét các hệ thống này. Nó thường nhấn mạnh vai trò của năng lượng và sự bảo toàn của nó bằng cách sử dụng các biến khác nhau như vị trí tổng quát và động lượng. Cách mô tả độc đáo này về trạng thái và sự tiến hóa của hệ thống được sử dụng trong HMC.
2. Ví dụ cụ thể
Chúng ta sẽ tạo phân phối mục tiêu từ phân phối Gaussian 2D bằng cách sử dụng Xác suất TensorFlow. Điều này có nghĩa là HMC sẽ mô hình hóa phân phối mục tiêu này.
Phân phối Gaussian 2D được tạo bằng dữ liệu tổng hợp để chứng minh quy trình xấp xỉ bằng cách sử dụng Hamiltonian Monte Carlo.
Nói cách khác, HMC sẽ thể hiện chính xác phân phối Gaussian 2D này.
Trong các tình huống thực tế, từ mạch điện đến tài chính, tất cả các hệ thống đều có thể được mô tả như một phân phối xác suất.
Các phương pháp Monte Carlo xấp xỉ các phân phối phức tạp này. Và MCMC làm cho quá trình này nhanh hơn rất nhiều.
Trong ví dụ mã đơn giản này, tôi đang xấp xỉ một phân phối mục tiêu đơn giản để bạn có thể hiểu cách thức, trong một kịch bản thực tế, điều này sẽ được áp dụng.
Dưới đây là mã đầy đủ (chúng ta sẽ xem qua từng bước một bên dưới):
import tensorflow as tf
import tensorflow_probability as tfp
# Define the target distribution (2D Gaussian)
def target_log_prob(x, y):
return -0.5 * (x**2 + y**2)
# Initialize the HMC transition kernel
num_results = 1000
num_burnin_steps = 500
hmc = tfp.mcmc.HamiltonianMonteCarlo(
target_log_prob_fn=lambda x, y: target_log_prob(x, y),
num_leapfrog_steps=3,
step_size=0.1
)
# Define the trace function to record the state and kernel results
@tf.function
def run_chain(initial_state, kernel, num_results, num_burnin_steps):
return tfp.mcmc.sample_chain(
num_results=num_results,
num_burnin_steps=num_burnin_steps,
current_state=initial_state,
kernel=kernel,
trace_fn=lambda _, pkr: pkr
)
# Run the MCMC chain
initial_state = [tf.zeros([]), tf.zeros([])]
samples, kernel_results = run_chain(initial_state, hmc, num_results, num_burnin_steps)
# Extract the samples and log
samples_ = [s.numpy() for s in samples]
samples_x, samples_y = samples_
print("Acceptance rate: ", kernel_results.is_accepted.numpy().mean())
print("Mean of x: ", samples_x.mean())
print("Mean of y: ", samples_y.mean())
Hãy cùng tìm hiểu cách thức hoạt động của đoạn mã từng bước một. Nhập các thư viện
import tensorflow as tf
import tensorflow_probability as tfp
Trong đoạn mã này, chúng ta nhập hai thư viện Python:
- TensorFlow: Xây dựng và đào tạo các mô hình học máy
- TensorFlow Probability: Suy luận xác suất và mô hình hóa thống kê
Tạo phân phối mục tiêu
def target_log_prob(x, y):
return -0.5 * (x**2 + y**2)
Trong đoạn mã này, chúng ta xác định phân phối Gaussian 2D:
Phân phối Gaussian 2D
Biểu đồ này được xác định bởi:
Phương trình hiển thị -0.5 × (x2 + y2)
Là một phân phối Gaussian 2D, mỗi điểm dữ liệu được biểu diễn bằng hai biến có tương quan tuân theo phân phối Gaussian chung.
Nếu đây là một kịch bản thực tế, chúng ta sẽ mô hình hóa một hệ thống bằng cách tìm phân phối xác suất của nó dựa trên hai biến.
Trong nhiều ứng dụng thực tế, chẳng hạn như mạch điện, có thể có hàng tá biến liên quan.
Để mô hình hóa chính xác các hệ thống như vậy, chúng ta thường sử dụng các phân phối xác suất đa biến, tổng quát hóa khái niệm phân phối Gaussian thành nhiều chiều.
Khởi tạo Monte Carlo Chuỗi Markov
num_results = 1000
num_burnin_steps = 500
hmc = tfp.mcmc.HamiltonianMonteCarlo(
target_log_prob_fn=lambda x, y: target_log_prob(x, y),
num_leapfrog_steps=3,
step_size=0.1
Khối mã này thiết lập hạt nhân chuyển tiếp Hamiltonian Monte Carlo (HMC) bằng cách sử dụng Xác suất TensorFlow.
Đầu tiên, nó xác định hai biến:
- num_results là 1000, cho biết số lượng mẫu cần tạo
- num_burnin_steps là 500, đại diện cho số lượng mẫu ban đầu cần loại bỏ (giai đoạn burn-in).
Hạt nhân chuyển tiếp HMC được thiết lập với:
- Một hàm xác suất nhật ký mục tiêu nhận hai đầu vào và trả về xác suất nhật ký của chúng. Trong trường hợp của chúng ta, hàm xác suất nhật ký mục tiêu là phân phối gaussian 2D. Xác suất nhật ký là khả năng xảy ra của một tập hợp các giá trị cụ thể.
- Thuật toán thực hiện 3 bước mỗi lần.
- Mỗi kích thước bước (Số lượng thay đổi) là 0,1.
Tạo hàm theo dõi để ghi lại trạng thái và kết quả hạt nhân
@tf.function
def run_chain(initial_state, kernel, num_results, num_burnin_steps):
return tfp.mcmc.sample_chain(
num_results=num_results,
num_burnin_steps=num_burnin_steps,
current_state=initial_state,
kernel=kernel,
trace_fn=lambda _, pkr: pkr
)
Hàm được trang trí bằng @tf.function, giúp tối ưu hóa hiệu suất bằng cách biên dịch nó thành biểu đồ TensorFlow.
Hàm run_chain nhận bốn đối số:
- initial_state: Trạng thái ban đầu của Chuỗi Markov.
- kernel: Hạt nhân chuyển tiếp MCMC sẽ sử dụng (chẳng hạn như Hamiltonian Monte Carlo).
- num_results: Số lượng mẫu cần tạo.
- num_burnin_steps: Số lượng mẫu ban đầu cần loại bỏ (giai đoạn burn-in).
Hàm gọi tfp.mcmc.sample_chain để thực hiện lấy mẫu MCMC:
- num_results: Số lượng mẫu cần vẽ.
- num_burnin_steps: Số bước burn-in.
- current_state: Trạng thái bắt đầu của Chuỗi Markov.
- kernel: Hạt nhân chuyển tiếp xác định quá trình lấy mẫu.
- trace_fn: Một hàm chỉ định những gì cần theo dõi trong quá trình lấy mẫu. Trong trường hợp này, nó trả về kết quả hạt nhân trước đó (pkr), theo dõi hiệu quả trạng thái nội bộ của thuật toán MCMC.
Chạy chuỗi MCMC
# Run the MCMC chain
initial_state = [tf.zeros([]), tf.zeros([])]
samples, kernel_results = run_chain(initial_state, hmc, num_results, num_burnin_steps)
# Extract the samples and log
samples_ = [s.numpy() for s in samples]
samples_x, samples_y = samples_
print("Acceptance rate: ", kernel_results.is_accepted.numpy().mean())
print("Mean of x: ", samples_x.mean())
print("Mean of y: ", samples_y.mean())
Được rồi, hãy chia nhỏ điều này vì có rất nhiều điều đang diễn ra ở đây:
Khởi tạo trạng thái:
- initial_state được đặt thành một danh sách chứa hai tenxơ bằng 0, đóng vai trò là điểm bắt đầu cho Chuỗi Markov.
Chạy chuỗi MCMC:
- Hàm run_chain được gọi với trạng thái ban đầu, hạt nhân HMC, số lượng kết quả và số bước burn-in.
- Hàm trả về hai giá trị: samples, là các mẫu được tạo và kernel_results, chứa kết quả từ hạt nhân (bao gồm thông tin chẩn đoán).
Trích xuất và chuyển đổi mẫu:
- Các mẫu được chuyển đổi từ tenxơ TensorFlow thành mảng NumPy để dễ dàng thao tác và phân tích hơn.
- samples_ là một biểu thức bao gồm danh sách chuyển đổi mỗi tenxơ mẫu thành một mảng numpy.
- samples_x và samples_y là các mẫu được trích xuất cho hai chiều.
In Chẩn đoán:
- Tỷ lệ chấp nhận của bộ lấy mẫu MCMC được tính toán và in ra. Nó cho thấy tỷ lệ đề xuất được chấp nhận trong quá trình lấy mẫu.
- Phương tiện của các mẫu cho cả hai chiều (x và y) được tính toán và in ra để cung cấp bản tóm tắt kết quả lấy mẫu.
Điều này cho kết quả là:
- Tỷ lệ chấp nhận: 1.0. Điều này có nghĩa là tất cả các đề xuất được đưa ra trong quá trình lấy mẫu đều được chấp nhận.
- Giá trị trung bình của x: -0,11450629 và giá trị trung bình của y: -0,23079416. Trong phân phối Gaussian 2D hoàn hảo, giá trị trung bình của x và y là 0.
Với biến thể MCMC này, chúng ta đang xấp xỉ phân phối Gaussian 2D. Nhưng nó gần bằng không. Điều này có nghĩa là, với nhiều thời gian tính toán hơn, nó có thể sẽ đi đến một số thậm chí còn nhỏ hơn cho đến khi nó quá nhỏ đến mức có thể coi là bằng không.
Kết luận: Tương lai của phương pháp Monte Carlo
Tương lai của phương pháp Monte Carlo nằm ở việc tạo ra các biến thể yêu cầu ít tài nguyên tính toán hơn và tiết kiệm thời gian.
Với những tiến bộ này, phương pháp Monte Carlo sẽ tìm thấy ứng dụng bổ sung trong nhiều lĩnh vực hơn.
Nhờ có phương pháp Monte Carlo, chúng ta có thể mô hình hóa các hệ thống và hiện tượng phức tạp mà trước đây không thể thực hiện một cách hiệu quả. Cảm ơn các bạn đã theo dõi.
All rights reserved