Python 함수값 얼마 이상일 때 그리기

0. 차례

1. 들어가기

2. 확률분포란?

3. 정규분포이란(Normal probability Distribution)?

4-1. 정규분포 그리기

4-2. 정규분포확률 구하기 및 누적확률밀도분포 그리기

4-3. 정규분포의 분위수(quartile) 구하기

4-4. 정규확률분포의 랜덤난수 구하기

5. 요약

6. 참고자료(Reference)

7. 더보기

1. 들어가기

이번 포스팅에서는 정규확률분포(Normal probability distribution)를 R에서 어떻게 구현할 수 있는 지에 대해 살펴보겠습니다. Python에서는 많은 종류의 확률분포에 대한 함수가 내장되어있습니다. 확률밀도 뿐만 아니라 누적분포값, 난수생성, 분위수값을 각각 구할 수 있습니다.

2. 확률분포란?

확률분포는 확률변수가 특정한 값을 가질 확률을 나타내는 함수를 의미합니다. 예를 들어 주사위를 던질 때 나오는 수가 확률변수가 되었을 때, 모든 수가 가지는 확률을 표나 그래프로 나타낸 것이라고 생각하면 됩니다. 확률분포는 확률변수가 취하는 값이 이산값이냐 연속값이에 따라 이산확률분포(discrete probability distribution)와 연속확률분포(Continuous probability distribution)로 나뉩니다.

3. 정규분포이란(Normal probability Distribution)?

정규분포는 연속확률분포로서 가장 자주 쓰이는 확률분포입니다. 모양은 평균을 중심으로 하나의 봉우리형태를 띄며 한 집단의 많은 사람들의 키, 몸무게, 시험성적 등의 데이터에 잘 나타나는 분포입니다. 가우시안(Gausssian) 분포라고 불리며 위치모수는 평균(μ)와 모양모수 표준편차(σ)을 가집니다(즉, 이 수치에 의해 정규분포의 특성이 결정된다고 생각하면 됩니다.) 수식은 다음과 같이 표현됩니다.

확률변수 X가 정규분포를 따를 때 간단하게 'X~N(μ, σ2)' 로 표시합니다.

4-1. 정규분포 그리기

Python에서 정규분포의 확률밀도값(확률값이 아님을 유의)은 scipy.stats 패키지의 norm.pdf() 함수로 구할 수 있습니다. 이때 norm.pdf() 함수의 인자는 다음과 같습니다.

scipy.stats 패키지의 norm.pdf() 함수

x

확률변수값

loc

평균(μ)

scale

표준편차(σ)

그럼, 평균이 0이고 표준편차가 1인 정규분포(표준정규분포)를 그려보도록 하겠습니다.

>>> #정규확률분포 그리기 >>> from scipy.stats import norm >>> import matplotlib.pyplot as plt >>> import numpy as np >>> rv = norm(loc = 0, scale = 1) #평균 0이고 표준편차 1인 정규분포 객체 만들기 >>> x = np.arange(-3, 3, 0.01) #X 확률변수 범위 >>> y = rv.pdf(x) #X 범위에 따른 정규확률밀도값 >>> fig, ax = plt.subplots(1,1) >>> ax.plot(x, y,'bo', ms=8, label = 'normal pdf') >>> ax.vlines(x, 0, y, colors='b', lw =5, alpha =0.5) #결과는 >>> ax.set_ylim([0,1.05]) #y축 범위

Python 함수값 얼마 이상일 때 그리기

위에서 확인할 수 있는 것처럼 평균 0을 기준으로 대칭임을 알 수 있습니다.

4-2. 정규분포확률 구하기 및 누적확률밀도분포 그리기

연속확률밀도함수값은 확률을 의미하는 것이 아니며 확률은 특정 구간의 확률밀도함수의 너비가 됩니다. 즉 P(-2<X<2)은 -2<X<2의 넓이를 구해야 합니다. P(-2<X<2)는 P(X<2) - P(X<-2)로 구할 수 있는데 P(X<-2), P(X<2)는 확률밀도함수의 누적밀도를 구하는 함수인 scipy 패키지의 norm.cdf() 함수로 구할 수 있습니다. norm.cdf() 함수의 입력인자는 다음과 같습니다.

scipy.stats 패키지의 norm.cdf() 함수

x

확률변수값

loc

평균(μ)

scale

표준편차(σ)

우선, P(-2<X<2)의 확률값을 norm.cdf() 함수로 구해보도록 하겠습니다.

>>> #정규확률분포 그리기 >>> from scipy.stats import norm >>> rv = norm(loc = 0, scale = 1) #평균 0이고 표준편차 1인 정규분포 객체 만들기 >>> rv.cdf(2) - rv.cdf(-2) #P(-2 < X < 2) 확률구하기 0.9544997361036416

P(-2 < X < 2)의 확률은 0.9544997 임을 알 수 있습니다.

정규누적확률밀도분포 역시 norm.cdf() 함수를 이용하면 쉽게 그릴 수 있습니다.

>>> #정규누적확률분포그리기 >>> from scipy.stats import norm >>> import matplotlib.pyplot as plt >>> import numpy as np >>> rv = norm(loc = 0, scale = 1) #표준정규확률객체 만들기 >>> x = np.arange(-3, 3, 0.05) #X 확률변수 범위 >>> y = rv.cdf(x) #X 범위에 따른 누적확률밀도값 >>> fig, ax = plt.subplots(1,1) >>> ax.plot(x, y,'bo', ms=4, label = 'normal pmf') >>> ax.vlines(x, 0, y, colors='b', lw =5, alpha =0.5) #결과는 >>> ax.set_ylim([0,1.05]) #y축 범위

Python 함수값 얼마 이상일 때 그리기

위의 그래프처럼 X가 증가할 수록 1에 수렴하는 그래프가 그려짐을 확인할 수 있습니다.

4-3. 정규분포의 분위수(quartile) 구하기

어느 고등학교생의 전교생의 상위 5%의 수학점수는 얼마인지를 구하라는 문제를 가끔보게 됩니다. 이것을 수학적인 용어로 바꾸면 0.95 분위수를 구하라는 말이 됩니다. 만약 특정분포가 정규분포이다면 Python에서는 scipy 패키지의 norm.ppf() 함수를 이용해서 구할 수 있습니다. norm.ppf() 함수의 입력인자는 다음과 같습니다.

scipy.stats 패키지의 norm.ppf() 함수

q

분위수 값

loc

평균(μ)

scale

표준편차(σ)

그럼 0.5 분위수값을 구해보도록 하겠습니다.

>>> #0.5 분위수값 구하기 >>> from scipy.stats import norm >>> rv = norm(loc = 0, scale = 1) #표준정규확률객체 만들기 >>> rv.ppf(0.5) #0.5 분위수값 0.0

위에서 알 수 이있듯이 0.5 분위수는 X=0임을 알 수 있습니다.

4-4. 정규확률분포의 랜덤난수 구하기

scipy.stats 패키지의 norm.rvs() 함수는 정규확률분포로부터 난수를 생성시킬 수 있습니다. 입력인자는 size, random_state 등이 있으며 size 인자는 난수갯수이며, random_state은 난수가 계산될 때, 초기값을 정하여 항상 같은 결과가 나오게 설정하는 인자입니다. random_state는 정수로 입력하면 됩니다.

먼저, random_state을 입력하지 않고 같은 난수 코드를 실행시켜봅시다.

>>> #정규확률분포의 랜덤난수 생성하기 :같은 코드 다른 난수(!주의) >>> from scipy.stats import norm >>> rv = norm(loc = 0, scale = 1) #정규확률객체 만들기 >>> rv.rvs(size = 4) #정규확률분포를 따르는 4개 난수생성(첫번째 실행) array([ 0.85627447, -0.70502111, -0.32706468, 0.7818646 ]) >>> rv.rvs(size = 4) #정규확률분포를 따르는 4개 난수생성(두번째 실행) array([-0.77839222, -2.17774312, 1.05850259, 0.29187685])

위에서 확인할 수 있듯이 같은 코드를 실행시켰는 데, 난수 결과는 완전히 다릅니다. 이를 통제하고 싶으면 rvs() 함수의 random_state 인자를 아래와 같이 설정하여 실행시킵니다.

>>> #random_state을 이용한 초기값고정: 같은 코드 같은 난수 >>> from scipy.stats import norm >>> rv = norm(loc = 0, scale = 1) #표준정규확률객체 만들기 >>> rv.rvs(size = 4, random_state = 50) #정규확률분포를 따르는 4개 난수생성 첫번째 실행 array([-1.56035211, -0.0309776 , -0.62092842, -1.46458049]) >>> rv.rvs(size = 4, random_state = 50) #정규확률분포를 따르는 4개 난수생성 두번째 실행 array([-1.56035211, -0.0309776 , -0.62092842, -1.46458049])

위에서 확인할 수 있듯이 첫번째 실행을 하든 두 번째 실행을 하든 같은 난수가 생성되게 됩니다. 2번 이상을 시도해도 같은 난수가 생성되게 됩니다.

5. 요약

- Python에서 scipy.stats 패키지를 이용해 정규확률분포에 대한 함수를 사용할 수 있음.

- 정규확률분포는 norm.함수명을 사용.​

- 정규확률밀도함수는 norm.pdf()함수를사용함.​

- 정규누적확률밀도함수는 norm.cdf()함수를 사용함.​

- 정규확률분포의 분위수는 norm.ppf()함수를 사용함.​

- 정규확률분포의 랜덤난수생성은 norm.rvs()함수를 사용함.

- 랜덤난수를 생성할 때, norm.rvs() 함수의 random_state 인자로 초기값을 고정할 수 있음.

6. 참고자료(Reference)

1) https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.norm.html

7. 더보기

1) R로 정규확률분포 그리기