Сегодня хотел бы поговорить об одном очень важном методе, которым мы очень часто пользуемся и даже не осознаём, что у него есть названия и некоторые математические свойства🙂
Речь о знаменитом методе Монте Карло.
В середине XX века учёный Станислав Улам, работавший в Манхеттенском проекте, задумался о том, нельзя ли решать сложные задачи не классическим аналитическим образом, а многократной симуляцией. Идея пришла к нему, когда он раскладывал пасьянс. Он подумал, что расчёт вероятности выигрыша - очень сложное аналитическое упражнение, и попробовал рассчитать эту вероятность путём многократного раскладывания пасьянса.
Правда заключается в том, что бывают не только сложные аналитические задачи, но и задачи, не имеющие вовсе аналитического строгого решения.
В широком смысле это относится не только к статистике, но и к матану - бывают функции, у которых не существует первообразной, а также бывают диффуры, не имеющие явного (эксплицитного) решения.
Для таких ситуаций и существуют численные методы👍
А через пару лет этот метод развили и научно обосновали, применив его к задачам ядерной физики.
Мы часто используем его в теории вероятностей и статистике. Вспомните любую задачу, которая начинается со слов "Создадим N нормально распределённых наблюдений", - это есть не что иное, как применение метода Монте Карло, получившего своё название от известного казино в Монако.
Рассмотрим пример задачи, которую имеет смысл решать именно этим методом.
Бросаем симметричную монету 100 раз.
Какова вероятность того, что среди этих 100 бросков найдётся хотя бы один подряд идущий прогон из 7 и более орлов (то есть существует подряд идущая подпоследовательность длины ( >=7 ), состоящая только из орлов)?
Аналитически это посчитать очень сложно, так как комбинаций существует превеликое множество.
Однако эту задачу можно решить с помощью Монте Карло буквально десятком питоновских строчек
def estimate_p(N, n_flips=100, k=7):
success = 0
for _ in range(N):
max_run = 0
current_run = 0
i = 0
while i < n_flips and max_run < k: # условие выхода заранее
f = random.choice([0, 1])
if f == 1:
current_run += 1
if current_run > max_run:
max_run = current_run
else:
current_run = 0
i += 1
if max_run >= k:
success += 1
return success / N
N_values = [1000, 5000, 10000, 100000]
results = []
for N in N_values:
p_hat = estimate_p(N)
results.append({"N": N, "p_hat": p_hat})
df = pd.DataFrame(results)
print(df)В следующем посте я дам еще пример и мы поговорим о свойствах этого метода.
Да здравствуют численные методы!😀
А вы когда-нибудь пользовались таким?