(** 인터넷 익스플로러에서 보면 파이썬 코드 줄이 제대로 적용되어 보이지 않을 수 있습니다.**)
파이썬을 활용하여 확률적 요소를 지닌 프로그램을 작성한다. 주사위 던지기나 동전 던지기에서 그 결과에 대해 시뮬레이션하고 그 결과를 그래프로 보여준다.
먼저 파이썬 random 모듈을 사용하여 주사위 던지기를 시뮬레이션하는 프로그램을 작성한다.
import random
random.choice( [1,2,3,4,5,6] ) 함수는 인자로 주어진 리스트의 원소를 임의로 선택하는 라이브러리이다. 이 함수를 활용하여 주사위 던지고 어떤 숫자가 나오는지 리턴하는 함수 rollDie()를 작성한다.
def rollDie(): return random.choice([1,2,3,4,5,6])
rollDie()를 몇 차례 반복해서 사용해보자.
>>> rollDie()
1
>>> rollDie()
2
>>> rollDie()
6
>>> rollDie()
4
rollDie()를 확장해서 n번 주사위를 던진 결과를 (문자열로 만들어) 내는 함수 rollN(n)을 작성한다.
def rollN(n):
result = ''
for i in range(n):
result = result + str(rollDie())
print(result)
rollN() 함수를 두 세 차례 실행해보자. 첫 번째 실행 결과 162415433은 10번 주사위를 던저 첫 번째 숫자는 1, 두 번째 숫자는 6, ... 과 같은 결과를 얻었다고 해석하면 된다.
>>> rollN(10)
1624515433
>>> rollN(5)
21523
>>> rollN(100)
6442456646523663352443661122223244162646646634232355463631422355263526426442455335324655333223323136
>>>
이번에는 동전을 던져 앞과 뒤 어느 쪽이 나오는지 시뮬레이션하는 프로그램을 작성하자.
def flip(numFlips):
heads = 0.0
for i in range(numFlips):
if random.random() < 0.5:
heads += 1
return heads/numFlips
flip()함수는 동전을 던질 횟수 numFlips를 인자로 받아 전체 중에 몇 번 앞 면이 나오는지 세어 그 비율을 계산한다. 이때 random.random() 함수는 0과 1 사이의 실수 값을 임의로 반환하는 함수다. 그 랜덤 값이 0.5보다 작으면 동전을 던져 앞 면이 나온 것으로 약속하자.
동전 던지기 횟수를 정하여 이 함수를 사용해보시오.
확률과 통계 과목에서 배운대로 동전 던지는 횟수가 상당히 많으면 그 비율은 0.5와 가까운 값이 되는 것을 이 프로그램을 실행하여 확인할 수 있다.
동전 던기기 시뮬레이션을 한 단계 더 발전시켜보자. flipSim(numFlipsPerTrial, numTrials) 함수는 두 번째 인자 numTrials 만큼 동전 던지기를 시도하고, 각 동전 던지기 시도에 첫 번째 인자 numFlipsPerTrial 회 만큼 동전을 던진다. 즉, flipSim(100, 10)은 100회 동전 던지기를 10번 시도한다. 그 결과로 각 시도의 평균을 계산하여 리턴한다.
def flipSim(numFlipsPerTrial, numTrials):
fracHeads = []
for i in range(numTrials):
fracHeads.append(flip(numFlipsPerTrial))
mean = sum(fracHeads)/len(fracHeads)
return mean
flipSim(100,10) 또는 flip(200,1) 등을 실행하고 그 결과를 살펴보시오.
마지막으로 동전 던지기 시뮬레이션 결과를 그래프로 그려보는 파이썬 프로그램을 작성해본다. 이 프로그램은 pylab 모듈을 이용하여 그래프를 그린다. pylab 모듈의 title, xlabel, ylabel 함수로 그래프의 제목, X축 라벨, Y축 라벨을 지정할 수 있다.
def flipPlot(minExp, maxExp):
ratios = []
xAxis = []
for exp in range(minExp, maxExp + 1):
xAxis.append(2**exp)
for numFlips in xAxis:
numHeads = 0
for n in range(numFlips):
if random.random() < 0.5:
numHeads += 1
numTails = numFlips - numHeads
ratios.append(numHeads/float(numTails))
pylab.title('Heads/Tails Ratios')
pylab.xlabel('Number of Flips')
pylab.ylabel('#heads/#Tails')
pylab.plot(xAxis, ratios)
flipPlot()함수를 다음과 같이 사용한다.
>>> import pylab
>>> flipPlot(4,20)
>>> pylab.show()
flipPlot(minExp, maxExp) 함수는 ratios와 xAxis를 각각 비어있는 리스트로 초기화하며 시작한다. xAxis는 X축 값들을 포함하는 리스트로, ratios는 Y축 값들을 포함하는 리스트로 만들려고 한다.
인자로 주어진 minExp와 maxExp는 X축 값을 2^minExp부터 2^maxExp까지 지수를 1씩 증가시키면서 만들려고 받은 최소 지수와 최대 지수이다. 첫 번째 for 반복문에서 xAxis 리스트를 만든다.
두 번째 for 반복문과 중첩된 세 번째 for 반복문에서 각 X축 값들만큼 동전을 던저 앞 면이 나오는 횟수 numHeads를 구하고, 전체 횟수와의 차이에서 뒷 면이 나오는 횟수 numTrails를 구한 다음, 그 비율 numHeads/numTrails를 구한다. 이 것을 Y축 값으로 ratios에 추가한다. 이때 float(...)은 정수 ...을 실수로 변환하는 파이썬 함수이다.
최종적으로 pylab.plot(xAxis, ratios)로 그래프를 그린다. 동전 던지기에서 앞 면이 나오는 횟수와 뒷 면이 나오는 횟수의 비율이므로 많이 반복하면 그 비율은 1에 가까워질 것이다. 이러한 상식을 위 프로그램을 실행하여 나온 그래프로 확인할 수 있다.