import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from statsmodels.graphics.mosaicplot import mosaic
from scipy import stats as spst
import statsmodels.api as sm
# data data
path = "https://raw.githubusercontent.com/DA4BAM/dataset/master/Attrition_NA.CSV"
data = pd.read_csv(path)
data.drop(['EducationField', 'Education','JobInvolvement', 'StockOptionLevel', 'BusinessTravel','YearsWithCurrManager'
,'YearsInCurrentRole','JobRole', 'Department','EmployeeNumber','EnvironmentSatisfaction','TrainingTimesLastYear','YearsAtCompany']
, axis = 1, inplace = True)
data['Attrition'] = np.where(data['Attrition']=='Yes', 1, 0)
data.head(10)
Attrition | Age | DistanceFromHome | Gender | JobSatisfaction | MaritalStatus | MonthlyIncome | NumCompaniesWorked | OverTime | PercentSalaryHike | RelationshipSatisfaction | TotalWorkingYears | WorkLifeBalance | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 33 | 7.0 | Male | 3 | Married | 11691 | 0.0 | No | 11 | 4 | 14 | 4 |
1 | 0 | 35 | 18.0 | Male | 4 | Single | 9362 | 2.0 | No | 11 | 3 | 10 | 3 |
2 | 0 | 42 | 6.0 | Male | 1 | Married | 13348 | 9.0 | No | 13 | 2 | 18 | 4 |
3 | 0 | 46 | 2.0 | Female | 1 | Married | 17048 | 8.0 | No | 23 | 1 | 28 | 3 |
4 | 0 | 39 | NaN | Male | 4 | Divorced | 4127 | 2.0 | No | 18 | 4 | 7 | 3 |
5 | 1 | 22 | 4.0 | Male | 3 | Single | 3894 | 5.0 | No | 16 | 3 | 4 | 3 |
6 | 0 | 24 | 21.0 | Male | 1 | Divorced | 2296 | 0.0 | No | 14 | 2 | 2 | 3 |
7 | 0 | 34 | 8.0 | Male | 3 | Married | 4404 | 2.0 | No | 12 | 1 | 6 | 4 |
8 | 0 | 30 | 20.0 | Male | 1 | Married | 9957 | 0.0 | No | 15 | 3 | 7 | 2 |
9 | 0 | 26 | 6.0 | Female | 4 | Married | 2659 | 1.0 | Yes | 13 | 3 | 3 | 3 |
구분 | 변수 명 | 내용 | type | 비고 |
---|---|---|---|---|
Target | Attrition | 이직여부, Yes , No | 범주 | 1- 이직, 0- 잔류 |
feature | Age | 나이 | 숫자 | |
feature | DistanceFromHome | 집-직장 거리 | 숫자 | 마일 |
feature | Gender | 성별 | 범주 | Male, Female |
feature | JobSatisfaction | 직무 만족도 | 범주 | 1 Low, 2 Medium, 3 High, 4 Very High |
feature | MaritalStatus | 결혼상태 | 범주 | Single, Married, Divorced |
feature | MonthlyIncome | 월급 | 숫자 | 달러 |
feature | NumCompaniesWorked | 입사 전 근무한 회사 수 | 숫자 | 0 - 우리회사가 첫 직장 |
feature | RelationshipSatisfaction | 동료와의 관계 | 범주 | 1 Low, 2 Medium, 3 High, 4 Very High |
feature | OverTime | 야근여부 | 범주 | Yes, No |
feature | PercentSalaryHike | 전년대비 급여인상율 | 숫자 | % |
feature | TotalWorkingYears | 총 경력 연수 | 숫자 | |
feature | WorkLifeBalance | 워라밸. 일-삶 균형도 | 범주 | 1 Bad, 2 Good, 3 Better, 4 Best |
① 변수의 비즈니스 의미
② 숫자? 범주?
③ NaN 존재 여부 및 조치 방안
④ 기초통계량
⑤ 분포
⑥ 위 정보로부터 파악한 내용(비즈니스!) 정리
⑦ 추가 분석해볼 사항 도출
target = 'Attrition'
feature = 'Gender'
① 교차표(pd.crosstab())
pd.crosstab(data[target], data[feature])
Gender | Female | Male |
---|---|---|
Attrition | ||
0 | 421 | 629 |
1 | 69 | 131 |
② 시각화( Stacked Bar, Mosaic)
temp = pd.crosstab(data[target], data[feature], normalize = 'index')
print(temp)
temp.plot.bar(stacked=True)
plt.axhline(1 - data[target].mean(), color = 'r')
plt.show()
Gender Female Male
Attrition
0 0.400952 0.599048
1 0.345000 0.655000
mosaic(data, [feature,target])
plt.axhline(1 - data[target].mean(), color = 'r')
plt.show()
시각화를 통해 파악한 내용을 적어 봅시다.
남성이 여성보다 이직률이 높음을 알 수 있음.
전체 직원의 성별을 비교해보면 남성 근무자가 더 많음을 알 수 있음.
③ 가설검정(카이제곱검정)
# 집계
table = pd.crosstab(data[target], data[feature])
print('교차표\n', table)
print('-' * 100)
# 카이제곱검정
result = spst.chi2_contingency(table)
print('카이제곱통계량', result[0])
print('p-value', result[1])
print('기대빈도\n',result[3])
교차표
Gender Female Male
Attrition
0 421 629
1 69 131
----------------------------------------------------------------------------------------------------
카이제곱통계량 1.9782495940105371
p-value 0.15957492990528155
기대빈도
[[411.6 638.4]
[ 78.4 121.6]]
④ 시각화와 가설검정을 통해서 파악한 내용을 적어 봅시다.
feature = 'MaritalStatus'
① 교차표(pd.crosstab())
pd.crosstab(data[feature], data[target])
Attrition | 0 | 1 |
---|---|---|
MaritalStatus | ||
Divorced | 253 | 23 |
Married | 501 | 69 |
Single | 296 | 108 |
② 시각화( Stacked Bar, Mosaic)
temp = pd.crosstab(data[feature], data[target], normalize = 'index')
print(temp)
temp.plot.bar(stacked = True)
plt.axhline(1 - data[target].mean(), color = 'r')
plt.show()
Attrition 0 1
MaritalStatus
Divorced 0.916667 0.083333
Married 0.878947 0.121053
Single 0.732673 0.267327
mosaic(data, [feature,target])
plt.axhline(1 - data[target].mean(), color = 'r')
plt.show()
시각화를 통해 파악한 내용을 적어 봅시다.
③ 가설검정(카이제곱검정)
# 집계
table = pd.crosstab(data[feature], data[target])
print('교차표\n', table)
print('-' * 100)
# 카이제곱검정
result = spst.chi2_contingency(table)
print('카이제곱통계량', result[0])
print('p-value', result[1])
print('기대빈도\n',result[3])
교차표
Attrition 0 1
MaritalStatus
Divorced 253 23
Married 501 69
Single 296 108
----------------------------------------------------------------------------------------------------
카이제곱통계량 53.12935546374186
p-value 2.9047385436211595e-12
기대빈도
[[231.84 44.16]
[478.8 91.2 ]
[339.36 64.64]]
④ 시각화와 가설검정을 통해서 파악한 내용을 적어 봅시다.
feature = 'JobSatisfaction'
① 교차표(pd.crosstab())
pd.crosstab(data[feature], data[target])
Attrition | 0 | 1 |
---|---|---|
JobSatisfaction | ||
1 | 197 | 53 |
2 | 196 | 39 |
3 | 308 | 60 |
4 | 349 | 48 |
② 시각화( Stacked Bar, Mosaic)
temp = pd.crosstab(data[feature], data[target], normalize = 'index')
print(temp)
temp.plot.bar(stacked=True)
plt.axhline(1 - data[target].mean(), color = 'r')
plt.show()
Attrition 0 1
JobSatisfaction
1 0.788000 0.212000
2 0.834043 0.165957
3 0.836957 0.163043
4 0.879093 0.120907
mosaic(data, [feature,target])
plt.axhline(1 - data[target].mean(), color = 'r')
plt.show()
시각화를 통해 파악한 내용을 적어 봅시다.
③ 가설검정(카이제곱검정)
# 집계
table = pd.crosstab(data[feature], data[target])
print('교차표\n', table)
print('-' * 100)
# 카이제곱검정
result = spst.chi2_contingency(table)
print('카이제곱통계량', result[0])
print('p-value', result[1])
print('기대빈도\n',result[3])
교차표
Attrition 0 1
JobSatisfaction
1 197 53
2 196 39
3 308 60
4 349 48
----------------------------------------------------------------------------------------------------
카이제곱통계량 9.63151465436614
p-value 0.021972649369306214
기대빈도
[[210. 40. ]
[197.4 37.6 ]
[309.12 58.88]
[333.48 63.52]]
④ 시각화와 가설검정을 통해서 파악한 내용을 적어 봅시다.
feature = 'Age'
① 그래프 : histogram, densityplot
sns.histplot(x=feature, data = data, hue = target)
plt.show()
sns.kdeplot(x=feature, data = data, hue = target, common_norm = False)
plt.show()
시각화를 통해 파악한 내용을 적어 봅시다.
연령대에 따른 이직률의 관계가 보임
- 20대 중반부터 30대 중반까지의 이직률이 높게 분포해 있음을 알 수 있음.
- 40대 역시 전후 나이대보다 높은 이직률을 보임.
- 이후 높은 연령대에서의 이직률은 점차 감소함
② 수치화 : 로지스틱회귀
model = sm.Logit(data[target], data[feature])
result = model.fit()
print(result.pvalues)
Optimization terminated successfully.
Current function value: 0.424660
Iterations 5
Age 4.667821e-100
dtype: float64
③ 시각화와 수치화를 통해 파악한 내용을 적어 봅시다.
feature = 'DistanceFromHome'
temp = data.loc[data[feature].notnull()]
① 그래프 : histogram, densityplot
sns.histplot(x=feature, data = temp, hue = target)
plt.show()
sns.kdeplot(x=feature, data = temp, hue = target, common_norm = False)
plt.show()
시각화를 통해 파악한 내용을 적어 봅시다.
② 수치화 : 로지스틱회귀
temp = data.loc[data[feature].notnull()]
model = sm.Logit(temp[target], temp[feature])
result = model.fit()
print(result.pvalues)
Optimization terminated successfully.
Current function value: 0.568793
Iterations 6
DistanceFromHome 2.694280e-44
dtype: float64
feature = 'MonthlyIncome'
① 그래프 : histogram, densityplot
sns.histplot(x = feature, data = data, hue = target)
plt.show()
sns.kdeplot(x = feature, data = data, hue = target, common_norm = False)
plt.show()
시각화를 통해 파악한 내용을 적어 봅시다.
② 수치화 : 로지스틱회귀
model = sm.Logit(data[target], data[feature])
result = model.fit()
print(result.pvalues)
Optimization terminated successfully.
Current function value: 0.437401
Iterations 6
MonthlyIncome 1.922717e-71
dtype: float64
③ 시각화와 수치화를 통해 파악한 내용을 적어 봅시다.
MaritalStatus, Age, DistanceFromHome, MonthlyIncome
Gender, JobSatisfaction