2026. 3. 8. 03:25ㆍ빅데이터분석기사

1. 3유형 개요 및 전략
| 항목 | 내용 |
| 배점 | 2문제 × 15점 = 30점 |
| 형식 | 통계 검정 수행 후 통계량·p값·결론 출력 |
| 핵심 라이브러리 | scipy.stats, statsmodels |
| 답안 형식 | print(round(통계량, 4)), print(round(p값, 4)), 결론 출력 |
2. 검정 선택 기준표 (중요 ★)
| 상황 | 정규성 만족? | 적절한 검정 | 함수 |
| 단일 집단 평균 | 만족 | 단일 t-검정 | stats.ttest_1samp |
| 단일 집단 평균 | 불만족 | 부호검정 또는 Wilcoxon | stats.wilcoxon |
| 두 독립 집단 평균 | 만족+등분산 | 독립 t-검정 | stats.ttest_ind(equal_var=True) |
| 두 독립 집단 평균 | 만족+이분산 | Welch t-검정 | stats.ttest_ind(equal_var=False) |
| 두 독립 집단 평균 | 불만족 | Mann-Whitney U | stats.mannwhitneyu |
| 대응 두 집단 (전후) | 만족 | 대응 t-검정 | stats.ttest_rel |
| 대응 두 집단 (전후) | 불만족 | Wilcoxon 부호순위 | stats.wilcoxon |
| 3개 이상 집단 | 만족 | 일원분산분석 | stats.f_oneway |
| 3개 이상 집단 | 불만족 | Kruskal-Wallis | stats.kruskal |
| 두 범주형 변수 독립성 | - | 카이제곱 독립성 | stats.chi2_contingency |
| 관측 분포 적합도 | - | 카이제곱 적합도 | stats.chisquare |
| 두 연속형 변수 관계 | 선형 정규 | 피어슨 상관 | stats.pearsonr |
| 두 연속형 변수 관계 | 비선형·비정규 | 스피어만 상관 | stats.spearmanr |
3. 정규성·등분산 검정
from scipy import stats
# 정규성 검정 - Shapiro-Wilk (n<50 적합)
data = df['col'].dropna()
stat, p = stats.shapiro(data)
print(f'Shapiro-Wilk: 통계량={round(stat,4)}, p값={round(p,4)}')
if p >= 0.05:
print('정규성 만족 (모수 검정 가능)')
else:
print('정규성 불만족 (비모수 검정 사용)')
# 정규성 검정 - K-S Test (대표본)
stat, p = stats.kstest(data, 'norm',
args=(data.mean(), data.std()))
print(f'K-S Test: p값={round(p,4)}')
# 등분산 검정 - Levene Test (비모수적으로 강건)
g1 = df[df['group']=='A']['col'].dropna()
g2 = df[df['group']=='B']['col'].dropna()
lev_stat, lev_p = stats.levene(g1, g2)
print(f'Levene: 통계량={round(lev_stat,4)}, p값={round(lev_p,4)}')
equal_var = (lev_p >= 0.05) # True면 등분산
# 등분산 검정 - Bartlett (정규분포 가정)
bart_stat, bart_p = stats.bartlett(g1, g2)
print(f'Bartlett: p값={round(bart_p,4)}')
4. t-검정 완전 코드
① 단일표본 t-검정
# H₀: 모평균 μ = 특정값(μ₀)
from scipy import stats
import pandas as pd
df = pd.read_csv('data.csv')
data = df['col'].dropna()
mu0 = 50 # 귀무가설의 기준값
t_stat, p_value = stats.ttest_1samp(data, popmean=mu0)
print(f't통계량: {round(t_stat, 4)}')
print(f'p-값 : {round(p_value, 4)}')
alpha = 0.05
if p_value < alpha:
print(f'귀무가설 기각: 모평균이 {mu0}과 유의하게 다르다. (유의수준 {alpha*100}%)')
else:
print(f'귀무가설 채택: 모평균이 {mu0}이라고 할 수 없다. (유의수준 {alpha*100}%)')
② 독립표본 t-검정
# H₀: 두 집단의 모평균이 같다
from scipy import stats
import pandas as pd
df = pd.read_csv('data.csv')
g1 = df[df['group']=='A']['value'].dropna()
g2 = df[df['group']=='B']['value'].dropna()
# 등분산 검정
lev_stat, lev_p = stats.levene(g1, g2)
print(f'등분산 검정 p값: {round(lev_p, 4)}')
equal_var = (lev_p >= 0.05)
# t-검정 수행
t_stat, p_value = stats.ttest_ind(g1, g2, equal_var=equal_var)
print(f't통계량: {round(t_stat, 4)}')
print(f'p-값 : {round(p_value, 4)}')
alpha = 0.05
if p_value < alpha:
print('귀무가설 기각: 두 집단의 평균에 유의한 차이가 있다.')
else:
print('귀무가설 채택: 두 집단의 평균에 유의한 차이가 없다.')
# 단측 검정 (g1 > g2인지 검정)
t_stat_one, p_one = stats.ttest_ind(g1, g2, equal_var=equal_var,
alternative='greater') # 'less'도 가능
print(f'단측 p-값: {round(p_one, 4)}')
③ 대응표본 t-검정
# H₀: 처리 전후의 차이(μ_d) = 0
from scipy import stats
import pandas as pd
df = pd.read_csv('data.csv')
before = df['before'].dropna()
after = df['after'].dropna()
# 두 열 길이 같아야 함!
t_stat, p_value = stats.ttest_rel(before, after)
print(f't통계량: {round(t_stat, 4)}')
print(f'p-값 : {round(p_value, 4)}')
# 차이 기술통계
diff = after - before
print(f'평균 차이: {round(diff.mean(), 4)}')
print(f'차이 표준편차: {round(diff.std(), 4)}')
5. 분산분석(ANOVA) 완전 코드
① 일원분산분석
# H₀: 모든 집단의 모평균이 같다
from scipy import stats
from statsmodels.stats.multicomp import pairwise_tukeyhsd
import pandas as pd
df = pd.read_csv('data.csv')
# 그룹 분리
groups = df.groupby('group')['score'].apply(list)
g_list = [df[df['group']==g]['score'].dropna().values
for g in df['group'].unique()]
f_stat, p_value = stats.f_oneway(*g_list)
print(f'F통계량: {round(f_stat, 4)}')
print(f'p-값 : {round(p_value, 4)}')
alpha = 0.05
if p_value < alpha:
print('귀무가설 기각: 집단 간 평균에 유의한 차이가 있다.')
# 사후검정 Tukey HSD
clean = df.dropna(subset=['score', 'group'])
tukey = pairwise_tukeyhsd(endog=clean['score'],
groups=clean['group'], alpha=0.05)
print(tukey)
else:
print('귀무가설 채택: 집단 간 평균에 유의한 차이가 없다.')
② 이원분산분석
import statsmodels.api as sm
from statsmodels.formula.api import ols
import pandas as pd
df = pd.read_csv('data.csv')
# 교호작용 포함
formula = 'score ~ C(factor1) + C(factor2) + C(factor1):C(factor2)'
model = ols(formula, data=df).fit()
anova_table = sm.stats.anova_lm(model, typ=2) # Type II
print(anova_table)
# 교호작용 제외 (주효과만)
formula2 = 'score ~ C(factor1) + C(factor2)'
model2 = ols(formula2, data=df).fit()
print(sm.stats.anova_lm(model2, typ=2))
6. 카이제곱 검정 완전 코드
① 독립성 검정
# H₀: 두 범주형 변수는 서로 독립이다
from scipy import stats
import pandas as pd
df = pd.read_csv('data.csv')
# 교차표 생성
ct = pd.crosstab(df['var1'], df['var2'])
print('교차표:')
print(ct)
chi2, p_value, dof, expected = stats.chi2_contingency(ct)
print(f'카이제곱통계량: {round(chi2, 4)}')
print(f'p-값 : {round(p_value, 4)}')
print(f'자유도 : {dof}')
alpha = 0.05
if p_value < alpha:
print('귀무가설 기각: 두 변수 간에 유의한 연관이 있다.')
else:
print('귀무가설 채택: 두 변수는 독립이다.')
② 적합도 검정
# H₀: 관측 빈도가 기대 빈도와 일치한다
from scipy import stats
import numpy as np
# 예: 주사위 600번 던진 관측값 vs 기대값(각 100)
observed = np.array([95, 102, 98, 107, 99, 99])
expected = np.array([100, 100, 100, 100, 100, 100]) # 균등 기대
chi2, p_value = stats.chisquare(f_obs=observed, f_exp=expected)
print(f'카이제곱통계량: {round(chi2, 4)}')
print(f'p-값 : {round(p_value, 4)}')
if p_value < 0.05:
print('귀무가설 기각: 관측 분포가 기대 분포와 유의하게 다르다.')
else:
print('귀무가설 채택: 관측 분포가 기대 분포와 일치한다.')
7. 상관분석 완전 코드
from scipy import stats
import pandas as pd
df = pd.read_csv('data.csv')
x = df['var1'].dropna()
y = df['var2'].dropna()
# 두 변수 같은 인덱스 맞추기
valid = df[['var1','var2']].dropna()
x, y = valid['var1'], valid['var2']
# 피어슨 상관계수 (선형, 정규분포)
corr_p, p_p = stats.pearsonr(x, y)
print(f'피어슨 r : {round(corr_p, 4)}, p값: {round(p_p, 4)}')
# 스피어만 상관계수 (순위, 비정규)
corr_s, p_s = stats.spearmanr(x, y)
print(f'스피어만 ρ: {round(corr_s, 4)}, p값: {round(p_s, 4)}')
# 결론 출력
alpha = 0.05
if p_p < alpha:
print(f'유의한 상관관계 있음 (r={round(corr_p,4)})')
if corr_p > 0:
print('양의 상관관계: 한 변수 증가 시 다른 변수도 증가')
else:
print('음의 상관관계: 한 변수 증가 시 다른 변수 감소')
else:
print('유의한 상관관계 없음')
8. 회귀분석 완전 코드
import statsmodels.api as sm
import pandas as pd
df = pd.read_csv('data.csv')
# 단순 선형 회귀
X = sm.add_constant(df['x']) # 절편항 추가 (필수!)
y = df['y']
model = sm.OLS(y, X).fit()
print(model.summary())
# 주요 결과값 추출
print(f'R² : {round(model.rsquared, 4)}')
print(f'조정 R² : {round(model.rsquared_adj, 4)}')
print(f'F통계량 : {round(model.fvalue, 4)}')
print(f'F p-값 : {round(model.f_pvalue, 4)}')
print(f'회귀계수 :')
print(model.params)
print(f'각 계수 p-값:')
print(model.pvalues)
print(f'AIC: {round(model.aic, 4)}')
print(f'BIC: {round(model.bic, 4)}')
# 다중 선형 회귀
X_multi = sm.add_constant(df[['x1', 'x2', 'x3']])
model_multi = sm.OLS(y, X_multi).fit()
print(model_multi.summary())
# 다중공선성 확인 (VIF)
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif_data = pd.DataFrame()
vif_data['feature'] = X_multi.columns
vif_data['VIF'] = [variance_inflation_factor(X_multi.values, i)
for i in range(X_multi.shape[1])]
print(vif_data) # VIF > 10이면 다중공선성 심각
9. 비모수 검정 코드
from scipy import stats
# Mann-Whitney U (독립 두 집단, 비모수)
g1 = df[df['group']=='A']['value'].dropna()
g2 = df[df['group']=='B']['value'].dropna()
stat, p = stats.mannwhitneyu(g1, g2, alternative='two-sided')
print(f'U통계량: {round(stat,4)}, p값: {round(p,4)}')
# Wilcoxon 부호순위 (대응 두 집단, 비모수)
before = df['before'].dropna()
after = df['after'].dropna()
stat, p = stats.wilcoxon(before, after)
print(f'W통계량: {round(stat,4)}, p값: {round(p,4)}')
# Kruskal-Wallis (3+ 집단, 비모수 ANOVA)
g_list = [df[df['group']==g]['score'].dropna() for g in df['group'].unique()]
stat, p = stats.kruskal(*g_list)
print(f'H통계량: {round(stat,4)}, p값: {round(p,4)}')
10. 3유형 실전 문제 5선
문제 1: 독립표본 t-검정 전체 풀이
# 문제: A/B 그룹의 구매금액 평균에 유의한 차이가 있는지
# 유의수준 5%에서 검정하시오. 등분산 여부를 확인하고 적절한 방법을 선택하라.
from scipy import stats
import pandas as pd
df = pd.read_csv('data.csv')
g_a = df[df['group']=='A']['amount'].dropna()
g_b = df[df['group']=='B']['amount'].dropna()
# 등분산 검정
lev_stat, lev_p = stats.levene(g_a, g_b)
print(f'[등분산 검정] F={round(lev_stat,4)}, p={round(lev_p,4)}')
equal_var = lev_p >= 0.05
print(f'등분산 여부: {equal_var}')
# t-검정
t, p = stats.ttest_ind(g_a, g_b, equal_var=equal_var)
print(f'[t-검정] t통계량={round(t,4)}, p값={round(p,4)}')
if p < 0.05:
print('결론: 유의수준 5%에서 두 그룹의 구매금액 평균은 유의하게 다르다.')
else:
print('결론: 유의수준 5%에서 두 그룹의 구매금액 평균에 차이가 없다.')
문제 2: 카이제곱 독립성 검정
# 문제: 성별(gender)과 구매여부(purchased) 간에
# 유의한 연관이 있는지 카이제곱 검정으로 확인하시오. (α=0.05)
from scipy import stats
import pandas as pd
df = pd.read_csv('data.csv')
ct = pd.crosstab(df['gender'], df['purchased'])
print('교차표:', ct, sep='\n')
chi2, p, dof, exp = stats.chi2_contingency(ct)
print(f'카이제곱통계량: {round(chi2, 4)}')
print(f'p-값: {round(p, 4)}, 자유도: {dof}')
if p < 0.05:
print('결론: 성별과 구매여부 간에 유의한 연관이 있다.')
else:
print('결론: 성별과 구매여부는 독립적이다.')
문제 3: 일원분산분석 + 사후검정
# 문제: 3개 지역(Seoul, Busan, Daegu)의 월 매출 평균에
# 차이가 있는지 일원분산분석으로 검정하고, 유의하면 사후검정을 수행하시오.
from scipy import stats
from statsmodels.stats.multicomp import pairwise_tukeyhsd
import pandas as pd
df = pd.read_csv('data.csv')
regions = df['region'].unique()
g_list = [df[df['region']==r]['sales'].dropna() for r in regions]
f_stat, p_val = stats.f_oneway(*g_list)
print(f'F통계량: {round(f_stat, 4)}, p값: {round(p_val, 4)}')
if p_val < 0.05:
print('귀무가설 기각: 지역 간 매출 평균에 유의한 차이가 있다.')
clean = df.dropna(subset=['sales','region'])
tk = pairwise_tukeyhsd(clean['sales'], clean['region'], alpha=0.05)
print(tk)
else:
print('귀무가설 채택: 지역 간 매출 평균에 유의한 차이가 없다.')
문제 4: 회귀분석 유의성 검정
# 문제: 'study_hours'가 'exam_score'에 유의한 영향을 미치는지
# 단순 회귀분석으로 검정하고, 회귀계수와 R²을 출력하시오.
import statsmodels.api as sm
import pandas as pd
df = pd.read_csv('data.csv').dropna()
X = sm.add_constant(df['study_hours'])
y = df['exam_score']
model = sm.OLS(y, X).fit()
const, slope = model.params
p_const, p_slope = model.pvalues
r2 = model.rsquared
print(f'절편(const): {round(const,4)}, p값: {round(p_const,4)}')
print(f'기울기(study_hours): {round(slope,4)}, p값: {round(p_slope,4)}')
print(f'R²: {round(r2,4)}')
if p_slope < 0.05:
print('study_hours는 exam_score에 유의한 영향을 미친다.')
else:
print('study_hours는 exam_score에 유의한 영향을 미치지 않는다.')
문제 5: 대응표본 t-검정
# 문제: 교육 전(before)과 후(after)의 성적 평균에
# 유의한 차이가 있는지 대응표본 t-검정으로 검정하시오. (α=0.05)
from scipy import stats
import pandas as pd
df = pd.read_csv('data.csv')
valid = df[['before', 'after']].dropna()
before = valid['before']
after = valid['after']
print(f'before 평균: {round(before.mean(), 4)}')
print(f'after 평균: {round(after.mean(), 4)}')
print(f'평균 차이 : {round((after-before).mean(), 4)}')
t_stat, p_val = stats.ttest_rel(before, after)
print(f't통계량: {round(t_stat, 4)}')
print(f'p-값 : {round(p_val, 4)}')
if p_val < 0.05:
print('결론: 교육 전후 성적에 유의한 차이가 있다.')
if after.mean() > before.mean():
print('교육 후 성적이 유의하게 향상되었다.')
else:
print('결론: 교육 전후 성적에 유의한 차이가 없다.')
'빅데이터분석기사' 카테고리의 다른 글
| 빅데이터분석기사 필기 핵심용어 암기노트 - 1 (1) | 2026.03.12 |
|---|---|
| 2026 빅데이터 분석기사 실기 작업형 3 기타 학습자료 (1) | 2026.03.08 |
| 2026 빅데이터 분석기사 실기 작업형 2 유형 (0) | 2026.03.08 |
| 2026 빅데이터 분석기사 실기 작업형1 문제 유형 (0) | 2026.03.08 |
| 2026 빅데이터 분석기사 실기 작업형 1 함수 정리 (0) | 2026.03.08 |