다운로드
작성자: admin 작성일시: 2016-09-22 20:44:31 조회수: 6039 다운로드: 326
카테고리: Python 태그목록:

SciPy를 이용한 확률분포 분석

SciPy는 수치해석기능을 제공하는 파이썬 패키지다. SciPy는 여러 개의 서브 패키지로 구성되어 있는데 그 중 stats 서브패키지는 확률분포 분석을 위한 다양한 기능을 제공한다.

In [1]:
import scipy as sp
import scipy.stats

확률분포 클래스

SciPy에서 확률분포 기능을 사용하려면 우선 해당 확률분포에 대한 확률분포 클래스 객체를 생성한 후에 이 객체의 메서드를 호출해야한다.

확률분포 객체를 생성하는 명령에는 다음과 같은 것들이 있다.

종류 이름 확률분포
이산 bernoulli 베르누이 분포
이산 binom 이항 분포
이산 multinomial 다항 분포
연속 uniform 균일 분포
연속 norm 가우시안 정규 분포
연속 beta 베타 분포
연속 gamma 감마 분포
연속 t 스튜던트 t 분포
연속 chi2 카이 제곱 분포
연속 f F 분포
연속 dirichlet 디리클리 분포
연속 multivariate_normal 다변수 가우시안 정규 분포

이 명령들은 모두 stats 서브패키지에 포함되어 있다. 예를 들어 가우시안 정규 분포 객체는 다음과 같이 생성한다.

In [2]:
rv = sp.stats.norm()

모수 지정

확률분포 객체를 생성할 때는 분포의 형상을 구체적으로 지정하는 모수(parameter)를 인수로 지정해 주어야 한다. 각 확률분포마다 지정해 주어야 할 모수의 종류가 다르므로 자세한 설명은 SciPy 문서를 참조하여야 한다. 하지만 대부분 다음과 같은 모수들을 공통적으로 가진다.

인수 의미
loc 일반적으로 분포의 기댓값
scale 일반적으로 분포의 표준편차

예를 들어 기댓값이 1이고 표준 편차가 2인 정규 분포 객체는 다음과 같이 생성한다.

In [3]:
rv = sp.stats.norm(loc=1, scale=2)

확률분포 메서드

확률분포 객체가 가지는 메서드는 다음과 같다.

메서드 기능
pmf 확률질량함수 (probability mass function)
pdf 확률밀도함수 (probability density function)
cdf 누적분포함수 (cumulative distribution function)
ppf 누적분포함수의 역함수 (inverse cumulative distribution function)
sf 생존함수 (1 - 누적분포함수) (survival function)
isf 생존함수의 역함수 (inverse survival function)
rvs 랜덤 표본 생성 (random variable sampling)

메서드 사용법은 다음과 같다.

확률밀도함수

In [4]:
xx = np.linspace(-8, 8, 100)
pdf = rv.pdf(xx)
plt.plot(xx, pdf)
plt.title("확률밀도함수 ")
plt.xlabel("$x$")
plt.ylabel("$p(x)$")
plt.show()

누적분포함수

In [5]:
xx = np.linspace(-8, 8, 100)
cdf = rv.cdf(xx)
plt.plot(xx, cdf)
plt.title("누적분포함수 ")
plt.xlabel("$x$")
plt.ylabel("$F(x)$")
plt.show()

무작위 표본 생성

무작위로 표본을 만들때는 rvs(random value sampling) 메서드를 사용한다. 이 메서드에서 받는 인수는 다음과 같다.

인수 의미
size 표본 생성시 생성될 표본의 크기
random_state 표본 생성시 사용되는 시드(seed)값
In [6]:
rv.rvs(size=(3, 5), random_state=0)
Out:
array([[ 4.52810469,  1.80031442,  2.95747597,  5.4817864 ,  4.73511598],
       [-0.95455576,  2.90017684,  0.69728558,  0.7935623 ,  1.821197  ],
       [ 1.28808714,  3.90854701,  2.52207545,  1.24335003,  1.88772647]])
In [7]:
sns.distplot(rv.rvs(size=10000, random_state=0))
plt.title("랜덤 표본 생성 결과")
plt.xlabel("표본값")
plt.ylabel("count")
plt.xlim(-8, 8)
plt.show()

연습 문제 8.1.10

rvs 명령으로 N개의 정규 분포의 표본 데이터를 생성하고 이 표본 데이터로부터 표본평균과 비편향 표본분산을 계산하라. 이 값이 인수로 넣은 기댓값과 분산과 비슷한지 비교하라.

  1. $N$=10인 경우
  2. $N$=10000인 경우

새로운 확률변수의 시뮬레이션

시뮬레이션 기능을 사용하면 확률변수의 표본을 가공하여 만들어진 새로운 확률변수의 확률분포도 알 수 있다. 예를 들어 0과 1사이의 균일 분포를 가지는 확률변수에서 두 개의 값을 선택하여 이 두 값을 합한다면 결과는 어떤 분포를 가질까? 얼핏 생각하듯이 균일 분포와 균일 분포의 표본의 합은 균일 분포가 되지 않는다. 시뮬레이션으로 확인하면 1에서 최빈값을 가지는 삼각형 모양의 분포가 된다는 것을 알 수 있다.

In [8]:
rv1 = sp.stats.uniform()
rv2 = sp.stats.uniform()

np.random.seed(0)
N = 50000
x_1 = rv1.rvs(N)
x_2 = rv2.rvs(N)
x_3 = x_1 + x_2

plt.figure(figsize=(12, 5))

plt.subplot(131)
sns.distplot(x_1, kde=False)
plt.title("균일 분포")
plt.xlabel("표본값")
plt.xlim(-0.2, 2.2)

plt.subplot(132)
sns.distplot(x_2, kde=False)
plt.title("균일 분포")
plt.xlabel("표본값")
plt.xlim(-0.2, 2.2)

plt.subplot(133)
sns.distplot(x_3, kde=False)
plt.title("균일 분포 표본의 합의 분포")
plt.xlabel("표본값")
plt.xlim(-0.2, 2.2)

plt.show()

연습 문제 8.1.11

균일분포 확률변수 10개의 표본의 합은 어떤 확률분포 모양을 가지는지 시뮬레이션으로 구하라.

질문/덧글

scipy import 오류 ehan*** 2018년 12월 11일 1:38 오후

import scipy as sc
로 하면 stats 모듈을 불러올 수 없다고 오류가 나네요..

3.5 버전의 문제인지요?

import scipy.stats as sps 로 일단 해결은 했습니다..

답변: scipy import 오류 관리자 2018년 12월 12일 7:19 오후

수정하였습니다. 지적 감사합니다.