🔥알림🔥
① 테디노트 유튜브 -
구경하러 가기!
② LangChain 한국어 튜토리얼
바로가기 👀
③ 랭체인 노트 무료 전자책(wikidocs)
바로가기 🙌
④ RAG 비법노트 LangChain 강의오픈
바로가기 🙌
⑤ 서울대 PyTorch 딥러닝 강의
바로가기 🙌
국민연금 데이터를 활용한 연봉추정 분석
국민연금 데이터를 공공 데이터 포털에서 제공합니다. 국민연금 데이터를 활용하여 특정 회사의 임직원 평균 연봉을 역추정해보는 것도 가능합니다.
대표적인 사례가 바로 크레딧잡(kreditjob.com) 입니다.
임직원의 국민연금 납부 내역을 역추적하여 사람들이 제일 궁금해 하는 연봉 정보를 역추정하여 정보를 제공합니다.
물론, 정확도는 다소 떨어질 수 있습니다. 국민연금 납부액에도 상한선이 있기 때문에,
실제보다 낮게 평가될 가능성이 큽니다.
국민연금 데이터를 활용한 데이터 분석
- 데이터셋: 공공 데이터 포털
- 형태: 파일데이터 (csv)
- 다운로드: https://www.data.go.kr/data/3046071/fileData.do
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
plt.rc('font', family='NanumBarunGothic')
plt.rcParams['figure.figsize'] = (10, 7)
pd.set_option('display.float_format', lambda x: '%.2f' % x)
%matplotlib inline
df = pd.read_csv('data/national-pension-202006.csv')
df.head()
Column 정리 (Clean)
df.columns
columns = ['자료생성년월', '사업장명', '사업자번호', '가입상태', '우편번호', '지번주소', '도로명주소', '법정주소코드',
'행정주소코드', '광역시코드', '시군구코드', '읍면동코드', '사업장형태', '업종코드', '업종코드명',
'적용일', '재등록일', '탈퇴일', '가입자수', '고지금액', '신규', '상실',
]
len(df.columns)
len(columns)
df.columns = columns
df.head()
핵심 데이터 column 추출
df_main = df[['사업장명', '가입자수', '신규', '상실', '고지금액']]
df_main.head()
데이터 통계
df_main['신규'].mean()
df_main['상실'].mean()
df_main['가입자수'].mean()
df_main['고지금액'].mean()
월급, 연봉 추정
(df_main['고지금액'] / df_main['가입자수']).head()
df_main['인당고지금액'] = df_main['고지금액'] / df_main['가입자수']
df['인당고지금액'] = df['고지금액'] / df['가입자수']
df_main['인당고지금액'].head()
국민연금 정보로 어떻게 연봉정보를 계산하나요?
국민연금 보험률은 9%입니다. 쉽게 이야기 하면 급여(신고소득월액)의 9%를 국민연금으로 내는 것입니다.
하지만 이를 절반으로 나누어 4.5%는 회사가, 나머지 절반은 개인이 부담하는 구조입니다. 회사는 급여 외에 추가로 금액을 부담합니다.
국민연금 보험료는 소득 상한선과 하한선이 설정되어 있어 소득 전체가 아닌 일부 소득에만 부과됩니다.
이를 역산하면 신고소득월액의 계산이 가능합니다. 하지만 상한선과 하한선이 설정되어 있어 실제보다 과소계산될 수 있습니다
[수식]
- 임직원 평균 월급 = 인당고지금액 / 9% * 100%
- 임직원 평균 연봉 = 임직원 평균 월급 * 12개월
df_main['평균월급'] = df_main['인당고지금액'] / 9 * 100
df['평균월급'] = df['인당고지금액'] / 9 * 100
df_main['평균연봉'] = df_main['평균월급'] * 12
df['평균연봉'] = df['평균월급'] * 12
df_main['평균월급'].notnull().sum()
plt.figure(figsize=(10, 7))
sns.distplot(df_main.loc[df_main['평균연봉'].notnull(), '평균연봉'])
plt.title('평균연봉', fontsize=18)
plt.show()
plt.figure(figsize=(10, 7))
sns.distplot(df_main.loc[df_main['평균월급'].notnull(), '평균월급'])
plt.title('평균월급', fontsize=18)
plt.show()
정렬(Order)
연봉 King!
df_main.sort_values(by='가입자수', ascending=False).head(20)
신규 채용 King!
df_main.sort_values(by='신규', ascending=False).head(20)
상실 King!
df_main.sort_values(by='상실', ascending=False).head(20)
300인 이하 기업
people_limit = 300
small = df_main.loc[(df_main['가입자수'].notnull()) & (df_main['가입자수'] < people_limit)]
small['가입자수'].isnull().sum()
plt.figure(figsize=(10, 7))
sns.distplot(small['가입자수'])
plt.title('가입자', fontsize=18)
plt.show()
small.sort_values(by='상실', ascending=False)
사업장명 데이터 정제 (Cleansing)
import re
# 괄호안 문자열 제거
pattern_1 = '\(.*\)'
pattern_2 = '\(.*\)'
pattern_3 = '주식회사'
(주), (주식회사) 문자열 제거
re.sub(pattern_1, '', '브레인크루(주)')
re.sub(pattern_1, '', '브레인크루(주식회사)')
re.sub(pattern_1, '', '(주)브레인크루')
re.sub(pattern_2, '', '(주)타워홀딩스')
주식회사 문자열 제거
re.sub(pattern_2, '', '브레인크루 주식회사')
re.sub(pattern_2, '', '브레인크루주식회사')
re.sub(pattern_2, '', '주식회사브레인크루주식회사')
def text_preprocess(text):
text = re.sub(pattern_1, '', text)
text = re.sub(pattern_2, '', text)
text = re.sub(pattern_3, '', text)
return text
df_main['사업장명'] = df_main['사업장명'].apply(text_preprocess)
df_main[df_main['사업장명'] == '패스트캠퍼스']
df['사업장명'] = df['사업장명'].apply(text_preprocess)
df.columns
plt.figure(figsize=(16, 6))
sns.barplot(x=df.groupby('시군구코드')['가입자수'].mean().index, y=df.groupby('시군구코드')['가입자수'].mean())
plt.title('시군구 별 가입자수')
plt.xticks(rotation=90)
plt.show()
plt.figure(figsize=(16, 6))
sns.barplot(x=df.groupby('시군구코드')['신규'].mean().index, y=df.groupby('시군구코드')['신규'].mean())
plt.title('시군구 별 신규인력')
plt.xticks(rotation=90)
plt.show()
plt.figure(figsize=(16, 6))
sns.barplot(x=df.groupby('시군구코드')['상실'].mean().index, y=df.groupby('시군구코드')['상실'].mean())
plt.title('시군구 별 신규인력')
plt.xticks(rotation=90)
plt.show()
df.head()
신규 인력이 많은 시군구코드
경기도 평택시에서 최근 국민연금 가입자 신규인력이 가장 많이 발생했음
주로 건축 인력 혹은 건설사 인력들이 신규로 편입되면서 국민연금 가입자 발생이 가장 많이 일어난 것으로 집계 됐다.
df.loc[df['시군구코드'] == 220][['사업장명','지번주소','신규']].sort_values(by='신규', ascending=False).head(20)
서울특별시 영등포구에서 가장 많은 상실 인력이 발생했다.
하지만, 효성ITX, 엘지전자와 같이 굵직한 기업들이 인력 감소를 함으로써 본 주소인 영등포구 에서 상실 인력이 많이 발생한 것으로 집계됐다.
df.loc[df['시군구코드'] == 560][['사업장명','지번주소','상실']].sort_values(by='상실', ascending=False).head(20)
업종별 신규 인력 현황
df.groupby('업종코드명')['신규'].mean()
df_1 = df.groupby('업종코드명')['신규'].mean()
df_1.sort_values(ascending=False).count()
총 출력할 갯수(업종=1121개)가 너무 많다...ㅠ
상위 50 개 업종 출력하도록 하겠습니다.
df_top100 = df_1.sort_values(ascending=False).head(50)
plt.figure(figsize=(16, 6))
sns.barplot(x=df_top100.index, y=df_top100)
plt.title('업종별 신규인력')
plt.xticks(rotation=90)
plt.show()
- 코로나 바이러스 이전 사태와는 면밀한 비교를 위하여 이전 데이터가 필요합니다.
- 하지만, 포스트 코로나 현상황에서는 음료품배달업, 포장 검수 및 계량 서비스업, 수산동물 훈제 조리 및 유사 조제식품 제조업 순으로 채용이 증가되었음을 확인할 수 있습니다.
df_2 = df.groupby('업종코드명')['상실'].mean()
df_bot100 = df_2.sort_values(ascending=False).head(50)
plt.figure(figsize=(16, 6))
sns.barplot(x=df_bot100.index, y=df_bot100)
plt.title('업종별 상실인력')
plt.xticks(rotation=90)
plt.show()
업종별 상실 인력에 대한 TOP 50 결과입니다.
여기서 재밌는 점은, 이전에 신규인력이 가장 많은 업종도 음료품배달원 이었다는 점입니다.
좀 더 구체적인 데이터를 통해서 신규와 상실이 동시에 많이 일어난 이유에 대한 분석이 면밀히 필요합니다.
때론, 한 기업이 M&A를 진행된 후 타 회사로 인력이 상실 -> 편입 되면서 데이터 인사이트에 대한 왜곡 현상이 생길 수 있습니다.
업종별 단일 회사 연봉 비교 차트 그리기
def compare_and_visualize(company):
code = df[df['사업장명'] == company]['업종코드']
cols = ['가입자수', '평균월급', '평균연봉', '신규', '상실', '업종코드']
filtered = df.loc[df['업종코드']==code.item()][cols]
df_company = df.loc[df['사업장명'] == company][cols]
df_company = df_company.append(pd.Series(filtered.mean()), ignore_index=True)
compare_cols = ['가입자수', '평균월급', '평균연봉', '신규', '상실']
for col in compare_cols:
plt.figure(figsize=(10, 5))
sns.barplot(x=[company, '업종평균'], y=col, data=df_company)
plt.title('{} vs 업종평균'.format(col), fontsize=18)
plt.show()
compare_and_visualize('패스트캠퍼스')
댓글남기기