2026 빅데이터 분석기사 실기 작업형 3 요약

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

11111

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('결론: 교육 전후 성적에 유의한 차이가 없다.')

 

2222