본문 바로가기
Archive/Playground

[Playground] 이직 예측 모델 만들기 (1)

by 다람이도토리 2024. 2. 14.
https://github.com/swtaktak/playground/blob/main/data_scientist_drop_predict/ds_move_predict.ipynb

도입

이 문제를 생각하게 된 계기는 이전에 원티드 채용공고 크롤링을 통해 직접 키워드를 분석해 본 적이 있었던 경험에서 기반하였다. 회사가 어떤 사람을 뽑고 싶어할지 공고의 주요 키워드를 보는 일이었다. 그러면, 이제 enter는 봤으니, "exit"를 보면 어떨지 고려해봅시다.

문제 목표 , 데이터 확인

https://www.kaggle.com/datasets/arashnic/hr-analytics-job-change-of-data-scientists
(1) 이직에 대해 고려하고 있는 사람을 예측하기
(2) 클러스터링을 통한 인사이트 발굴
(3) 기타 추가 인사이트 찾기

변수 설명을 가져와보겠습니다.

- enrollee_id : Unique ID for candidate.
- city: City code.
- city_ development_index : Developement index of the city (scaled).
- gender: Gender of candidate
- relevent_experience: Relevant experience of candidate
- enrolled_university: Type of University course enrolled if any
- education_level: Education level of candidate
- major_discipline :Education major discipline of candidate
- experience: Candidate total experience in years
- company_size: No of employees in current employer's company
- company_type : Type of current employer
- last_new_job: Difference in years between previous job and current job
- training_hours: training hours completed
- target: 0 – Not looking for job change, 1 – Looking for a job change

이번 데이터의 가장 난점은...

결측치가 뭉탱이로 너무 많다는 것입나다. 날려도 되지만, 이번에는 날리지 않고 최대한 채워봅시다. 하지만 그 전에 또 다른 문제가 있습니다.

데이터가 불균형합니다! 이 문제도 해결해야 할 대상입니다. 우선은, 변수들이 정말 유의미하게 사용될수는 있는지 통계검정을 잠깐 진행해봅시다.

이 변수들 다 유의미해?

이 글에서 다 하기에는 너무 TMI이므로 몇가지만 봅시다.

City_development_index

도시의 발전도가 과연 이직 결심에 영향을 줄까요?, 정확히는 이직 결심 여부가 있는 사람들과 없는 사람들이 다니는 회사의 발전도에는 차이가 있을까요? 이를 검정해봅시다.

- 귀무가설 : 이직 희망자들의 도시 발전도 평균과 이직 비희망자의 도시 발전도 평균에는 차이가 없다.
- 대립가설 : 이직 희망자들의 도시 발전도 평균과 이직 비희망자의 도시 발전도 평균에는 차이가 있다.

사실, 그림만 봐도 그 큰 차이가 느껴집니다. 실제로 t-test를 해봅시다.? 잠깐만 정규성은요?

print(stats.shapiro(train_df_move['city_development_index']))
print(stats.shapiro(train_df_notmove['city_development_index']))

target 0과 1을 분리하여, 발전도 수치의 정규성을 검증해보면

네, 정규성부터 깨집니다. 비모수검정법을 써야겠습니다.

결과는 유의미한 차이가 존재한다! 라고 말할 수 있겠네요. 시각화 결과만 봐도, 이직을 희망하는 사람들이 근무하는 회사 도시의 발전도가 더 낮다고 생각할만 합니다. 

Gender

성별도 고려해봐야 할 요소입니다. 여성의 경우는 출산의 문제도 걸리니까, 충분히 고려해볼만한 문제입니다. 허나 문제는 성별 데이터에는 결측치도 있고 데이터를 좀 탐색해보면 Other라고 성별을 알 수 없는 데이터가 존재합니다. 성별의 미공개까지 고려하여, 데이터를 검정해봅시다. 우선 집단 내에 유의미한 차이 자체가 존재하는지는?

유의수준 5% 정도 하에서, 집단간 이직 고려 여부에 유의미한 차이가 있다고 말할 수 있겠군요, 근데 남성과 여성은요?

4% 정도의 차이입니다. 위의 데이터는 여성의 데이터, 아래 데이터는 남성의 데이터입니다. 실제 대부분의 회사 규모를 생각해보면 적지 않은 인원의 차이일 것이므로 이 차이는 유의미하다고 봐야 할 것입니다. 나머지 데이터는 코드를 참고하고 우선 이야기를 넘겨봅시다.

결측치, 결측치를 채우자.

결측치를 채워야 합니다. 근데 문제는 무작정 없다라고 하기에는 곤란합니다. 예를 들어 봅시다.

예를 들어 전공의 결측치를 살펴봅시다.

그냥 전공이 없다라고 채우기엔, Gradute  즉, 학부 졸업을 했는데 전공이 없을리가 없죠. 이런 경우는 전공을 알 수 없지만 일정 학위 이상의 경우 Other로 채워 전공이 없는 케이스와 구분을 해야 할 것입니다. 이런식의 전처리를 모두 진행해줍시다.  추가로 하나만 더 살펴봅시다.

경력의 결측치입니다. 그러나, 최근 직장 근무 경험이 있는 경우가 있습니다. 이 경우는 앞의 직장의 정보는 없으나, 최근 직장 근무 경험의 수치를 그대로 가져올 수 있을 것입니다. 이도저도 정보가 없을 경우에는 정말 0을 쓰면 되겠죠

def get_exp(exp, last):
    if exp == exp:
        return exp
    else:
        if last == last:
            if last in ['1', '2', '3', '4']:
                return last
            elif last == '>4':
                return '5'
            elif last == 'never':
                return '0'
        else:
            return '0'

이런 식으로 처리를 모두 해줍시다.

이후 범주형 변수는 0-1 처리를 해주고 필요없는 column은 지워줍시다.

Baseline 만들기

Baseline은 데이터를 8:2로 나눠서 lightgbm으로 학습시키겠습니다. 

평가 지표는 f1-score로 결정하였습니다.  이직 생각이 있는 직원이라고 예측한 직원들이 실제 이직을 고려하지 않고 있다면 비용 측면의 손실, 이직 생각이 있는 직원을 많이 못 찾는다면 인력 손실의 문제가 발생하므로 두 가지 모두를 고려할 수 있는 f1-score가 합리적입니다. 

f1 score가 0.6으로 아직은 여러 개선이 가능해 보입니다. baseline model을 좀 더 살펴봅시다. 어떤 변수를 중요하게 분류에 사용하고 있을까요?

교육 시간, 도시 발전도, 최근 근무 년수가 가장 중요한 3개의 변수 입니다. 이 이외 변수들의 중요도는 낮아보입니다. 조금만 생각해보면,

- 이전 직장에서 오래 있을 경우 당연히 이직 확률이 올라갈 것이다. 이는 당연하다
- 도시가 낙후되었을 경우 이직을 생각할 가능성이 높다.
- 충분한 직무 교육을 받았을 경우 더 좋은 조건의 회사로 이직할 가능성이 높다.
- 관련 경험의 유무가 그렇게 이직에 영향을 줄 거 같지는 않다. (경험상, 사실 오히려 다른 직무 전환일때..)
- 특정 년차에서 이직이 많이 일어날 수 있다. 

예상밖의 사항은 변수 중요도에 여성에 대해 물어보는 변수가 상위 중요도에 없다는 점입니다.이것은 어떻게 된 일일까요?, 그리고 각 변수는 이직 가능성에 어떤 영향을 주고 있을까요?

그리고 이렇게 0-1만 보면 끝일까요?  2편에서 모델을 좀 더 해석하고 데이터에 해당하는 사람들을 분류해보는 문제들을 생각해보겠습니다.