통계학 필수문제 이해해보기 😵💫
문제1. 변동계수 구하기
- 출제의도
- 평균과 표준편차를 구하는 함수를 사용할 수 있습니다.
- 모집단과 샘플의 차이를 구분합니다.
- Numpy 혹은 Pandas를 이용한 변동계수를 계산해봅니다.
- 문제
- 회사 주식에 투자하고자 합니다. 하지만 보수적인 나는 변동성이 크지 않은 회사를 골라 안정적인 투자를 희망합니다. 이를 위해 2가지 회사로 좁혔고 A,B회사의 6일간 주가 데이터를 수집하였습니다. Numpy 혹은 Pandas를 이용하여 회사의 변동계수를 구해봅시다.
- 변수명
- cv_a_np : a 회사의 변동계수
- cv_b_np : b 회사의 변동계수
📍 변동계수
➡️ 표준 편차를 표본 평균이나 모 평균 등 산술 평균으로 나눈 값으로 측정 단위가 다른 자료를 비교할 때 쓰임
➡️ CV = 표준편차 / 평균
import numpy as np
import pandas as pd
com_a = [76300, 77400, 77900, 77200, 76900, 78800]
com_b = [6400, 7000, 7400, 6900, 7300, 7600]
1) Numpy를 이용한 방법
mean_a_np = np.mean(com_a) # A 회사의 평균
std_a_np = np.std(com_a, ddof=1) # A 회사의 표준편차 # ddof=1: 샘플 표준편차를 계산하는 옵션
cv_a_np = std_a_np / mean_a_np # A 회사의 변동계수
mean_b_np = np.mean(com_b) # B 회사의 평균
std_b_np = np.std(com_b, ddof=1) # B 회사의 표준편차
cv_b_np = std_b_np / mean_b_np # B 회사의 변동계수
print(f'A회사의 변동계수 {cv_a_np:.3f}')
print(f'B회사의 변동계수 {cv_b_np:.3f}')
2) Pandas를 이용한 방법
data = pd.DataFrame({'Company A': com_a, 'Company B': com_b})
mean_a_pd = data['Company A'].mean() # A 회사의 평균
std_a_pd = data['Company A'].std() # A 회사의 표준편차
cv_a_pd = std_a_pd / mean_a_pd # A 회사의 변동계수
mean_b_pd = data['Company B'].mean() # B 회사의 평균
std_b_pd = data['Company B'].std() # B 회사의 표준편차
cv_b_pd = std_b_pd / mean_b_pd # B 회사의 변동계수
print(f'A회사의 변동계수 {cv_a_pd:.3f}')
print(f'B회사의 변동계수 {cv_b_pd:.3f}')
문제2. 신뢰구간 구하기
- 출제의도
- scipy 의 함수를 이용해서 신뢰구간을 구합니다.
- 문제
- 평균이 μ 이고 표준편차가 σ = 8 인 정규분포를 따르는 모집단에서 크기가 25인 표본을 추출하여 평균을 계산하였더니 x̄ 가 42.7 이다. 이때 μ에 대한 95% 신뢰 구간을 구하라.
📍 신뢰구간
➡️ 모수가 어느 범위 안에 있는지를 확률적으로 보여주는 방법
➡️ 대부분 95% 혹은 99%의 신뢰구간을 가짐
import scipy.stats as stats
import numpy as np
# 주어진 값들
sigma = 8 # 모집단의 표준편차
n = 25 # 표본 크기
x_bar = 42.7 # 표본 평균
confidence_level = 0.95 # 신뢰 수준
1) 직접 계산하는 방법
se = sigma /np.sqrt(n) # se: 표준오차, sqrt: 제곱근
lower_bound = x_bar - 1.96 * se # 1.96: 신뢰수준에 따른 z값
upper_bound = x_bar + 1.96 * se
print(f"95% 신뢰 구간: ({lower_bound:.2f}, {upper_bound:.2f})")
2) scipy를 이용하는 방법
stats.norm.interval(0.95, loc= 42.7, scale= sigma/np.sqrt(n))
문제3. 이표본 t 검정
- 출제의도
- 귀무가설과 대립가설을 설정할 수 있다.
- t검정에 이해하고 올바르게 해석할 수 있다.
- t검정에 적절한 전달인자를 넣을 수 있다.
- 문제
- 목초에 따른 우유의 생산량을 알아보기위하여 25마리 젖소를 대상으로 3주동안 임의로 추출된 12마리 젖소에게 건조시킨 목초를 주고 13마리 젖소에게는 들판에서 말린 목초를 주었다.
- 두 종류의 모 표준편차는 같다고 가정하고 또한 우유생산량의 자료는 정규분포를 따른다고 가정한다.
- 자연적으로 말린 목초의 사육하는 젖소의 우유생산량이 인공적으로 말린 목초로 사용하는 젖소보다 많다고 할 수 있는지 유의수준 0.05 에서 검정하세요.(단측 검정)
📍 t 검정
➡️ 두 집단 간의 평균 차이가 통계적으로 유의미한지 확인하는 검정 방법
📍 t 검정의 종류 | 일표본 t검정 | 독립표본(이표본) t검정 | 대응표본 t검정 |
비교 대상 | 한 표본의 평균과 특정 값 | 두 독립 그룹 간 평균 비교 | 같은 집단의 두 조건 간 평균 비교 |
데이터 구조 | 단일 표본 | 두 독립 그룹 | 같은 집단에서 반복 측정 또는 쌍으로 구성 |
예시 | 학생들의 평균 점수 vs 기준 점수 | 남성 vs 여성 키 비교 | 치료 전후 혈압 비교 |
1) 데이터 정의
import numpy as np
from scipy.stats import ttest_ind
nature = [44, 44, 56, 46, 47, 38, 58, 53, 49, 35, 46, 30, 31] # 자연적으로 말린 목초
artificial = [35, 47, 55, 29, 40, 39, 32, 41, 42, 57, 51, 39] # 인공적으로 말린 목초
2) 독립 이표본 t-검정 수행
t_stat, p_value_two_tailed = ttest_ind(nature, artificial, equal_var=True) # 등분산 가정
- ttest_ind: 독립 이표본 t-검정을 수행하는 함수
- equal_var = True: 등분산 가정
→ 결과
- t_stat: t-통계량. 두 그룹 평균의 차이를 나타내는 값으로 양수이면 nature, 음수이면 artificial의 평균이 더 큼을 의미
- p_value_two_tailed: 양측 검정의 p-value 반환
💡 nature과 artificial의 입력 순서는 중요할까?
→ 양측검정인 경우: 입력 데이터 순서가 t-통계량의 부호에만 영향을 미치며, p-value는 동일
→ 단측검정인 경우: t-통계량의 부호를 사용하여 대립가설의 방향성을 판단하기 때문에 입력 순서가 매우 중요 (t_stat > 0인 경우 대립가설을 지지한다고 봄)
😵💫 복잡하니까, 항상 대립가설의 방향에 맞는 데이터를 먼저 입력한다고 기억하자‼️
3) 단측 검정으로 변환
# 단측 검정을 위해 p-value를 2로 나눔
p_value_one_tailed = p_value_two_tailed / 2
- 단측 검정에서는 대립가설의 방향을 설정한 뒤, p-value를 양측 검정 결과의 절반으로 계산
- 양측 검정은 평균 차이가 양쪽 어느 방향으로든 유의미한지를 검정하지만, 단측 검정은 한 방향으로만 검정하므로 p-value를 절반으로 줄여야 함
4) 결과 출력
# 결과 출력
print("H0: 귀무가설은 '목초의 건조 방법은 우유생산량과 관계가 없다' 이다.")
print("H1: 대립가설은 '자연적으로 말린 목초로 사육하는 젖소의 우유생산량이 더 많다' 이다.")
print(f"t-통계량: {t_stat:.4f}")
print(f"단측 검정 p-value: {p_value_one_tailed:.4f}")
5) 유의수준 설정 및 귀무가설 기각 여부 판단
# 유의수준 설정
alpha = 0.05
# 귀무가설 기각 여부 판단
if p_value_one_tailed < alpha and t_stat > 0:
print("귀무가설을 기각합니다.")
else:
print("귀무가설을 기각하지 않습니다.")
- 단측 검정의 경우 p-value가 유의수준보다 작고 t-통계량이 양수이면 대립가설 채택 (귀무가설 기각)
- 양측 검정의 경우 p-value가 유의수준보다 작으면 대립가설 채택 (귀무가설 기각)
- p-value: 0.2754
- t-통계량: 0.6056
→ t-통계량은 양수이지만, 단측검정 p-value 0.2754가 유의수준 0.05보다 크므로 귀무가설은 기각되지 않음
문제4. 카이제곱 검정
- 출제의도
- 귀무가설과 대립가설을 설정할 수 있다.
- 카이제곱 검정을 이해하고 올바르게 해석할 수 있다.
- 카이제곱 검정 함수에 적절한 전달인자를 넣을 수 있다.
- 문제
- 다음 click_rate 데이터는 헤드라인별 클릭과 클릭하지 않은 수 에 대한 데이터입니다.
- 귀무가설과 대립가설을 설정하세요.
- 카이제곱 검정 수행하여 실제로 클릭률에 대한 차이가 있는지 유의수준 0.05 에서 검정해보세요.
📍 카이제곱 검정
➡️ 범주형 데이터의 표본 분포가 모집단 분포와 일치하는지 검정(적합도 검정)하거나 두 범주형 변수 간의 독립성을 검정
📍 적합도 검정
➡️ 관찰된 분포와 기대된 분포가 일치하는지 검정
➡️ p-value가 높으면 관찰된 데이터와 귀무 가설이 적합 ↔ 낮으면 관찰된 데이터와 귀무 가설이 부적합
1) 데이터 로드 및 준비
import pandas as pd
from scipy import stats
# URL 로 데이터 가져오기
url = "https://raw.githubusercontent.com/gedeck/practical-statistics-for-data-scientists/master/data/click_rates.csv"
click_rate = pd.read_csv(url)
2) 데이터 변환
# 데이터를 피벗 테이블로 변환
clicks = click_rate.pivot(index='Click', columns='Headline', values='Rate')
display(clicks)
3) 카이제곱 독립성 검정
chisq, pvalue, df, expected = stats.chi2_contingency(clicks)
- stats.chi2_contingency:
- 입력된 교차표(clicks)에 대해 카이제곱 검정 수행
- 목적: 클릭 여부(Click)와 헤드라인(Headline) 간의 독립성 검정
→ 결과
- chisq: 카이제곱 통계량
- pvalue: 검정의 p-value (귀무가설 기각 여부 판단에 사용됨)
- df: 자유도 = (행의 개수−1)×(열의 개수−1)
- expected: 기대 빈도 (각 셀이 독립적일 때 예상되는 값)
4) 결과 출력
print(f'chisq:{chisq:.3f}\npvalue:{pvalue:.3f}')
5) 유의수준 설정 및 귀무가설 기각 여부 판단
# 유의수준 설정
alpha = 0.05
# 귀무가설 기각 여부 판단
if pvalue < alpha:
print("귀무가설 기각: 헤드라인과 페이지 클릭율에는 관련이 있다.")
else:
print("귀무가설 채택: 헤드라인과 페이지 클릭율에는 관련이 없다.")
- 카이제곱 검정의 경우 p-value가 유의수준보다 작으면 대립가설 채택 (귀무가설 기각)
- p-value: 0.435
→ p-value 0.435가 유의수준 0.05보다 크므로 귀무가설은 기각되지 않음 (귀무가설 채택)