개발자가 몬티홀 문제(Monty Hall Problem) 이해하는 이야기

몬티 홀 문제(Monty Hall Problem)

몬티 홀은 이 문제를 소개한 TV쇼의 사회자이다. 방송을 계기로 문제가 유명해지면서 문제의 이름이 몬티 홀 문제(Monty Hall Problem)로 굳어졌다. 문제는 아래와 같다.

  • 문이 세 개가 있다. 하나의 문 뒤에는 자동차(상품)가 있고, 나머지 두 개의 문 뒤에는 염소(꽝)가 있다.
  • 참가자는 문 하나를 고른다.
  • 사회자는 참가자가 선택하지 않은 문 중 염소가 있는 문을 하나 열어서 보여준다.
  • 사회자는 참가자에게 문을 바꿀 수 있는 기회를 준다.
  • 이 때 참가자는 문을 바꾸는 게 이익일까? 바꾸지 않는 게 이익일까?

정답은 바꾸는 게 더 이익이다. 바꾸지 않으면 당첨 확률이 1/3이지만 바꾸면 2/3로 확률이 높아진다.

어설픈 직관

문제와 정답만 보고 왜 그런지 이해하기는 쉽지가 않다. 나는 얼마 전 점심 시간에 팀원에게 이 문제를 들었는데, 틀린 답을 내놓았다. (나를 포함해서) 사람들이 흔히 하는 착각은 이것이다.

어차피 두 개 중 하나니까 50대 50 아닌가?

애초에 문이 두 개였으면 50대 50이 맞지만 몬티 홀 문제는 그렇지 않다. 처음에는 문이 세 개이고, 정답을 알고 있는 사회자가 개입하여 정답이 아닌 문을 하나 열어준다. 남은 두 개의 문은 참가자가 고른 문과 사회자가 남은 모든 문들 중 정답을 피해 열고 남은 문이다. 문을 10개로 늘려보자. 여전히 자동차는 하나이고, 아홉 개의 문 뒤에는 염소가 있다. 참가자는 문을 하나 고르고, 사회자는 남은 아홉 개의 문들 중 정답이 아닌 문 여덟 개를 열어준다. 이렇게 문이 두 개가 남았어도 50대 50이라고 할 수 있을까?

참가자가 문을 바꾸지 않으면 당첨 확률은 처음 고를 때의 확률과 같다. 문이 3개일 때는 1/3이고, 10개일 때는 1/10이다. 따라서 바꿨을 때 당첨 확률은 그 나머지인 2/3, 9/10이 된다. 사실 이렇게 설명해도 여전히 이해가 되지 않을 수도 있다. 개발자라면 몬테카를로 시뮬레이션 프로그램을 작성해보자. 이해하는 데 확실히 도움이 된다!

몬테카를로 시뮬레이션

몬테카를로 방법은 난수를 이용하여 원하는 값을 추정하는 방법이다. random 함수를 이용하여 몬티 홀 문제를 모델링한 다음 여러 번 수행하여 참가자가 문을 바꿨을 때 당첨 확률과 바꾸지 않았을 때 당첨 확률을 추정할 수 있다. 아래는 내가 파이썬으로 작성한 몬티 홀 시뮬레이션 프로그램이다.

여기서 문제를 모델링한 함수는 다음과 같다.

함수 기능
problem() cnt는 문의 개수이다. 하나만 자동차이고, 나머지 cnt - 1개가 염소인 문제가 생성된다.
select() 참가자가 문을 선택한다.
last_other_door() doors, answer는 문제에서 정의된 문들과 정답이다. selected는 참가자가 선택한 문이다. 사회자가 나머지 문들 중 염소가 있는 문들을 보여주고 문을 하나만 남긴다.
montyhall() cnt는 문의 개수, change는 사용자가 문을 바꾸면 True 아니면 False이다. 몬티 홀 문제를 수행하고, 사용자가 당첨되면 True를 반환한다.
monte_carlo() montyhall()을 여러번 수행하여 확률을 추정한다.

내 경우에는 프로그램을 다 작성하기 전에 ‘아하!’ 하고 깨닫는 순간이 있었는데, 그건 select() 함수를 작성할 때이다. 이 함수는 참가자가 무작위로 문을 고르는 행위를 모델링한다. 참가자가 문을 무작위로 선택하여 정답을 맞힐 확률은 1/N(문의 개수)이다. 참가자가 문을 바꾸지 않는다면 이 확률은 변하지 않는다. 반대로 문을 바꾸면 그 나머지 확률인 (N-1)/N이 당첨 확률이 된다.

이 파이썬 프로그램으로 문이 3개인 문제를 100000번 시뮬레이션해보면 아래와 같은 결과를 얻을 수 있다.

$ python montyhall.py 3 100000
probability when you stay
0.33566
probability when you change
0.66879

문을 10개로 바꾸면 아래와 같은 결과가 나온다.

$ python montyhall.py 10 100000
probability when you stay
0.10014
probability when you change
0.89918

다르게 보기

동일한 문제를 다르게 해석하면 이해가 더 쉬울 수 있다. 참가자 A와 B가 있다. A는 N개의 문 중에 하나만 선택하고, 나머지 N-1개의 문을 B가 다 갖는다. 그럼 A와 B가 자동차를 가질 확률은 각각 어떻게 될까? 당연히 A는 1/N이고, B는 (N-1)/N이다. 사회자는 여흥을 위해 B가 가진 문들 중 자동차가 아닌 문 N-2개를 열어주는 것 뿐이다. 이제 자신이 A라고 생각해보자. B와 문을 바꿀 것인가?

참고 문서

몬티홀 문제 - 나무위키
몬테카를로 방법 - 위키피디아