Отвечая на загадку Монти Холла с Монте-Карло
Монте-Карло - концептуально простой, но мощный метод, который широко используется. Он использует случайность для ответов на вопросы.
В этом посте я объясню, как решить проблему Монти Холла с помощью метода Монте-Карло. Реализация выполнена на языке программирования python, название которого само по себе является данью уважения британской Comedy Group - Monty Python.
Проблема Монти Холла
Впервые я познакомился с проблемой Монти Холла в фильме - 21. Этот клип демонстрирует проблему.
Этому есть объяснения со стороны Майкла Дэвида Стивенса из Vsauce и Vox.
Давайте перейдем к проблеме - Представьте, перед вами три двери.
Ведущий игрового шоу просит вас выбрать одну из дверей. Если вы выберете правильную дверь, вы выиграете машину, иначе получите козу.
Допустим, вы выбрали дверь №1
Ведущий игрового шоу, который знает, что находится за каждой дверью - открывает дверь № 3 и показывает козу.
Организатор игрового шоу предлагает два варианта
- Наклейка с дверцей № 1
- Переключитесь на номер двери. 2
Что бы вы выбрали?
Эксперименты Монте-Карло
Определение экспериментов Монте-Карло согласно wikipWikipedia методы те-Карло или эксперименты Монте-Карло, представляют собой широкий класс вычислительных алгоритмов, которые полагаются на о повторной случайной выборке для получения числовых результатов. Основная идея заключается в использовании случайности для решения проблем, которые в принципе могут быть детерминированными ».
Это означает, что вы можете моделировать эксперимент любое количество раз в зависимости от некоторого условия или условий, а затем анализировать результаты моделирования, чтобы прийти к решению.
В фильме «Мстители: Война бесконечности» Доктор Стрэндж выполняет почти 14 миллионов симуляций будущего, чтобы определить, сколько из будущих результатов выиграют мстители? По сути, он применяет принципы экспериментов Монте-Карло.
Моделирование Монти Холла с помощью Монте-Карло
Представьте, что описанная ранее игра застряла в петле, как Билл Мюррей в фильме День сурка.
Каждый раз, когда происходит игра, мы фиксируем успехи и неудачи при удержании первой выбранной двери, а также переключение на новую дверь.
Допустим, игра проводилась 100 раз. Мы проверим, в скольких из этих 100 игр машина была выиграна, не переключая дверь и не переключая дверь.
Глядя на эти коэффициенты, мы узнаем, какой вариант увеличивает шансы на успех.
Кодификация Монти Холла и Монте-Карло
Давайте определим функцию, которая имитирует проблему Монти Холла.
def monty_hall(): ...
В рамках функции создайте три двери с автомобилем, случайным образом назначенным одной из дверей. Значение «1» в списке соответствует автомобилю.
doors = [0, 1, 0] shuffle(doors)
Игрок выбирает дверь, которую нужно открыть. Значения 0,1 и 2 представляют собой индексы переменной списка «дверей».
door_selected = choice([0, 1, 2])
Ведущий игрового шоу теперь открывает дверь, за которой нет машины.
non_car_doors = list() for i,d in enumerate(doors): if d == 0 and i != door_selected: non_car_doors.append(i) door_opened = choice(non_car_doors)
Теперь оцените следующие два варианта
- Выигрывает автомобиль, придерживаясь первоначального выбора
non_switch_success = True if doors[door_selected] == 1 else False
2. Побеждает автомобиль, переключившись на оставшуюся дверь.
remaining_door = set([0,1,2]).difference([door_selected, door_opened]) remaining_door = remaining_door.pop() switch_success = True if doors[remaining_door] == 1 else False
Наконец, верните успех для каждого из вариантов
return non_switch_success, switch_success
Определите функцию Монте-Карло, которая принимает единственный аргумент «n», представляющий количество запускаемых симуляций. Запустите моделирование Монте-Холла «n» раз и верните распределение успешности для каждого из вариантов.
def monte_carlo(n): non_switch_success_count = 0 switch_success_count = 0 for i in range(n): ns, ss = monty_hall() non_switch_success_count += ns switch_success_count += ss print(f"Number of plays: {n}") print(f"Number of success on switch: {switch_success_count} {(switch_success_count/n)*100}%") print(f"Number of success on non-switch: {non_switch_success_count} {(non_switch_success_count/n)*100}%")
Полный код можно найти ниже, а также узнать, как его запустить, в комментариях заголовка.
Запуск симуляции
Смоделируем 100 игр
╰─$ ./main.py 100 Number of plays: 100 Number of success on switch: 71 71.0% Number of success on non-switch: 29 28.999999999999996%
Мы видим, что переключение происходит более успешно.
Давай снова запустим
╰─$ ./main.py 100 Number of plays: 100 Number of success on switch: 62 62.0% Number of success on non-switch: 38 38.0%
Мы все еще можем видеть, что переключение более успешное, но процент успеха сильно различается.
Давайте запустим одно и то же моделирование для 1 миллиона игр и сделаем это 3 раза, чтобы увидеть, сильно ли различаются проценты успеха.
╰─$ ./main.py 1000000 Number of plays: 1000000 Number of success on switch: 666566 66.6566% Number of success on non-switch: 333434 33.3434% ╰─$ ./main.py 1000000 Number of plays: 1000000 Number of success on switch: 666588 66.6588% Number of success on non-switch: 333412 33.3412% ╰─$ ./main.py 1000000 Number of plays: 1000000 Number of success on switch: 666628 66.6628% Number of success on non-switch: 333372 33.3372%
Мы видим, что процент успеха не сильно различается, и это говорит нам о том, что если мы сделаем переход, то шансы на победу увеличиваются в 2 раза из 3.
Сделай переключатель!
Заключение
Мотивация этого поста заключалась в том, чтобы познакомить с методом Монте-Карло и применить его к проблеме, которая проста для понимания и интересна для новичков. Метод Монте-Карло может показаться простым концептуально, но это мощный метод, который активно используется в финансовой индустрии, обучении с подкреплением, физических науках, вычислительной биологии и т. Д. И т. Д.