-
[2월 2주차-2/12(3)]한국복지패널데이터로 한국인의 삶을 분석해보자! 🧐Why Not SW CAMP 5기/수업 기록 2025. 2. 13. 10:37
안녕하세요! 오늘은 한국복지패널데이터(Koweps) 를 활용해 한국인의 삶을 데이터 분석을 통해 살펴보려고 합니다. 한국복지패널데이터는 가구 및 개인의 경제활동, 생활실태, 복지 욕구 등을 연구하기 위해 구축된 대규모 데이터로, 800개 이상의 변수로 구성되어 있어 굉장히 방대한 자료입니다.
데이터 분석을 통해 다음과 같은 궁금증을 해결해 보겠습니다!
✅ 성별에 따른 월급 차이는 존재할까?
✅ 나이와 월급의 관계는 어떨까?
✅ 연령대별 평균 월급은 어떻게 다를까?
✅ 직업별로 월급은 얼마나 차이가 날까?
✅ 종교 유무에 따라 이혼율이 다를까?
✅ 지역별 연령대 비율은 어떤 패턴을 보일까?
🔹 1. 데이터 준비하기 📊
분석을 위해 먼저 데이터를 불러오고, 주요 변수들을 확인해 보겠습니다.
📌 데이터 불러오기
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 한국복지패널데이터 불러오기 raw_welfare = pd.read_spss('./data/Koweps_hpwc14_2019_beta2.sav') # 복사본 생성 welfare = raw_welfare.copy()데이터를 살펴보면 총 14,418개 행과 830개 컬럼으로 구성되어 있음을 알 수 있습니다.
welfare.shape # (14418, 830) welfare.info() # 변수 타입 및 결측치 확인📌 주요 변수 선택 및 이름 변경
데이터에서 우리가 분석에 활용할 주요 변수들을 선정하고, 이해하기 쉽게 변수명을 변경하겠습니다.
welfare = welfare.rename(columns={ 'h14_g3': 'sex', # 성별 'h14_g4': 'birth', # 태어난 연도 'h14_g10': 'marriage_type', # 혼인 상태 'h14_g11': 'religion', # 종교 유무 'p1402_8aq1': 'income', # 월급 'h14_eco9': 'code_job', # 직업 코드 'h14_reg7': 'code_region' # 지역 코드 })이제 데이터를 본격적으로 분석해 보겠습니다! 🚀
🔹 2. 성별에 따른 월급 차이 분석
📌 성별 데이터 전처리
먼저 성별 데이터를 확인해 보면, 1(남성), 2(여성)으로 기록되어 있습니다. 이를 'male', 'female'로 변환하겠습니다.
# 1. 변수 검토: 타입 파악, 범주마다 몇 명? welfare['sex'].dtypes # dtype('float64') # 항목별 개수 -> 이상치 확인 가능 welfare['sex'].value_counts() ''' sex 2.0 7913 1.0 6505 Name: count, dtype: int64 ''' # 성별 항목에 이름 부여 welfare['sex'] = np.where(welfare['sex'] ==1, 'male', 'female') welfare['sex'].value_counts() ''' sex female 7913 male 6505 Name: count, dtype: int64이제 성별 빈도를 시각화해 보겠습니다.
sns.countplot(data=welfare, x='sex') plt.show()📌 월급 데이터 전처리
월급(income) 데이터를 확인해 보니 결측치가 많습니다. 먼저 결측치를 제거하고 월급 분포를 살펴보겠습니다.
welfare['income'].isna().sum() # 9,884개 결측치 확인 # 결측치 제거 후 평균 월급 계산 sex_income = welfare.dropna(subset=['income']).groupby('sex', as_index=False).agg(mean_income=('income', 'mean')) ''' sex mean_income 0 female 186.293096 1 male 349.037571 '''sns.barplot(data=sex_income, x='sex', y='mean_income') plt.show()📌 결과: 남성이 여성보다 평균적으로 더 높은 월급을 받는 것으로 나타났습니다.

🔹 3. 나이와 월급의 관계
📌 나이 데이터 변환
태어난 연도(birth)를 이용해 나이(age) 변수를 생성하겠습니다.
welfare = welfare.assign(age=2019 - welfare['birth'] + 1)나이 분포를 확인해 보겠습니다.
sns.histplot(data=welfare, x='age') plt.show()📌 나이별 평균 월급 분석
age_income = welfare.dropna(subset=['income']).groupby('age', as_index=False).agg(mean_income=('income', 'mean')) sns.lineplot(data=age_income, x='age', y='mean_income') plt.show()📌 결과: 50대까지 월급이 증가하다가 이후 감소하는 경향을 보였습니다.

🔹 4. 연령대 및 성별 월급 차이
연령대를 청년(30세 미만), 중년(30~59세), 노년(60세 이상) 으로 나누고, 평균 월급을 비교해 보겠습니다.
# 연령대 변수 만들기 welfare = welfare.assign( ageg=np.where(welfare['age'] < 30, 'young', np.where(welfare['age'] <= 59, 'middle', 'old')) ) welfare['ageg'].value_counts() ''' ageg old 5955 middle 4963 young 3500 Name: count, dtype: int64 ''' ageg_sex = welfare.dropna(subset='income').groupby(['ageg','sex'], as_index = False).agg(mean_income =('income', 'mean')) ''' ageg sex mean_income 0 middle female 230.481735 1 middle male 409.541228 2 old female 90.228896 3 old male 204.570231 4 young female 189.822222 5 young male 204.909548 ''' sns.barplot(data=ageg_sex, x = 'ageg', y='mean_income', hue = 'sex', order = ['young', 'middle', 'old']) plt.show()📌 결과: 중년층의 평균 월급이 가장 높고, 노년층에서 급격히 감소하는 경향이 나타났습니다.

🔹 5. 직업별 월급 차이
직업별 평균 월급을 비교해 보겠습니다.
# 직업 코드 데이터를 불러와 병합 list_job = pd.read_excel('./data/Koweps_Codebook_2019.xlsx', sheet_name='직종코드') list_job.head() ''' code_job job 0 111 의회 의원∙고위 공무원 및 공공단체 임원 1 112 기업 고위 임원 2 121 행정 및 경영 지원 관리자 3 122 마케팅 및 광고∙홍보 관리자 4 131 연구∙교육 및 법률 관련 관리자 ''' welfare = welfare.merge(list_job, how='left', on='code_job') # 직업별 월급 평균 계산 job_income = welfare.dropna(subset=['income']).groupby('job', as_index=False).agg(mean_income=('income', 'mean')) job_income.head() ''' job mean_income 0 가사 및 육아 도우미 92.455882 1 간호사 265.219178 2 감정∙기술영업및중개관련종사자 391.000000 3 건물 관리원 및 검표원 168.375000 4 건설 및 광업 단순 종사자 261.975000 ''' # 상위 10개 직업 시각화 top10_jobs = job_income.sort_values(by='mean_income', ascending=False).head(10) plt.rcParams.update({'font.family': 'Malgun Gothic'}) sns.barplot(data=top10_jobs, x='mean_income', y='job') plt.show()📌 결과: 의료 진료 전문가, 법률 전문가 등이 가장 높은 월급을 받는 것으로 나타났습니다.

🔹 6. 종교 유무에 따른 이혼율
# 종교 유무 변수 확인 welfare['religion'] = np.where(welfare['religion'] == 1, 'yes', 'no') # 결혼 상태 변수 확인 dm={0:'비해당(18세 미만)', 1:'유배우', 2:'사별', 3:'이혼', 4:'별거', 5:'미혼(18세이상, 미혼모 포함)', 6:'기타(사망 등)'} welfare['marriage_type'] = welfare['marriage_type'].replace(dm) # 이혼율 분석 religion_marriage = welfare.query("marriage_type in ['유배우', '이혼']").groupby(['religion', 'marriage_type'], as_index=False).agg(n = ('marriage_type','count')) ''' religion marriage_type n 0 N 유배우 3660 1 N 이혼 384 2 Y 유배우 3530 3 Y 이혼 305 ''' religion_marriage['total'] = religion_marriage.groupby('religion')['n'].transform('sum') religion_marriage['ratio'] = religion_marriage['n'] / religion_marriage['total'] religion_marriage # 그래프 그리기 plt.figure(figsize=(8, 5)) ax=sns.barplot(data = religion_marriage, x = 'religion', y='ratio', hue = 'marriage_type') plt.ylabel("이혼율 (%)") plt.xlabel("종교 유무") plt.title("종교 유무에 따른 이혼율 비교") plt.ylim(0, 1) for container in ax.containers: ax.bar_label(container, fmt="%.3f%%", fontsize=10) plt.show()📌 결과:

🔹 7. 지역별 연령대 비율
# 지역 변수 dr={1:'서울', 2:'수도권(인천/경기)', 3:'부산/경남/울산', 4:'대구/경북', 5:'대전/충남', 6:'강원/충북', 7:'광주/전남/전북/제주도'} welfare['code_region'] = welfare['code_region'].replace(dr) # 연령대 변수 만들기 welfare = welfare.assign(age = 2019-welfare['birth'] + 1) welfare['age'].describe() welfare = welfare.assign(ageg = np.where(welfare['age']<30, 'young', np.where(welfare['age']<=59, 'middle', 'old'))) region_ageg = welfare.groupby(['code_region', 'ageg'], as_index = False).agg(n = ('ageg', 'count')) region_ageg.head() ''' code_region ageg n total ratio 0 강원/충북 middle 351 1137 0.308707 1 강원/충북 old 522 1137 0.459103 2 강원/충북 young 264 1137 0.232190 3 광주/전남/전북/제주도 middle 784 2466 0.317924 4 광주/전남/전북/제주도 old 1108 2466 0.449311 ''' # 비율 계산 region_ageg['total'] = region_ageg.groupby('code_region')['n'].transform('sum') region_ageg['ratio'] = region_ageg['n'] / region_ageg['total'] # 그래프 그리기 plt.figure(figsize=(8, 5)) ax=sns.barplot(data = region_ageg, x = 'code_region', y='ratio', hue = 'ageg') plt.xticks(rotation=25) plt.ylabel("연령대 비율 (%)") plt.xlabel("지역") plt.title("지역에 따른 연령대 비율 비교") plt.ylim(0, 0.6) for container in ax.containers: ax.bar_label(container, fmt="%.3f%%", fontsize=7) plt.show()📌 결과: 지역별로 연령대 분포가 다르게 나타났습니다.

〰 비율 구하는 다른 방법(value_counts(normalize=True) 사용)
region_ageg2 = welfare.groupby('code_region', as_index = False)['ageg'].value_counts(normalize=True) region_ageg2 = region_ageg2.assign(proportion = region_ageg2['proportion']*100).round(1) ''' code_region ageg proportion 0 강원/충북 old 45.9 1 강원/충북 middle 30.9 2 강원/충북 young 23.2 3 광주/전남/전북/제주도 old 44.9 4 광주/전남/전북/제주도 middle 31.8 ''' sns.barplot(data=region_ageg2, y='code_region', x='proportion', hue='ageg') plt.show()
〰 누적 막대 그래프 만들기 (피벗 이용)
# 시각화(막대, 누적) ''' code_region ageg proportion 0 강원/충북 old 45.9 1 강원/충북 middle 30.9 2 강원/충북 young 23.2 3 광주/전남/전북/제주도 old 44.9 4 광주/전남/전북/제주도 middle 31.8 피벗을 이용해 이 구조를 바꿀거임. 피벗: 행과 열을 회전하여 표의 구성을 변경하는 작업. 누적 그래프 형태로 시각화 할 때 사용 1. 지역, 연령대, 비율 추출 2. DataFrame.pivot() 2-1. 지역을 기준으로 : index = 지역 2-2. 연령대별로 컬럼을 구성: columns = 연령대 2-3. 각 항목의 값을 비율로 채우기: values = 비율 ''' pivot_df = region_ageg2[['code_region', 'ageg', 'proportion']].pivot(index='code_region', columns='ageg', values = 'proportion') # 초년 중년 노년 으로 순서 바꾸기 reorder_df = pivot_df.sort_values('old')[['young', 'middle', 'old']] ''' ageg young middle old code_region 수도권(인천/경기) 28.7 38.8 32.5 서울 23.9 38.5 37.6 대전/충남 25.0 33.6 41.3 부산/경남/울산 22.9 33.4 43.8 광주/전남/전북/제주도 23.3 31.8 44.9 강원/충북 23.2 30.9 45.9 대구/경북 20.0 29.6 50.4 ''' reorder_df.plot.barh(stacked = True) plt.show()
🔹 마무리
오늘은 한국복지패널데이터를 활용해 한국인의 삶을 분석해 보았습니다. 데이터 분석을 통해 성별, 연령, 직업, 종교 등의 요소가 개인의 경제 및 사회적 특성과 어떻게 연관되는지를 확인할 수 있었습니다. 😊
'Why Not SW CAMP 5기 > 수업 기록' 카테고리의 다른 글
[2월 2주차-2/13(2)]🌟 인터랙티브 시각화: HTML 파일로 저장하여 웹 브라우저에서 실행하기 (1) 2025.02.13 [2월 2주차-2/13(1)]📊 통계 분석 기법을 이용한 가설 검정 (0) 2025.02.13 [2월 2주차-2/12(2)]📝 Pandas로 데이터 정제하기: 이상치 & 결측치 처리 (0) 2025.02.12 [2월 2주차-2/12(1)]이터레이터(Iterator)와 제너레이터(Generator) 쉽게 이해하기 (0) 2025.02.12 [2월 2주차-2/11] Python 기초 문법 정리 (0) 2025.02.11