실전 데이터 분석 67: 부서별 직원의 사내 교육 이수시간 대비 평가 전후 성적 향상 및 인사고과 기여도 분석
📌 강의 개요 (30분 완성)

임직원의 사내 직무 역량 강화 교육 연수 이력 데이터셋입니다. 교육 투입 시간과 교육 전후의 역량 평가 점수 도약, 그리고 최종 인사고과(PerformanceRating) 간의 시너지 관계를 규명합니다.
학습 목표:
- 그룹별 평균 대치 (
groupby.transform): 부서별 기본 직무 역량이 상이하므로 부서별 평균 사후 평가 성적으로 누락값을 정밀 대치합니다. - 다차원 교육 성장률 산점도 (
boxplot,scatterplot): 고과 등급별 연수 시간 상자 및 부서 오버레이 전후 평가 상관 지도를 시각화합니다.
🧐 실무 도메인 지식 가이드 (Domain Knowledge Guide)
👥 인사 및 조직 문화 (HR & Workplace Analysis) 인적 자원 관리(HR Analytics)는 핵심 인재의 이탈(Attrition) 방지, 사내 직무 이동 성과, 복지 리텐션을 다루는 과학적 기업 운영 분야입니다.
- 직원 자발적 퇴사(Attrition): 야근 빈도, 직무 몰입도(Engagement), 급여 대비 승진 연한 격차 등을 통해 조기 이탈 리스크 직원을 경보합니다.
- 채용 채널 성과 분석: 직무 코딩테스트 및 전형 결과와 입사 사후 실제 성과 데이터 간의 타당성(상관) 관계를 실증 분석합니다.
- 원격 근무 효율성: 원격/사무실 하이브리드 근무자의 생산성 점수와 근무 만족도 분산 차이를 통계 검증(T-test 등)합니다.
Step 1: 데이터 구조 살펴보기 (Data Overview)
csv_data 폴더에 준비해 둔 hr_training.csv 파일을 판다스로 불러옵니다.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 그래프 설정 (한글 폰트 및 마이너스 기호 깨짐 방지)
import koreanize_matplotlib
plt.rcParams['axes.unicode_minus'] = False
sns.set_theme(style="whitegrid")
# 로컬 CSV 파일 불러오기
df = pd.read_csv('./hr_training.csv')
# 데이터 구조 및 첫 5행 확인
df = pd.read_csv('./hr_training.csv')
print(df.info())
print(df.head())
💻 [실행 결과]
<class 'pandas.DataFrame'> RangeIndex: 1000 entries, 0 to 999 Data columns (total 6 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 EmployeeID 1000 non-null int64 1 Department 1000 non-null str 2 TrainingHours 1000 non-null int64 3 PreScore 1000 non-null int64 4 PostScore 988 non-null float64 5 PerformanceRating 1000 non-null int64 dtypes: float64(1), int64(4), str(1) memory usage: 53.6 KB None EmployeeID Department ... PostScore PerformanceRating 0 670001 Support ... 68.0 3 1 670002 HR ... 86.8 5 2 670003 Engineering ... 93.0 5 3 670004 Engineering ... 75.4 4 4 670005 Support ... 61.5 3 [5 rows x 6 columns]
<class ‘pandas.DataFrame’>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 6 columns):
# Column Non-Null Count Dtype
— —— ————– —–
0 EmployeeID 1000 non-null int64
1 Department 1000 non-null str
2 TrainingHours 1000 non-null int64
3 PreScore 1000 non-null int64
4 PostScore 988 non-null float64
5 PerformanceRating 1000 non-null int64
dtypes: float64(1), int64(4), str(1)
memory usage: 47.0 KB
EmployeeID Department TrainingHours PreScore PostScore PerformanceRating
0 670001 Support 27 45 68.0 3
1 670002 HR 39 64 86.8 5
2 670003 Engineering 36 66 93.0 5
3 670004 Engineering 36 52 75.4 4
4 670005 Support 12 49 61.5 3
```
💡 코드 딥다이브 (Code Deep Dive)
주요 분석 대상 컬럼:
EmployeeID: 직원 고유 사번Department: 소속 부서 (Engineering, Sales, HR, Support 등)TrainingHours: 연간 직무 교육 이수 시간PreScore: 교육 이수 직전 역량 평가 점수PostScore: 교육 이수 완료 후 직무 평가 점수 (결측치 존재)PerformanceRating: 당해년도 최종 분기 인사고과 평가 등급 (1~5점)
Step 2: 전처리와 결측치 정제 (Preprocess)
현실의 데이터는 항상 누락이 있거나 유효성 정제가 필요합니다. 데이터 전처리 단계에서 결측 상태를 확인하고 올바르게 보정합니다.
# 1. 컬럼별 결측치 개수 확인
print("--- 정제 전 결측치 확인 ---")
print(df.isnull().sum())
# 2. 결측치 전처리 및 대치 수행
df['PostScore'] = df.groupby('Department')['PostScore'].transform(lambda x: x.fillna(x.mean()))
print(df.isnull().sum())
💻 [실행 결과]
--- 정제 전 결측치 확인 --- EmployeeID 0 Department 0 TrainingHours 0 PreScore 0 PostScore 12 PerformanceRating 0 dtype: int64 EmployeeID 0 Department 0 TrainingHours 0 PreScore 0 PostScore 0 PerformanceRating 0 dtype: int64
— 정제 전 결측치 확인 — EmployeeID 0 Department 0 TrainingHours 0 PreScore 0 PostScore 12 PerformanceRating 0
— 정제 후 결측치 확인 — EmployeeID 0 Department 0 TrainingHours 0 PreScore 0 PostScore 0 PerformanceRating 0
```
💡 분석가의 통찰 (Analyst’s Insight)
- 부서 가중 그룹 대치의 합리성: 직무 사후 점수는 부서(Department) 종류에 따라 기저 점수 수준과 기술 난이도 편차가 매우 큽니다. 전체 평균으로 대입하면 기술직군의 특성을 반영하지 못하므로 부서별 평균 성적으로 결측을 채워 전처리의 무결성을 지켜냅니다.
Step 3: 단변수 분포 분석 (Univariate EDA)
가장 먼저 핵심 변수가 전체 데이터에서 어떤 빈도와 분포를 가졌는지 단일 변수 시각화를 통해 파악해 봅니다.
plt.figure(figsize=(8, 5))
# 단변수 분석 그래프 생성
sns.boxplot(data=df, x='PerformanceRating', y='TrainingHours', palette='Set2')
plt.title('인사고과 등급별 직무 교육 시간 분포', fontsize=14, fontweight='bold')
plt.show()
💻 [실행 결과]
💡 시각화 차트 읽는 법 & 인사이트
- 교육 투자 시간과 우수 인사고과의 밀접한 연계: 최종 인사고과 점수가 4~5점인 고성과 직원 그룹의 주간 직무 교육 이수 시간 상자가 1~2점 저성과 집단 대비 유의미하게 우상향 포지셔닝되어 있습니다. 이는 학습 시간이 고과 성과 창출에 주요한 밑바탕이 됨을 뒷받침합니다.
Step 4: 다변수 상관관계 및 이상치 분석 (Multivariate EDA)
두 개 이상의 변수를 동시에 결합하여, 조건에 따른 수치 차이나 독립 변수와 종속 변수 간의 통계적 경향을 분석합니다.
plt.figure(figsize=(9, 6))
# 다변수 분석 그래프 생성
sns.scatterplot(data=df, x='PreScore', y='PostScore', hue='Department', palette='Set1', alpha=0.8)
plt.title('직무 교육 전후의 평가 성적 상관 분포', fontsize=14, fontweight='bold')
plt.show()
💻 [실행 결과]
💡 코드 딥다이브 & 비즈니스 통찰 (Analyst’s Insight)
- 교육 효과에 따른 역량 상승 도약선 관찰: 교육 전 점수(X축) 대비 교육 후 점수(Y축)가 전반적으로 우상향 정비례 띠를 두릅니다. 특히 거의 모든 직원의 사후 성적 점수선이 사전 점수선 대비 큰 도약 성장 궤적을 띠며, 부서별 고른 성장을 이뤄냈음을 증명합니다.
Step 5: 통계적 직관과 해석 (Statistical Logic)
💡 [대응표본 t-검정(Paired t-test)을 통한 전후 변화의 과학적 검증] 교육 프로그램 도입 전후의 역량 차이처럼 동일 대상의 2회 반복 측정 수치를 검증할 때 사용하는 표준 기법이 대응표본 t-검정(Paired t-test)입니다.
- 이는 단순히 두 집단 평균을 비교하는 일반 t-test와 달리, 개별 직원마다의 ‘사후 성적 - 사전 성적’ 편차인 차이값($D$)의 평균이 통계적으로 유의미하게 0보다 큰지 봅니다.
- 이 귀무가설 검정을 판다스 Scipy 패키지로 가동하여 t-통계량의 유의 확률(p-value)이 0.05 미만으로 떨어지면, 사내 연수가 우연한 운이 아닌 직원 성장과 역량 증진에 강력한 기여 인프라로 작동했음을 보장해 줍니다.
🎯 30분 강의 마무리 및 심화 과제
오늘 우리는 실전 데이터셋을 분석하여 판다스로 데이터를 가공 및 정제하고, 시각화를 활용하여 핵심 변수 간의 통계적 유의성을 검증했습니다. 데이터 속에서 숨겨진 패턴을 올바른 시각으로 탐색하는 능력이 데이터 사이언티스트의 가장 강력한 무기입니다.
📝 심화 과제 (Advanced Challenge)
- 역량 향상율 파생변수 생성 및 요약:
Score_Improvement = df['PostScore'] - df['PreScore']파생변수를 만들고, 부서별 평균 역량 성장률 순위를 산출해 보세요. - 교육 시간 대비 고효율 성장 직원 필터링: 교육 이수 시간이 15시간 미만으로 적음에도 불구하고 역량 성적이 20점 이상 급상승한 ‘핵심 인재’ 그룹을 코드로 찾아내 보세요.