#pmf 이용 : 0 ~ 59까지 나올 확률을 모두 더한 후 1에서 확률 빼기
#cdf 이용 : 0번부터 나올 확률의 누적 확률
p = sp.stats.binom.cdf(n=100, p=0.5, k=59)
print(1-p)
#sf 이용 : 생존 함수는 1-cdf의 값을 가지는 함수
p = sp.stats.binom.sf(n=100, p=0.5, k=59)
print(p)
0.02844396682049044 0.028443966820490392
# 앞면이 20~60번 나올 확률
#cdf 이용 : 0번부터 나올 확률의 누적 확률
p1 = sp.stats.binom.cdf(n=100, p=0.5, k=19)
p2 = sp.stats.binom.cdf(n=100, p=0.5, k=60)
print(p2 - p1)
현재 메일이 온 경우 메일에 포함된 내용들을 원핫 인코딩 해서 기존에 만들어진 단어들의 스팸 비율 확인해서 판정
감성분석, 욕설 방지 등에 사용 utf8mb4 : 글자 + 이모티콘까지
4-3) 카테고리 분포
- 이항 분포가 성공인지 실패인지를 구별하는 거라면
카테고리 분포는 2개 이상의 경우 중 하나가 나오는 경우
대표적인 경우가 주사위 (k=6)
- 스칼라 값으로 표현하는 경우가 많지만 확률 변수에서는 카테고리를 원핫인코딩해서 표현
각 열로부터 각 베르누이 확률 분포의 모수 추정값
순서가 명확한 의미를 가지면 라벨인코딩, 순서가 의미없이 독립적이면 원핫인코딩
원핫인코딩을 하는 이유: 서로 독립적인 데이터들의 거리를 동일하게 맞추기 위해! 그렇지 않으면 편향이 될 가능성이 높다.
- scipy에서는 카테고리 분포 클래스 제공 X
다항분포를 위한 multinomial 클래스에서 시행횟수를 1로 설정하면 카테고리 분포가 됨
- 베르누이 분포가 이진 분류 문제에 사용된 것처럼 카테고리 분포는 다중 분류 클래스에 이용
모수는 원래 카테고리 개수와 카테고리별 확률이 되어야 하는데 scipy를 이용할 때는 1과 각 카테고리 확률의 vector가 됨
시뮬레이션에 사용되는 데이터는 원핫인코딩 된 데이터
원핫 인코딩은 pandas의 get_dummies()를 이용하거나 sklearn.preprocessing 패키지의 Encoder 클래스를 이용해서 수행 가능
#카테고리 별 확률
mu = [0.1, 0.1, 0.1, 0.1, 0.1, 0.5]
#카테고리 분포 인스턴스
rv = sp.stats.multinomial(1, mu)
#데이터 생성
xx = np.arange(1, 7)
#원핫 인코딩
xx_ohe = pd.get_dummies(xx)
result = sp.stats.uniform.ppf(scale=60, q=0.73)
result
43.8
4-6) 정규분포
- 가우시안 정규분포 (Gaussian normal distribution) 또는 정규 분포
- 자연 현상에서 나타나는 숫자를 확률 모형으로 나타낼 때 가장 많이 사용되는 모형
- 데이터가 평균을 기준으로 좌우 대칭
- 평균을 기준으로 표준 편차 좌우 1배 내에 약 68% 그리고 좌우 2배 안에 약 95% 정도의 데이터가 분포된 경우
- 평균이 0이고 표준편차가 1인 경우를 특별히 표준 정규 분포라고 함
- scipy.stats.norm
mu = 0
std = 1
#평균이 0이고 표준편차가 1인 정규분포 객체 생성
rv = sp.stats.norm(mu, std)
#시각화 할 구간 설정
xx = np.linspace(-10, 10, 200)
plt.plot(xx, rv.pdf(xx))
plt.ylabel('확률')
plt.title('정규 분포 곡선')
-2 ~ 2 사이가 표준편차의 약 4배
# 붓꽃 데이터에서 꽃잎 길이에 대한 히스토그램 - 정규분포와 유사한 모양
from sklearn.datasets import load_iris
setosa_sepal_length = load_iris().data[:50, 2]
주가의 수익률이 정규 분포라면 주가 자체는 로그 정규 분포(log-normal distribution)
로그 정규 분포를 가지는 데이터는 기본적으로 항상 양수라서 로그 변환을 수행한 다음 사용하는 것이 일반적
머신러닝이나 딥러닝에 사용하는 경우 로그 변환 후 사용하기도 함
np.random.seed(0)
mu = 1
rv = sp.stats.norm(loc=mu)
x1 = rv.rvs(1000)
#정규 분포 데이터를 이용한 로그 정규 분포 데이터 생성
#시작하는 부분에 데이터가 치우침
#타겟 데이터가 한쪽으로 몰려있는 경우 로그 변환 고려
s = 0.5
x2 = np.exp(s * x1)
fig, ax = plt.subplots(1, 2)
sns.histplot(x1, kde=False, ax=ax[0])
ax[0].set_title("정규분포")
sns.histplot(x2, kde=False, ax=ax[1])
ax[1].set_title("로그정규분포")
plt.tight_layout()
plt.show()
- Q-Q (Quntile-Quantile) Plot
정규분포는 연속확률분포 중 가장 널리 사용되는 확률분포 => 정규분포인지 확인하는 것이 중요
분석할 표본 데이터의 분포와 정규 분포의 분포 형태를 비교해서, 표본 데이터가 정규 분포를 따르는지 검사하는 간단한 시각적 도구
정규 분포를 따르는 데이터를 Q-Q plot으로 그리면 대각선 방향의 직선 모양으로 만들어짐
scipy.stats.probplot(x, plot=plt)
#평균이 0이고 표준편차가 1인 정규 분포 객체로 데이터 샘플링
rv = sp.stats.norm(0, 1)
x = rv.rvs(20)
#랜덤하게 데이터 추출
# x = np.random.rand(100)
sp.stats.probplot(x, plot=plt)
plt.show()
정규분포
랜덤추출
- 중심 극한 정리
모집단이 정규 분포가 아니더라도 표본 크기가 충분하고 데이터가 정규성을 크게 이탈하지 않는다면 여러 표본에서 추출한 평균은 종 모양의 정규 곡선을 따른다.
N 개의 임의의 분포로부터 얻은 표본의 평균은N 이 증가할수록 기댓값이μ , 분산이σ2/N 인 정규 분포로 수렴
#여러개의 표본에서 추출한 데이터를 합치면 정규 분포와 유사해짐
xx = np.linspace(-2, 2, 100)
for i, N in enumerate([1, 2, 10]):
X = np.random.rand(5000, N)
Xbar = (X.mean(axis=1) - 0.5) * np.sqrt(12 * N)
sp.stats.probplot(Xbar, plot=plt)
enumerate 함수: iterable 객체를 받아서 순회하고 (인덱스, 데이터)로 리턴 - 몇번째 데이터인지 알 수 있음
enumerate([1, 2, 10])
enumerate([1, 2, 5, 10, 20])
점점 가까워진다.
중심극한정리
4-7) 스튜던트 T분포
- 현실의 데이터는 정규 분포와 거의 유사하지만, 양 끝단의 데이터가 정규 분포에 비해 극단적 현상이 더 자주 발생
- 분포의 모양을 볼 때 양 끝이 정규 분포보다 두껍기 때문에 fat tail 현상이라 한다.
금융 시장에서는 black swan이라 한다.
#S&P 500, 나스닥(Nasdaq), 다우존스(Dow-Jones), 니케이255(Nikkei255)
symbols=[
'S&P500',
'IXIC',
'DJI',
'N225',
'KS11'
]
#주가 가져오기
data = pd.DataFrame()
for sym in symbols:
data[sym] = fdr.DataReader(sym, '2011-01-01')["Close"]
data = data.dropna()
data
scailing - 값을 줄이는 것 표준화(standardiztion) - 열의 값을 어떤 특정 범위(0~1, -1~1)로 변경하는 것 정규화(normalization) - 행의 값을 어떤 특정 범위로 변경하는 것 -1로 맞추는 직업
원핫인코딩이 정규화
data = np.array([23, 30,18, 33, 28, 33, 34, 38, 29, 31])
#자유도
df = len(data)-1
#평균
d_mean = data.mean()
#표준 편차
d_std = data.std(ddof=1) #모집단의 표준편차가 아니라 샘플 데이터의 표준편차이므로 평균을 가정해야 함 - 1 설정
#섬씨 25도일 때 상위 몇 %에 속하는 온도일까?
score = 25
p = sp.stats.t.cdf(x=score,loc=d_mean,scale=d_std,df=df)
print(f"{score}는 상위 {(1-p)*100:.2f}%로 예측한다.")
p2 = sp.stats.t.sf(x=score,loc=d_mean,scale=d_std,df=df)
print(f"{score}는 상위 {p2*100:.2f}%로 예측한다.")
25는 상위 78.31%로 예측한다. 25는 상위 78.31%로 예측한다.
4-8) 카이 제곱 분포
- 정규 분포를 따르는 확률 변수 X의 N개 개의 표본 x1,⋯,xN 의 합(또는 평균)은 표본 분산으로 정규화하면 스튜던트 t분포를 따른다. N개의 표본을 제곱해서 더하면 양수만을 갖는 분포 생성 - 카이제곱분포
- scipy.stats.chi2
- 제곱 합을 구하는 표본의 수가 2보다 커지면 0 근처의 값이 가장 많이 발생할 것 같지만, 실제로는 0보다 큰 어떤 수가 흔하게 발생
4-9) F 분포
- 카이 제곱 분포를 따르는 독립적인 두개의 확률변수의 확률 변수 표본을 각각 x1, x2라고 할 때 이를 각각 자유도 N1, N2로 나눈 뒤 비율을 구하면 F분포
- t 분포의 표본 값을 제곱한 값이 F 분포
N1과 N2의 값이 같을 경우: 1 근처 값이 가장 많이 발생할 것 같지만 실제는 1이 아닌 다른 수가 조금 더 흔하게 발생
N1과 N2의 값이 커지면: 1 근처의 값이 많이 발생
- scipy.stats.f
------------------------------------------------------------------------------------------------여기까지 정규분포 통계량 분포
스튜던트 t 분포: 추정된 가중치에 대한 확률분포
카이제곱 분포: 오차 제곱 합에 대한 확률분포
F분포: 비교 대상이 되는 선형 모형의 오차 제곱 합에 대한 비율의 확률 분포
4-10) 푸아송 분포
- 단위 시간 안에 어떤 사건이 몇번 일어날 것인지를 표현하는 이산확률분포
- 푸아송이 민사사건과 형사사건 재판에서 확률에 관한 연구 및 일반적인 확률계산 법칙에 대한 서문에서 최초로 사용
-scipy.stats.poisson.rvs()
μ: 모양 매개 변수로 사용
방정식의 λ(람다):단위 시간당 발생하는 사건의 개수 설정
loc: 분포 이동
zmrl: 분포에서 임의의 변량 수 결정
random_state 인수 포함: 재현성 유지
- 예시
어떤 식당에 주말 오후 동안 시간당 평균 20명의 손님이 방문한다고 할 때, 다음주 주말 오후에 30분 동안 5명의 손님이 방문할 확률은?
# 2022년 기준으로 한 시간 평균 신생아 수는 682 명인 경우에 한 시간에 650명 이하의 신생아를 낳을 확률은?
# p = sp.stats.poisson.cdf(mu=682, k=650)
x=range(500,800)
y = sp.stats.poisson.pmf(mu=682,k=x)
plt.plot(x,y,alpha=0.7,label='pmf')
x2 = range(500,630)
y2 = sp.stats.poisson.pmf(mu=682,k=x2)
plt.fill_between(x2,y2,color='r',label='x<630') #630명 미만일 때 확률(면적)
#630명 미만
x3 = range(630,651)
y3 = sp.stats.poisson.pmf(mu=682,k=x3)
plt.fill_between(x3,y3,color='c',label='630<x<=651') #630명 이상 650명 이하일 때 확률(면적)
plt.xticks([500,630,650,682,800])
plt.title("")
plt.show()
# 0.11328673711427531
#시간당 500M 정도의 트래픽을 소모하는데 99% 정도를 처리하고자 할 때 필요한 트래픽은?
#help(sp.stats.poisson.ppf)
p = sp.stats.poisson.ppf(mu=500, q=0.99)
print(p)
630.0
4-11) 지수분포
- 푸아송 분포: 사건이 독립적일 때 일정 시간 동안 발생하는 사건의 횟수
- 지수 분포: 다음 사건이 일어날 때까지 대기 시간
- scipy.stats.expon
scale: 시간 설정
loc: 사건의 발생 횟수
사건의 대기 시간이 일정한 형태로 줄어들거나 늘어나는 경우 weibull distribution 이용
# 스마트폰의 배터리 수명은 평균 24시간인 경우, 20시간 이내에 소진할 확률은?
# sp.stats.expon.pdf(scale=24,x=x)
x = range(0,100)
y = sp.stats.expon.pdf(scale=24,x=x)
for i in x:
print(f'{i:02d}시간 {y[i]:.2f}', end=' ')
if i%10==9:
print()
# 시각화
plt.plot(x,y)
plt.xlabel("time")
plt.ylabel("probability")