[빅분기 실기] 작업형 3유형: groom 체험 문제 풀이
이전 내용
[빅분기 실기] 작업형 1유형 판다스 중요 문법 정리
이전 내용 [빅분기 실기] 작업형 1유형: transfrom('mean') vs mean()이전 내용 [빅분기 실기] 실기 체험환경 (groom)이전 내용 [빅분기 실기] 작업형 3유형 요약이전 내용 [빅분기 실기] 작업형 3유형 : 로지
puppy-foot-it.tistory.com
빅데이터분석기사
체험 3유형 문제
[전체 문제]
제공된 데이터를 활용하여 암 환자와 정상인의 리지스틴 수치에 대한 정보를 분석합니다. 두 집단의 로그 리지스틴 값에 차이가 있는지를 검정하여야 하며, 소수점 이하 반올림하여 답을 구한 후, [제출 형식]에 맞춰 제출 페이지에 입력하십시오. (단, 모델은 불편향을 포함한다.)
제공 데이터(bcc.csv)
- Resistin: 리지스틴 수치(ng/mL)
- Classification: 실험자 정보 [1: 정상, 2: 환자]
데이터 불러오기 및 데이터 확인
import pandas as pd
df = pd.read_csv("data/bcc.csv")
# 데이터 크기
# print(df.shape) # (116, 2)
# 데이터 샘플 확인
# print(df.head()) # 컬럼 Resistin Classification
문제 및 풀이
1. 두 집단의 로그 리지스틴 값의 분산에 차이가 있는지를 알아보기 위해 F-검정을 수행할 때 검정통계량의 값을 구하여라. (단, 분자의 자유도가 분모의 자유도보다 크도록 하여라.)
[제출 형식] 반올림하여 소수 셋째 자리까지 작성
[코드 및 풀이]
1) numpy를 import 하고, 로그 리지스틴 값 구하기
※ np.log() 를 사용하는 이유는, 데이터가 한 쪽으로 치우쳐있을 수 있어(왜도가 있어 log를 통해 정규 분포로 만들어) 정규성을 만족시키기 위함이다.
import numpy as np
df['log_resistin'] = np.log(df['Resistin'])
group1 = df[df['Classification'] == 1]['log_resistin']
group2 = df[df['Classification'] == 2]['log_resistin']
2) 분석할 두 그룹을 'Classification' 컬럼을 기준으로 나눈다
# 암환자와 정상인 나누기
group1 = df[df['Classification'] == 1]['log_resistin'] # 정상
group2 = df[df['Classification'] == 2]['log_resistin'] # 환자
▶ group1에는 정상인의 리지스틴 수치만, group2에는 암 환자의 리지스틴 수치만 들어 있게 된다.
3) F-검정을 통한 분산의 동질성 확인 (F-test for Equality of Variances)
F-검정은 두 집단의 분산이 서로 같은지 다른지를 비교하는 통계 방법으로, '등분산성 검정' 이라고도 한다.
# 분산 계산
var1 = group1.var() # 정상인 분산
var2 = group2.var() # 환자 분산
4) 각 집단의 자유도 계산하고, 비교하여 어떤 값이 분자에 (그리고 분모에) 갈 지 결정
# 각 집단의 자유도 계산
dof_1 = len(group1) - 1
dof_2 = len(group2) - 1
# print(dof_1, dof_2) # 51 63 # 그룹2의 자유도가 높음 -> 분자
▶ "자유도"는 통계에서 값을 자유롭게 변화시킬 수 있는 독립적인 데이터의 개수로, 분산을 계산할 때 평균값 1개를 이미 계산에 사용했기 때문에 항상 1을 빼줘야 한다.
5) F-검정 통계량 계산
F-검정 통계량은 항상 1보다 크거나 같게 만들기 위해 분산이 큰 값을 분산이 작은 값으로 나눠야 한다.
f_stat = var2/var1
print(f"{round(f_stat, 3)}") # 1.348 # F통계량이 1에 가깝다는 것은 둘의 분산이 비슷하다는 것
▶ 1.348 값은 두 그룹의 리지스틴 수치 분산이 얼마나 차이나는지를 비교하는 지표가 된다.
2. 두 집단의 로그 리지스틴 값에 대한 합동 분산 추정량을 구하여라.
[제출 형식] 반올림하여 소수 셋째 자리까지 작성
[코드 및 풀이]
6) 합동 분산 추정량 계산 (Pooled Variance Estimation)
'합동 분산(pooled variance)'이라는 건 두 집단의 분산이 비슷하다고 가정할 때, 두 집단의 분산을 하나로 합쳐서 더 정확한 분산을 추정하는 방법이다. 마치 두 그룹의 분산을 '평균'내는 것과 비슷하지만, 각 그룹의 표본 크기를 고려해서 가중치를 주는 방식이다.
먼저, 정상인과 암 환자의 표본 크기(데이터 개수)를 각 변수에 저장
# 두 집단의 로그 리지스틴 값에 대한 합동 분산 추정량
n1 = group1.count() # 또는 n1 = len(group1)
n2 = group2.count() # 또는 n2 = len(group2)
그리고 합동 분산을 계산하는데,
각 그룹의 분산에 (표본 크기 - 1)을 곱한 값을 더한 후, (전체 표본 크기 - 2)로 나눈다.
pooled_var = (((n1 - 1) * var1) + ((n2 - 1) * var2)) / (n1 + n2 - 2)
# 소수 셋째 자리까지 출력
print(f"합동분산: {round(pooled_var, 3)}") # 0.449
▶ 이 0.449 라는 값이 두 그룹의 분산을 합쳐서 추정한 '합동 분산'이며, 이 값은 다음 단계인 t-검정의 표준오차 계산에서 사용된다.
3. 2번 문제에서 구한 합동 분산 추정량을 이용하여 두 집단의 로그 리지스틴 값에 유의미한 차이가 있는지 독립표본 t-검정을 수행하고 p-값을 구하여라.
[제출 형식] 반올림하여 소수 셋째 자리까지 작성
[코드 및 풀이]
독립표본 t-검정은 두 개의 독립적인 그룹 간에 평균의 차이가 통계적으로 유의미한지 확인하는 데 사용되는 아주 흔한 방법이다. 여기서 '유의미하다'는 것은 우연히 발생했다고 보기 어렵다는 뜻이다.
4) statsmodels 라이브러리의 ttest_ind 함수를 사용하여 독립표본 t-검정 수행
from scipy import stats
t_stat, p_value = stats.ttest_ind(group1, group2, equal_var=True)
# True: 두 집단의 분산이 같다 (기본값으로 생략 가능)
print(f"{round(p_value, 3)}") # 0.003
▶ 여기서 나온 p-value는 0.003이며, 이 p-값은 우리가 설정한 유의수준(보통 0.05)보다 작을 때, 두 그룹 간에 통계적으로 유의미한 차이가 있다고 결론 내릴 수 있다.
- 만약 p-값이 0.05보다 작으면 (예: 0.003), "귀무가설(두 그룹의 평균은 차이가 없다)을 기각하고, 대립가설(두 그룹의 평균은 차이가 있다)을 채택한다"고 말한다. 즉, 정상인과 암 환자의 리지스틴 수치 평균에 통계적으로 유의미한 차이가 있다고 볼 수 있다.
- 만약 p-값이 0.05보다 크면, "귀무가설을 기각할 수 없다"고 말한다. 즉, 두 그룹의 리지스틴 수치 평균에 유의미한 차이가 있다고 보기 어렵다는 의미이다.
- 이 경우 p-값이 0.003로 0.05보다 작기 때문에, 정상인과 암 환자 그룹의 리지스틴 수치 평균에는 통계적으로 유의미한 차이가 있다고 결론 내릴 수 있다.
4. 전체 코드
# print(df.head(3))
# print(df.shape) # (116, 2)
# 두 집단의 로그 리지스틴 값 구하기
import numpy as np
df['log_resistin'] = np.log(df['Resistin'])
# print(df.head(3))
# 그룹 나누기
group1 = df[df['Classification'] == 1]['log_resistin'] # 정상
group2 = df[df['Classification'] == 2]['log_resistin'] # 환자
# print(group1.shape, group2.shape) # (52,) (64, )
# 그룹별 로그 리지스틴 분산 값 구하기
var1 = group1.var() # 0.3765
var2 = group2.var() # 0.5076
# print(var1, var2)
# 분자와 분모 결정 위한 자유도 구하기
dof1 = len(group1) - 1 # 51 -> 분모
dof2 = len(group2) - 1 # 63 -> 분자
# print(dof1, dof2)
# F통계량 구하기
fstat = var2 / var1 # 자유도 큰 분산 / 자유도 작은 분산
print(f"1. F-통계량: {round(fstat, 3)}") # 1.348
# 두 집단의 합동 분산 추정량 구하기
# 표본 크기 구하기
n1 = len(group1) # 52
n2 = len(group2) # 64
# print(n1, n2)
pooled_var = (((n1 - 1) * var1) + ((n2 - 1) * var2)) / (n1 + n2 - 2)
print(f"2. 합동 분산 추정량: {round(pooled_var, 3)}") # 0.449
# 독립표본 t-검정 수행 후 p값 구하기
from scipy import stats
tstat, p_value = stats.ttest_ind(group1, group2, equal_var=True)
print(f"3. 독립표본 t-검정 p값: {round(p_value, 3)}")
※ 문제를 풀 때는 print() 를 자주 써서 내 풀이가 맞는지 확인해 보는 게 좋다.
5. 합동 분산 추정량 쉽게 구하기
합동 분산 추정량 공식은 '(((그룹1 표본개수 -1) * 그룹1 분산) + ((그룹2 표본개수 -1) * 그룹2 분산)) / (그룹1 표본개수 + 그룹2 표본개수 - 2) 인데, 생각해보면 자유도 = 표본개수 - 1 이다.
따라서, 아래와 같이 식을 외워두면 된다.
합동분산 추정량 = ((그룹1 자유도 * 그룹1 분산) + (그룹2 자유도 * 그룹2 분산)) / (그룹1자유도 + 그룹2자유도)
# 기존
pooled_var = (((n1 - 1) * var1) + ((n2 - 1) * var2)) / (n1 + n2 - 2)
# 쉽게
dof1 = n1 -1
dof2 = n2 -1
# 합동분산추정량
pooled_var = ((dof1 * var1) + (dof2 * var2)) / (dof1 + dof2)
다음 내용
[빅분기 실기] 모듈의 뒷부분 이름이 기억나지 않을 때
이전 내용 [빅분기 실기] 작업형 3유형: groom 체험 문제 풀이이전 내용 [빅분기 실기] 작업형 1유형 판다스 중요 문법 정리이전 내용 [빅분기 실기] 작업형 1유형: transfrom('mean') vs mean()이전 내용 [빅
puppy-foot-it.tistory.com