[Python] 난수(random number)발생과 표본추출(sampling)

업데이트:

난수생성과 샘플링

이번 포스팅에서는 표본추출과 모델링에 주로 활용되는 난수(random number)와 관련된 함수들을 알아보자.
이는 넘파이에서 제공하는 np.random 모듈이 많은 기능을 제공한다.

import numpy as np

1. 시드(seed) 설정 : np.random.seed

난수를 발생시킨다는 것은 정말 무작위로 수를 배출해낸다고 생각할 수 있지만, 실제로는 컴퓨터 프로그램에서 어떤 계산된 과정에 의한 것이다.
이는 시드(seed)라는 시작 숫자에 의한 알고리즘을 통해 난수처럼 보이는 수열을 생성하는 것이다.
즉, 이 시드값이 같다면 같은 난수를 발생시킬 수 있는 것이다.

np.random.seed(0)

이제 난수를 생성해보자 np.random.rand는 뒤에 나오겠지만 0~1사이의 난수를 입력값 만큼의 개수를 반환한다.

np.random.rand(5)
array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
np.random.rand(10)
array([0.64589411, 0.43758721, 0.891773  , 0.96366276, 0.38344152,
       0.79172504, 0.52889492, 0.56804456, 0.92559664, 0.07103606])
np.random.rand(15)
array([0.0871293 , 0.0202184 , 0.83261985, 0.77815675, 0.87001215,
       0.97861834, 0.79915856, 0.46147936, 0.78052918, 0.11827443,
       0.63992102, 0.14335329, 0.94466892, 0.52184832, 0.41466194])

무작위로 난수가 생성됨을 알 수 있다. 시드를 다시 설정하고 난수를 발생시켜보자.

np.random.seed(0)
np.random.rand(5)
array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])

처음에 시드를 설정하고 발생시킨 난수와 동일함을 알 수 있다!

2-1. 데이터 순서 바꾸기 : np.random.shuffle

x = np.arange(10)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

np.random.shuffle함수를 이용하면 배열을 섞어 다시 배열이 저장된 변수로 보내준다.(판다스의 inplace=True옵션과 같은 맥락)

np.random.shuffle(x)
x
array([0, 8, 7, 9, 1, 3, 5, 2, 4, 6])
np.random.shuffle(x)
x
array([3, 8, 6, 7, 5, 2, 0, 9, 1, 4])

2-2 데이터 순서 바꾸기 : np.random.permutation

비슷한 기능을 하는 np.random.permutation함수는 배열이 저장된 변수자체를 변경하는게 아니라, 랜덤으로 섞은 배열만을 다시 반환해준다.

x = np.arange(10)
np.random.permutation(x)
array([1, 2, 5, 0, 8, 3, 7, 9, 6, 4])

기존 배열 x는 그대로다.

x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

3. 데이터 샘플링 : np.random.choice()

이 함수는 다음과 같은 인수를 가진다.

np.random.choice(a, size=None, replace=True, p=None)

  • a : 배열이면 배열 자체, 정수이면 arange(a)명령으로 배열 생성
  • size : 정수, 샘플 숫자
  • replace : boolean. True이면 복원추출, False면 비복원추출
  • p : 배열, 각 데이터가 선택될 수 있는 확률

0~4까지 배열 중, 5개 추출, 비복원 추출

np.random.choice(5,5, replace=False)
array([2, 4, 3, 1, 0])

0~9까지 배열중, 5개 추출, 복원추출

x = np.arange(10)
np.random.choice(x,5)
array([5, 3, 3, 7, 9])

0~4까지 배열중, 10개 추출, 복원추출, 1과 4는 뽑힐확률을 0으로 지정

np.random.choice(5, 10, p=[0.1, 0, 0.3, 0.6, 0])
array([3, 2, 3, 0, 3, 2, 3, 2, 3, 2])

실제로 1과 4는 절때 뽑히지 않음을 알 수 있다.

4. 난수생성

가장 간단하고 많이 사용되는 난수 생성법은 다음과 같다.

  • np.random.rand : 0부터 1사이의 균일분포
  • np.random.randn : 가우시안 표준 정규 분포
  • np.random.randint : 균일 분포의 정수 난수

randrandn은 입력인수에 들어가는 숫자만큼의 난수를 생성하고, 여러개의 인수를 넣으면 해당 크기를 가진 행렬을 생성한다.

np.random.rand(5)
array([0.27268312, 0.14826864, 0.85630298, 0.6350568 , 0.29964349])
np.random.rand(5,5)
array([[0.46021971, 0.0245274 , 0.5580651 , 0.36115152, 0.50270954],
       [0.15362754, 0.42550764, 0.90617184, 0.00851159, 0.9688641 ],
       [0.69089373, 0.09941639, 0.28977588, 0.53907355, 0.72414785],
       [0.38886743, 0.22708397, 0.45485988, 0.97208251, 0.83381823],
       [0.91479066, 0.66728484, 0.44066609, 0.68509199, 0.64859831]])
np.random.randn(10)
array([ 0.53386311, -1.10213089,  0.2517392 ,  1.14051141, -1.49341013,
        0.71435718, -0.24106748, -0.17595882,  1.01146172, -2.74060805])
np.random.randn(2,3)
array([[ 1.90540978, -0.26825475, -1.29785512],
       [ 0.59605289, -0.86537543, -2.00020141]])

randint의 입력 인수는 다음과 같다.

numpy.random.randint(low, high=None, size=None)
만약 high를 입력하지 않으면 0과 low사이의 정수를, high를 입력하면 lowhigh는 사이의 정수를 출력한다. size는 난수의 크기이다.

low만 10으로 지정, 0~9까지의 정수 5개

np.random.randint(10, size=5)
array([7, 3, 6, 9, 3])

10~19까지의 정수 10개

np.random.randint(10,20, size=10)
array([10, 13, 19, 19, 17, 10, 14, 11, 13, 15])

이번엔 3행 5열의 행렬로 반환

np.random.randint(10, 20, size=(3, 5))
array([[11, 17, 10, 17, 15],
       [19, 17, 11, 11, 12],
       [14, 11, 14, 15, 18]])

댓글남기기