빅데이터분석기사 실기 학습자료 3과목 파트1 - 기술통계 정규성 검정 상관분석 실전
2026. 4. 28. 20:28ㆍ빅데이터분석기사
11111
2222

| [샘플데이터] 3유형 실습 데이터: id salary age score dept gender 1 4500.0 32 85.0 IT M 2 3800.0 45 72.0 HR F 3 5200.0 28 91.0 Finance M 4 3100.0 55 68.0 Sales F 5 8200.0 41 88.0 IT M ← 이상치 가능성 (1000행, 일부 결측 포함) |
1. 작업형 3유형 개요
| [기출패턴] 20점(2문제 × 10점). 가설 설정→검정→결론 순서 준수. 통계량과 p-value를 지정 자릿수로 print(). |
2. 가설검정 기본 원칙 (반드시 암기)
| [핵심암기] 가설검정 핵심 원칙: H0(귀무가설): 차이/관계 없다 → 이것을 기각하거나 채택 H1(대립가설): 차이/관계 있다 → 기각 실패 시 H0 채택 p ≤ 0.05 → H0 기각 → 유의한 차이/관계 있음 (★) p > 0.05 → H0 채택 → 유의한 차이/관계 없음 α(유의수준) = 0.05 기본 사용. 문제에서 다른 값 명시 시 그 값 사용. 양측검정(two-sided): 크거나 작거나 모두 / 단측검정(one-sided): 방향 지정 |
3. 기술통계 완전 정복
3.1 수치형 기술통계
| import pandas as pd, numpy as np df = pd.read_csv("/data/data.csv") # describe(): 수치형 열의 핵심 통계량 한번에 확인 print(df.describe()) # 특정 열 상세 통계 col = df['salary'] print(f"평균(mean) : {col.mean():.4f}") # 산술 평균 print(f"중앙값(median): {col.median():.4f}") # 중간값 (이상치에 강건) print(f"최빈값(mode) : {col.mode()[0]:.4f}") # 가장 많이 등장한 값 ★[0]필수 print(f"표준편차(std) : {col.std():.4f}") # 퍼짐 정도 print(f"분산(var) : {col.var():.4f}") # 표준편차의 제곱 print(f"왜도(skew) : {col.skew():.4f}") # 분포 비대칭도 (+양수=오른쪽 꼬리) print(f"첨도(kurtosis): {col.kurtosis():.4f}") # 분포 뾰족함 (정규=0, 양수=뾰족) print(f"Q1, Q3 : {col.quantile(0.25):.4f}, {col.quantile(0.75):.4f}") ──────────────────────────────────────────────────── 실행 결과 salary count 1000.000 mean 4423.820 ← 평균 std 980.340 ← 표준편차 min 1800.000 25% 3750.000 ← Q1 50% 4380.000 ← 중앙값 75% 5050.000 ← Q3 max 8200.000 평균(mean) : 4423.8200 중앙값(median): 4380.0000 ← 평균>중앙값 → 우측 꼬리 (양의 왜도) 최빈값(mode) : 4200.0000 표준편차(std) : 980.3400 분산(var) : 961066.5600 왜도(skew) : 0.8234 ← 양수: 오른쪽에 긴 꼬리 (고소득자 소수 존재) 첨도(kurtosis): 0.4521 ← 정규분포(0)보다 약간 뾰족 Q1, Q3 : 3750.0000, 5050.0000 |
3.2 범주형 기술통계
| import pandas as pd df = pd.read_csv("/data/data.csv") # value_counts(): 범주별 빈도 print(df['dept'].value_counts()) # normalize=True: 비율로 출력 print(df['dept'].value_counts(normalize=True).round(4)) # 교차표: 두 범주형 변수의 빈도 ct = pd.crosstab(df['dept'], df['gender']) print(ct) # margins=True: 행합/열합 추가 print(pd.crosstab(df['dept'], df['gender'], margins=True)) ──────────────────────────────────────────────────── 실행 결과 IT 320 ← 가장 많은 부서 HR 280 Finance 240 Sales 145 Other 15 Name: dept, dtype: int64 IT 0.3200 ← 32% 차지 HR 0.2800 Finance 0.2400 Sales 0.1450 Other 0.0150 gender F M dept Finance 112 128 HR 145 135 IT 158 162 Sales 72 73 gender F M All dept Finance 112 128 240 ← 합계 포함 All 487 498 985 |
4. 정규성 검정 완전 정복
4.1 Shapiro-Wilk (n < 5000, 시험 표준)
| [기출패턴] 기출: "데이터가 정규분포를 따르는지 Shapiro-Wilk 검정으로 확인하라" |
| from scipy import stats import pandas as pd df = pd.read_csv("/data/data.csv") data = df['salary'].dropna() # 결측값 반드시 제거 후 검정! # H0: 데이터가 정규분포를 따른다 # H1: 데이터가 정규분포를 따르지 않는다 # W(통계량): 1에 가까울수록 정규분포에 가까움 stat, p = stats.shapiro(data) print(f"Shapiro-Wilk W : {round(stat, 4)}") print(f"p-value : {round(p, 4)}") if p > 0.05: print("→ 정규분포 O (p > 0.05, H0 채택) → 모수 검정 사용 가능") else: print("→ 정규분포 X (p ≤ 0.05, H0 기각) → 비모수 검정 사용 권장") ──────────────────────────────────────────────────── 실행 결과 Shapiro-Wilk W : 0.9812 ← 1에 가깝고 (정규에 가까움) p-value : 0.1423 ← 0.05보다 크므로 → 정규분포 O (p > 0.05, H0 채택) → 모수 검정 사용 가능 |
4.2 기타 정규성 검정
| from scipy import stats import pandas as pd df = pd.read_csv("/data/data.csv") data = df['salary'].dropna() # Anderson-Darling: 모든 표본 크기에서 사용 가능 ad_result = stats.anderson(data, dist='norm') print(f"Anderson-Darling 통계량: {round(ad_result.statistic, 4)}") # critical_values[2] = 5% 유의수준 임계값 (인덱스 2) print(f"5% 임계값: {ad_result.critical_values[2]:.4f}") if ad_result.statistic < ad_result.critical_values[2]: print("→ 정규분포 O (통계량 < 임계값)") else: print("→ 정규분포 X (통계량 ≥ 임계값)") # Kolmogorov-Smirnov: n > 5000 대규모 데이터에서 사용 stat, p = stats.kstest(data, 'norm', args=(data.mean(), data.std())) # 평균, 표준편차 지정 print(f" KS 통계량: {round(stat, 4)}, p={round(p, 4)}") ──────────────────────────────────────────────────── 실행 결과 Anderson-Darling 통계량: 0.4823 5% 임계값: 0.7520 → 정규분포 O (0.4823 < 0.7520) KS 통계량: 0.0234, p=0.4821 ← p>0.05: 정규분포 O |
4.3 정규성에 따른 검정 선택 기준
| [핵심암기] 정규성 검정 → 검정 방법 선택: ┌──────────────┬────────────────────┬──────────────────────┐ │ 상황 │ 정규 O (p>0.05) │ 정규 X (p≤0.05) │ ├──────────────┼────────────────────┼──────────────────────┤ │ 독립 2집단 │ 독립표본 t-검정 │ Mann-Whitney U │ │ 대응 2집단 │ 대응표본 t-검정 │ Wilcoxon 부호순위 │ │ 3집단 이상 │ 일원 ANOVA │ Kruskal-Wallis │ │ 단일표본 │ 단일표본 t-검정 │ Wilcoxon 부호검정 │ └──────────────┴────────────────────┴──────────────────────┘ |
5. 상관 分석 완전 정복
5.1 피어슨 상관계수 (수치형-수치형, 정규분포 가정)
| [기출패턴] 기출: "두 변수 간 상관관계를 분석하고 상관계수와 p-value를 출력하라" |
| from scipy.stats import pearsonr import pandas as pd df = pd.read_csv("/data/data.csv") x = df['age'].dropna().reset_index(drop=True) y = df['salary'].dropna().reset_index(drop=True) # 두 변수 길이 맞추기 n = min(len(x), len(y)) x, y = x[:n], y[:n] # H0: 두 변수 간 선형 상관관계 없다 (r=0) # H1: 두 변수 간 선형 상관관계 있다 (r≠0) r, p = pearsonr(x, y) print(f"피어슨 상관계수(r): {round(r, 4)}") # -1~1: 부호=방향, 절대값=강도 print(f"p-value : {round(p, 4)}") # 강도 해석: |r| 0.1↑=약함, 0.3↑=보통, 0.5↑=강함, 0.7↑=매우강함 if abs(r) < 0.3: strength = "약한" elif abs(r) < 0.5: strength = "보통의" elif abs(r) < 0.7: strength = "강한" else: strength = "매우 강한" direction = "양" if r > 0 else "음" print(f"→ {strength} {direction}의 상관관계") print(f"→ 유의성: {'있음 (★)' if p<=0.05 else '없음'}") ──────────────────────────────────────────────────── 실행 결과 피어슨 상관계수(r): 0.6234 ← 양수: 나이↑ → 급여↑ 경향 p-value : 0.0000 ← 0.05보다 매우 작음 → 강한 양의 상관관계 (|0.62| ≥ 0.5) → 유의성: 있음 (★) (p < 0.05) |
5.2 스피어만 & 켄달 상관계수 (비정규/순서형)
| from scipy.stats import spearmanr, kendalltau import pandas as pd df = pd.read_csv("/data/data.csv") x = df['age'].dropna().reset_index(drop=True) y = df['score'].dropna().reset_index(drop=True) n = min(len(x), len(y)) x, y = x[:n], y[:n] # 스피어만: 순위(rank) 기반 상관계수 (비정규 데이터에도 사용 가능) rho, p_s = spearmanr(x, y) print(f"스피어만 rho: {round(rho, 4)}, p={round(p_s, 4)}") # 켄달 타우: 소표본 또는 순서형 데이터에 적합 tau, p_k = kendalltau(x, y) print(f"켄달 tau : {round(tau, 4)}, p={round(p_k, 4)}") # 전체 상관행렬 (수치형 열 전체) corr_matrix = df[['age','salary','score']].corr() print(f" 상관행렬(피어슨): {corr_matrix.round(4)}") ──────────────────────────────────────────────────── 실행 결과 스피어만 rho: 0.5823, p=0.0000 ← 비정규 데이터에서 피어슨 대신 사용 켄달 tau : 0.4012, p=0.0000 상관행렬(피어슨): age salary score age 1.0000 0.6234 0.3821 salary 0.6234 1.0000 0.4512 score 0.3821 0.4512 1.0000 → age-salary 상관(0.62)이 가장 강함 |
5.3 상관분석 실전 패턴
| import pandas as pd from scipy.stats import pearsonr df = pd.read_csv("/data/data.csv") # 패턴1: 특정 변수와 가장 강한 상관관계인 변수 찾기 num_cols = df.select_dtypes(include='number').columns corr = df[num_cols].corr() # 자기 자신(대각선=1.0) 제외 후 최대값 위치 corr_no_diag = corr.where(~(corr == 1.0)) max_pair = corr_no_diag.stack().abs().idxmax() print(f"가장 강한 상관 쌍: {max_pair}") print(f"상관계수: {corr.loc[max_pair]:.4f}") # 패턴2: target과의 상관계수 전체 (특성 선택에 활용) target_corr = df[num_cols].corr()['salary'].drop('salary') print(f" salary와의 상관계수 (절대값 내림차순):") print(target_corr.abs().sort_values(ascending=False).round(4)) ──────────────────────────────────────────────────── 실행 결과 가장 강한 상관 쌍: ('age', 'salary') 상관계수: 0.6234 ← age와 salary가 가장 강한 상관 salary와의 상관계수 (절대값 내림차순): age 0.6234 ← 1위 score 0.4512 tenure 0.3821 id 0.0234 ← 거의 무관 (id는 의미 없는 상관) |
'빅데이터분석기사' 카테고리의 다른 글
| 빅데이터분석기사 실기 학습자료 3과목 파트3 - 선형 회귀분석 · 로지스틱 회귀 · 실전 풀이 (0) | 2026.04.28 |
|---|---|
| 빅데이터분석기사 실기 학습자료 3과목 파트2 - t-검정 · ANOVA · 카이제곱 · 비모수 검정 (0) | 2026.04.28 |
| 빅데이터분석기사 실기 학습자료 2과목 파트4 - 앙상블 심화 · Pipeline · 특성 중요도 · 과적합 진단 · 최종 제출 전략 (0) | 2026.04.28 |
| 빅데이터분석기사 실기 학습자료 2과목 파트3 - 회귀 알고리즘 완전정복 · 비지도학습(클러스터링/PCA) (0) | 2026.04.28 |
| 빅데이터분석기사 실기 학습자료 2과목 파트2 - 분류 알고리즘 완전정복 (0) | 2026.04.28 |