미국 공학박사의 코딩 연구소

데이터 분석의 기초인 균등분포 난수 공부하기

불확실성을 내포한 실제 데이터들을 분석하는데 사용되는 난수 중 균등분포 난수를 공부해 볼까요?
균등분포 난수(Uniform Distribution Random Number)는 기계학습(Machine Learning)의 한 종류인 강화학습(Reinforcement Learning)에서도 사용된답니다.


강의들은 모두 무료입니다. 단, 저작권은 키클 코딩랩 에 있으며, 무단 복제 및 배포를 엄금합니다.
이를 어길 시, 본 사이트의 서버가 미국에 있으므로, 미국법에 의해 처벌될 수도 있습니다.




균등분포 난수와 Numpy의 uniform() 이해하기

실제 데이터들의 불확실성을 분석할 때는 주로 정규분포 난수 (Normal/Gaussian Distribution Random Number)나 균등분포 난수(Uniform Distribution Random Number)를 많이 사용해요. 정규분포 난수는 나중에 기회될 때 알아보기로 하고, 이번 강의에서는 균등분포 난수를 공부할 거예요.

균등분포 난수는 주어진 선택 가능한 항목들 중 하나를 무작위로 선택하는 경우에 많이 사용되요.
예를 들어, 0에서 3까지 네 개의 정수, 즉, 0, 1, 2, 3 중 하나를 무작위로 선택해야 한다고 생각해 보세요. 단, 어떤 특정 정수에 유리하지 않고, 모든 정수가 동등한 선택 확률을 갖은 채로 선택해야 하는 것이죠.
이런 상황을 분석하기 위해, 위와 같은 선택을 하는 어떤 개체(사람 혹은 기계)를 코딩으로 구현해보고, 정말로 균일한 확률로 선택을 하는지 확인해 볼까요?

원하는 폴더에 새로운 Python파일을 만들고, "lec6_uniform_dist.py"라고 파일 이름을 지어 보지요.
균등분포 난수 생성을 위해서 Numpy에 있는 Random이라는 객체를 이용할 거예요. 그러니, 아래 줄1과 같이 Numpy를 np라는 별명으로 import해 보세요.

위 줄3에서는 네 개의 요소를 갖는 1차원 배열을 생성해서 cnt라는 변수에 할당했어요. 네 가지의 선택지 중 무작위 선택하는 코딩을 할 것이기 때문에 네 개의 요소를 갖는 배열을 선언했답니다.
배열의 개념에 관해서 복습이 필요하면 여기로 가서 꼭 확인하세요. Numpy의 array()를 이용해서 배열을 생성하는 방법은 아래와 같이 다시 한 번 설명하지요.

[라이브러리] Numpy의 array()

이제 Numpy 라이브러리에 구현되어 있는 Random객체의 uniform()함수를 이용해서 균등분포 난수를 생성할 건데요, 코딩에 들어가기 전에 uniform()함수에 대해서 먼저 짚어보고 갈까요? (아래 설명은 라이브러리 노트에서도 볼 수 있답니다.)

[라이브러리] Random의 uniform()




네 가지 선택지를 무작위 선택하기

자, 이제 네 가지 선택지 중에서 균등분포로 선택지 하나를 무작위 선택할 건데요. 앞서, 정말로 균일한 확률로 선택을 하는지 확인해 보자고 했었죠? 그 확인을 위한 방법으로, 무작위 선택을 엄청 많이 반복해 보고, 각 선택지들이 선택된 횟수를 세어보지요.

여러번 선택을 하기 위해서, 아래 줄5처럼 for 루프를 사용해 보지요. For 루프에 대한 복습이 필요하면, 여기로~!
저는 10,000번의 무작위 선택을 하기로 마음 먹었고, 그래서 range(10000)을 코딩했답니다.

그리고, 균등한 확률로 무작위 선택을 해야 하니, 균등한 확률로 무작위 숫자를 생성하는 uniform()을 줄6에서 코딩했어요.
단, 난수 생성 범위는 [0.0, 4.0)으로 했답니다. 이유는 네 가지 선택지를 가정하기 때문이예요. 즉, 생성된 난수가 [0.0, 1.0)의 범위에 있으면 첫번째 선택지가, [1.0, 2.0)의 범위에 있으면 두번째 선택지가, [2.0, 3.0)의 범위에 있으면 세번째 선택지가, [3.0, 4.0)의 범위에 있으면 네번째 선택지가 선택된 것으로 간주하는 것이지요.

위 생각을 코딩으로 구현한 부분이 아래 줄8에서 줄16까지의 코드랍니다.

줄8에서 idx라는 이름의 변수를 0으로 초기화 했구요. 줄9~10에서, 생성된 난수가 [0.0, 1.0)의 범위에 있는지 if문과 and 논리 연산자를 이용해서 확인했지요.
논리 연산자에 대해서 짚어볼까요?

[문법] 논리 연산자 (Logical Operator)

줄11~12는 [1.0, 2.0) 범위를 체크하고, 줄13~14는 [2.0, 3.0) 범위를, 줄 15~16은 나머지 범위를 체크하여 해당하는 범위를 나타내는 인덱스 번호를 idx에 할당했답니다.
다시 말해, [0.0, 4.0) 범위에서 균등분포 난수를 생성한 후, 그 난수가 속하는 범위를 네 가지 선택지에 대응시킴으로써 우리가 원하는 무작위 선택을 구현한 것이지요.

네 가지 선택지들 중에서 하나를 무작위로 선택했으니, 해당 선택이 이루어진 횟수를 기록해 볼까요? 그 횟수들을 나중에 확인해 보면, 무작위 선택이 정말로 균등분포를 이루는지 알 수 있거든요.
줄3에서 선언된 네 개의 0을 요소로 갖는 배열 cnt를 각 선택지의 선택 횟수를 기록하는 용도로 사용해 보지요. 선택된 선택지의 인덱스 번호가 idx에 저장되어 있으니, 아래의 줄18에서와 같이 idx에 해당하는 cnt의 요소를 1 증가시키도록 해 보지요. 그러면, 10,000번의 무작위 선택 동안 각 선택지가 선택되는 횟수를 cnt에 저장할 수 있게 된답니다.
그리고, for 루프가 끝나면, 즉, 10,000번의 무작위 선택이 끝나면, 줄20에서 처럼 cnt배열을 출력하도록 코딩해 보세요. 그러면, 10,000번의 무작위 선택 동안 각 선택지가 선택된 총 횟수를 볼 수 있어요.

이제, 지금까지 코딩한 파일을 저장 후 실행해 보세요.
저는 아래와 같은 결과가 출력되었답니다.

이론적으로는 균등분포이어야 하니, 각각 모두 2,500번의 선택 횟수를 가져야 하겠지만, 위에서 보는 바와 같이 정확하게 2,500번씩 선택이 되지는 않아요. 그래도, 각 선택 횟수들이 2,500번에 근접한 것을 확인할 수는 있어요. 말 그대로 무작위로 숫자를 뽑아내기 때문에, 불확실성이 존재하고, 고로, 이론에 의한 2500이라는 숫자가 정확하게 나오지는 않는답니다.

그럼 이 균등분포 난수가 기계학습의 한 종류인 강화학습에서 어떻게 사용되느냐?
궁금하면, 다음 강의로 Go~

강의에서 작성된 소스 코드 (source code)를 다운받으려면, 다음 링크를 클릭하세요: 소스 코드 다운로드
혹시, 이해가 잘 안되는 부분에 대한 질문이 있거나 다루어 줬으면 하는 주제가 있으면, 화면 오르쪽 하단에 "질문하기" 버튼을 이용해 주세요.






발자취

2019-09-11 "키클 코딩랩 - 미국 공학박사 아빠의 코딩 연구소"로 이름 변경
2019-06-28 코딩 교실 공개
2019-03-18 코딩 교실 제작 시작

바로가기
Python 배움터
C/C++ 배움터
About
Contact
Privacy Policy
강의목록
질문하기
처음으로