수업외 정리

24-01-11 통계실습 통계검정

glenlee 2024. 1. 11. 17:45

# 통계검정
- 교재 p294

 

## 문제 상황
- 편의점 감자튀김 (무게 130g으로 알려져 있음)
- 학생이 무게 하나 잼. 122.02g 밖에 되지 않음
- 2주간 매일 감자튀김을 사서 무게를 측정
  + 14개의 표본의 평균 계산했는데, 128.451g ==> 학생이 편의점주에게 항의
  + 편의점주 왈 : 그저 우연이다!
- 14개 표본의 평균이 128.451g으로 나온 건 정말 우연인가?

 

### 질문
- 어떤 통계 검정 방법을 사용해야 할까요?
  + t-test, One Sample T-Test
  + 표본 14개 ==> 정규성 검정 진행 후, 정규성 검정 통과 할 때, One Sample T-Test 

t test=

http://www.ktword.co.kr/test/view/view.php?nav=2&no=2425&sh=t-test

 


- 귀무가설과 대립가설을 설정해보세요?
  + 귀무가설 : 모평균 (130g)과 표본평균 (128.451)과 같다
  + 대립가설 : 모평균 (130g)과 표본평균 (128.451)과 같지 않다. (양측검정)
  + 대립가설 : 모평균 (130g)> 표본평균 (128.451)보다 크다. (단측검정)
- 교재 p302 단측검정과 양측검정 설명

 

 

불러온 라이브러리

import numpy as np 
import pandas as pd 
from scipy import stats

import scipy  #scipy.__version__ 버전 확인

불러온 데이터와 넘파이 어레이 표시

df = pd.read_csv('data/ch11_potato.csv')
sample = np.array(df['무게'])
sample

array([122.02, 131.73, 130.6 , 131.82, 132.05, 126.12, 124.43, 132.89,
       122.79, 129.95, 126.14, 134.45, 127.64, 125.68])

 

# 표본평균 = 넘파이.평균(샘플)
s_mean = np.mean(sample)
s_mean

 

 

### A 학생의 관심
- (14개의) 표본평균이 모평균130g보다 적은지 여부
- 여기서는 감자튀김의 표본집단이 정규분포를 따르고 있고 ==> 정규성 검정을 할 필요가 없다
    + 비모수 검정을 쓸 필요가 없다!!!
    + 모수 검정을 하면 된다!!
- 모분산이 9임을 알고 있다고 전제한다. 

 

rv = stats.norm(130,                       # 모평균  norm

                np.sqrt(9/14))                 # 9 모분산, 14 표본의 갯수
rv.isf(0.95)                                      # 0.95 신뢰구간 95%

128.681

 

앞으로 나올 표본의 무게값이 128.681 위로 나와야 문제가 없는 제품인것

stats = Statistics

norm = normal distribution 정규분포

sqrt = square root 제곱근

isf = inverse survival function 역함수

rv = random variable 랜덤 변수

 

### 검정통계량

 

모평균

z = (s_mean - 130) / np.sqrt(9/14)
z

1.932

Z-score는 정규 분포에서 어떤 값이 평균에서 얼마나 떨어져 있는지를 표준 편차 단위로 나타낸 값

 

# 검정 통계량에 관한 임곗값을 구하기
rv = stats.norm()
rv.isf(0.95)

-1.645

 

 

 

rv.cdf(z)

# 유의수준 0.05보다 작음


# 귀무가설 : 모평균 130g 표본평균 128.451g과 같다
# 대립가설 : 모평균 130g 표본평균 128.451g과 다르다.

# 대립가설 채택을 한다는 말은 통계에서는 존재하지 않음
# 귀무가설 채택 or 귀무가설 기각(=대립가설 채택)

0.027

 

 

 

# 양측검정
z = (s_mean - 130) / np.sqrt(9/14) 
rv = stats.norm()
rv.interval(0.95) # 신뢰구간 95%

(-1.960, 1.960)

 

 

 

rv.cdf(z) * 2

0.053

z-score z 의 누적 분포 함수 Cumulative Distribution Function 값을 사용하여 양측검정에서  P-value 값을 계산하는 코드

 

  • 단측검정, 양측검정을 어떤 상황에서 구분해서 사용하나요?
    • 양측검정 A와 B가 Not Same
      • 해석 : 우리가 모두 아는 평균 가지고 비교 가능
    • 단측검정 A > B, B > A

 

가설검정의 두 가지 오류

  • 제 1종 오류 : 귀무가설이 옳을 때 귀무가설을 기각하는 오류
  • 제 2종 오류 : 대립가설이 옳을 때 귀무가설을 채택하는 오류

 

제 1종 오류

  • 실제로 평균이 130g인데도 불구하고 평균은 130g보다 작다라고 결론을 내리는 상황
    • False Positive (오탐)

rv = stats.norm(130, 3)                                           통계내기.정규분포
c = stats.norm().isf(0.95)                                        통계내기.정규분포.역함수
n_samples = 10000                                                샘플수 10000
cnt = 0                                                                     CouNT 카운트    
for _ in range(n_samples):                                      10000 번 반복한다
    sample_ = np.round(rv.rvs(14), 2)                      rv에서 14인 표본을 추출, 소수점 둘째자리까지 반올림 sample 로 저장
    s_mean_ = np.mean(sample_)                           위 sample을 평균내고 s_mean 으로 저장
    z = (s_mean_ - 130) / np.sqrt(9/14)                    z 는 평균 / 9/14
    if z < c:                                                                 z값이 95 신뢰구간 보다 낮다면
        cnt += 1                                                           카운트에 1 증가한다
cnt / n_samples                                                      샘플값을 인쇄

0.051

 

코드 해설 gpt

  1. 평균이 130이고 표준 편차가 3인 정규 분포를 나타내는 랜덤 변수 객체 rv를 생성합니다.
  2. 95% 신뢰 구간에서의 Z-score를 계산하고 이를 c에 할당합니다.
  3. 14개의 표본을 가진 표본집단을 생성하고, 이 표본집단의 평균을 계산하여 z를 구합니다.
  4. 만약 z 값이 95% 신뢰 구간의 경계값 c보다 작다면, cnt를 1 증가시킵니다.
  5. 이 작업을 10,000번 반복하고, 95% 신뢰 구간에 속하는 표본들의 비율을 계산합니다.

주어진 코드의 주요 목적은 표본 평균의 Z-score가 95% 신뢰 구간에 속하는 표본의 비율을 계산하는 것으로 보입니다. 이는 일종의 가설 검정 과정을 시뮬레이션하는 것으로 볼 수 있습니다. cnt / n_samples는 표본의 평균이 95% 신뢰 구간에 속하는 비율을 나타냅니다.

 

- 1종 오류를 범할 비율은 0.053 / 약 5%의 비율로 130g보다 작다라고 잘못 탐지하는 것과 같다.
- 1종 오류를 범할 확률을 위험률
- 좀 더 엄격하게 적용하고 싶다고 하면 유의수준 1%에서 가설검정을 수행

 

제 2종 오류

  • 실제로 표본평균이 130g보다 작음에도 불구하고 표본평균은 130g보다 작다라는 결론을 얻을 수 없는 상황
    • 본래 검출해야 하는 것을 검출하지 못했으므로 미탐 false negative
rv = stats.norm(128, 3) # A 학생이 편의점에서 비밀문서, 실제로는 감자튀김의 평균이 128g

c = stats.norm().isf(0.95)

n_samples = 10000
 
cnt = 0
for _ in range(n_samples):
    sample_ = np.round(rv.rvs(14), 2)
    s_mean_ = np.mean(sample_)
    z = (s_mean_ - 130) / np.sqrt(9/14)
    if z >= c:
        cnt += 1
       
cnt / n_samples 
0.198
  • 0.198의 의미는 검정력 / 제대로 탐지하지 못할 확률이 20% 되더라!!
  • 제 2종 오류는 언제나 모집단의 정보에 의존한다.
    • 중요한 포인트는 분석가는 모집단의 구체적인 정보를 알 방법이 없다
rv = stats.norm(127, 3)
c = stats.norm().isf(0.95)
n_samples = 10000
cnt = 0
for _ in range(n_samples):
    sample_ = np.round(rv.rvs(14), 2)
    s_mean_ = np.mean(sample_)
    z = (s_mean_ - 130) / np.sqrt(9/14)
    if z >= c:
        cnt += 1
       
cnt / n_samples
0.018

 

### 모분산을 안다!!
- 현실적으로 모집단을 아는 것은 불가능
    + 건강보험과 통계 / 전국민 데이터가 있는 자료 (국가)
- 모분산을 알고 있다는 뜻은 모집단을 알고 있다 ==> 모평균도 구할 수 있음 ==> 모평균에 대한 검정을 우리가 굳이 할 필요가 있나?
def pmean_test(sample, mean0, alpha=0.05):
 
    s_mean = np.mean(sample)
    u_var = np.var(sample, ddof=1)
    n = len(sample)
    rv = stats.t(df=n-1)
    interval = rv.interval(1-alpha)

    t = (s_mean - mean0) / np.sqrt(u_var/n)
    print(f't통계량 값: {t:.3f}')
    if interval[0] <= t <= interval[1]:
        print('귀무가설을 채택')
    else:
        print('귀무가설을 기각')

    if t < 0:
        p = rv.cdf(t) * 2
    else:
        p = (1 - rv.cdf(t)) * 2
    print(f'p값은 {p:.3f}')
 
pmean_test(sample, 130)
t통계량 값: -1.455
귀무가설을 채택
p값은 0.169
    sample : 표본 샘플 데이터
    mean0 : 모평균을 제안 (감자칩의 무게와 같이 이미 기 제안이 된 것)
    alpha : 신뢰구간 95% 수준의 신뢰구간
 
t, p = stats.ttest_1samp(sample, 130)
t, p
(-1.455, 0.169)
 
 

keyboard_arrow_down

 

 

z 통계량 / t 통계량

  • 모집단을 알고, 모평균을 알고, 모분산을 다 알고 있다.
    • z-검정 : z-통계량
  • 표본을 추출한다. 표본 평균을 알고, 표분 분산을 알고 있다.
    • t-검정 : t-통계량

'수업외 정리' 카테고리의 다른 글

소스트리 사용과 깃허브 연동 1.작업위치지정과 파일 지정  (0) 2024.01.20
24-01-11 가설검정  (0) 2024.01.12
24-01-10 통계  (0) 2024.01.11
240108복습 시각화  (0) 2024.01.09
240108복습 데이터 불러오기  (1) 2024.01.09