IBM HR Analytics об убытке и производительности сотрудников с использованием классификатора случайного леса

Опубликовано: 4 Января, 2022

Убыль - это проблема, которая затрагивает все предприятия, независимо от географии, отрасли и размера компании. Это серьезная проблема для организации, и прогнозирование текучести кадров находится в авангарде потребностей отдела кадров (HR) во многих организациях. Организации несут огромные расходы, связанные с текучестью кадров. Благодаря достижениям в области машинного обучения и науки о данных можно прогнозировать увольнение сотрудников, и мы будем прогнозировать, используя алгоритм случайного лесного классификатора.

Набор данных: набор данных, который публикуется отделом кадров IBM, доступен на Kaggle.

Код: реализация алгоритма классификатора случайного леса для классификации.

Код: загрузка библиотек

Python3

# performing linear algebra
import numpy as np
# data processing
import pandas as pd
# visualisation
import matplotlib.pyplot as plt
import seaborn as sns % matplotlib inline

Код: Импорт набора данных

Python3

dataset = pd.read_csv( "WA_Fn-UseC_-HR-Employee-Attrition.csv" )
print (dataset.head)

Выход :

Код: информация о наборе данных

Python3

dataset.info()

Выход :

 RangeIndex: 1470 записей, от 0 до 1469
Столбцы данных (всего 35 столбцов):
Возраст 1470 ненулевой int64
Истощение 1470 ненулевой объект
BusinessTravel 1470 ненулевой объект
DailyRate 1470 ненулевое значение int64
Ненулевой объект отдела 1470
DistanceFromHome 1470 ненулевое значение int64
Образование 1470 непустое int64
EducationField 1470 ненулевой объект
EmployeeCount 1470 ненулевое значение int64
EmployeeNumber 1470 ненулевое значение int64
EnvironmentSatisfaction 1470 ненулевое значение int64
Пол 1470 ненулевой объект
HourlyRate 1470 ненулевое значение int64
JobInvolvement 1470 ненулевое значение int64
JobLevel 1470 ненулевое значение int64
JobRole 1470 ненулевой объект
JobSatisfaction 1470 ненулевое значение int64
MaritalStatus 1470 ненулевой объект
Ежемесячный доход 1470 ненулевое значение int64
MonthlyRate 1470 ненулевое значение int64
NumCompaniesWorked 1470 ненулевых int64
Более 18 1470 ненулевых объектов
OverTime 1470 ненулевой объект
PercentSalaryHike 1470 ненулевое значение int64
PerformanceRating 1470 ненулевое значение int64
RelationshipSatisfaction 1470 ненулевое значение int64
StandardHours 1470 ненулевое значение int64
StockOptionLevel 1470 ненулевое значение int64
TotalWorkingYears 1470 ненулевое int64
TrainingTimesLastYear 1470 ненулевое значение int64
WorkLifeBalance 1470 ненулевое значение int64
YearsAtCompany 1470 ненулевое значение int64
YearsInCurrentRole 1470 ненулевое значение int64
YearsSinceLastPromotion 1470 ненулевое значение int64
YearsWithCurrManager 1470 ненулевое значение int64
dtypes: int64 (26), объект (9)
использование памяти: 402,0+ КБ

Код: визуализация данных

Python3

# heatmap to check the missing value
plt.figure(figsize =(10, 4))
sns.heatmap(dataset.isnull(), 
            yticklabels = False,
            cbar = False,
            cmap ="viridis")

Выход:

Итак, мы видим, что в наборе данных нет пропущенных значений. Это проблема двоичной классификации, поэтому распределение экземпляров между двумя классами показано ниже:

Код:

Python3

sns.set_style( 'darkgrid' )
sns.countplot(x = 'Attrition' ,
data = dataset)

Выход:

Код:

Python3

sns.lmplot(x = 'Age' ,
y = 'DailyRate' ,
hue = 'Attrition' ,
data = dataset)

Выход:

Код:

Python3

plt.figure(figsize = ( 10 , 6 ))
sns.boxplot(y = 'MonthlyIncome' ,
x = 'Attrition' ,
data = dataset)

Выход:

Код: предварительная обработка данных

В наборе данных есть 4 нерелевантных столбца, то есть: EmployeeCount, EmployeeNumber, Over18 и StandardHour. Итак, мы должны удалить их для большей точности.

Python3

dataset.drop( 'EmployeeCount' ,
axis = 1 ,
inplace = True )
dataset.drop( 'StandardHours' ,
axis = 1 ,
inplace = True )
dataset.drop( 'EmployeeNumber' ,
axis = 1 ,
inplace = True )
dataset.drop( 'Over18' ,
axis = 1 ,
inplace = True )
print (dataset.shape)

Выход:

 (1470, 31)

Итак, мы удалили ненужный столбец.

Код: входные и выходные данные

Python3

y = dataset.iloc[:, 1 ]
X = dataset
X.drop( 'Attrition' ,
axis = 1 ,
inplace = True )

Код: кодирование метки

Python3

from sklearn.preprocessing import LabelEncoder
lb = LabelEncoder()
y = lb.fit_transform(y)

В наборе данных есть 7 категориальных данных, поэтому мы должны изменить их на данные типа int, т.е. мы должны создать 7 фиктивных переменных для большей точности.

Код: создание фиктивной переменной

Python3

dum_BusinessTravel = pd.get_dummies(dataset[ 'BusinessTravel' ],
prefix = 'BusinessTravel' )
dum_Department = pd.get_dummies(dataset[ 'Department' ],
prefix = 'Department' )
dum_EducationField = pd.get_dummies(dataset[ 'EducationField' ],
prefix = 'EducationField' )
dum_Gender = pd.get_dummies(dataset[ 'Gender' ],
prefix = 'Gender' , drop_first = True )
dum_JobRole = pd.get_dummies(dataset[ 'JobRole' ],
prefix = 'JobRole' )
dum_MaritalStatus = pd.get_dummies(dataset[ 'MaritalStatus' ],
prefix = 'MaritalStatus' )
dum_OverTime = pd.get_dummies(dataset[ 'OverTime' ],
prefix = 'OverTime' , drop_first = True )
# Adding these dummy variable to input X
X = pd.concat([x, dum_BusinessTravel, dum_Department,
dum_EducationField, dum_Gender, dum_JobRole,
dum_MaritalStatus, dum_OverTime], axis = 1 )
# Removing the categorical data
X.drop([ 'BusinessTravel' , 'Department' , 'EducationField' ,
'Gender' , 'JobRole' , 'MaritalStatus' , 'OverTime' ],
axis = 1 , inplace = True )
print (X.shape)
print (y.shape)

Выход:

 (1470, 49)
(1470,)

Код: разделение данных на обучение и тестирование

Python3

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size = 0.25 , random_state = 40 )

Итак, предварительная обработка завершена, теперь нам нужно применить классификатор случайного леса к набору данных.

Код: исполнение модели

Python3

from sklearn.model_selection import cross_val_predict, cross_val_score
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators = 10 ,
criterion = 'entropy' )
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)
def print_score(clf, X_train, y_train,
X_test, y_test,
train = True ):
if train:
print ( "Train Result:" )
print ( "------------" )
print ( "Classification Report: {} " . format (classification_report(
y_train, clf.predict(X_train))))
print ( "Confusion Matrix: {} " . format (confusion_matrix(
y_train, clf.predict(X_train))))
res = cross_val_score(clf, X_train, y_train,
cv = 10 , scoring = 'accuracy' )
print ( "Average Accuracy: {0:.4f}" . format (np.mean(res)))
print ( "Accuracy SD: {0:.4f}" . format (np.std(res)))
print ( "----------------------------------------------------------" )
elif train = = False :
print ( "Test Result:" )
print ( "-----------" )
print ( "Classification Report: {} " . format (
classification_report(y_test, clf.predict(X_test))))
print ( "Confusion Matrix: {} " . format (
confusion_matrix(y_test, clf.predict(X_test))))
print ( "accuracy score: {0:.4f} " . format (
accuracy_score(y_test, clf.predict(X_test))))
print ( "-----------------------------------------------------------" )
print_score(rf, X_train, y_train,
X_test, y_test,
train = True )
print_score(rf, X_train, y_train,
X_test, y_test,
train = False )

Выход:

 Результат поезда:
------------
Классификационный отчет: 
               точный отзыв поддержка f1-score

           0 0,98 1,00 0,99 988
           1 1,00 0,90 0,95 188

    точность 0,98 1176
   макрос ср. 0,99 0,95 0,97 1176
средневзвешенная 0,98 0,98 0,98 1176


Матрица неточностей: 
 [[988 0]
 [19 169]]

Средняя точность: 0,8520
Стандартное отклонение точности: 0,0122
-------------------------------------------------- --------
Результат испытаний:
-----------
Классификационный отчет: 
               точный отзыв поддержка f1-score

           0 0,86 0,98 0,92 245
           1 0,71 0,20 0,32 49

    точность 0,85 294
   макрос среднем 0,79 0,59 0,62 294
средневзвешенная 0,84 0,85 0,82 294


Матрица неточностей: 
 [[241 4]
 [39 10]]

оценка точности: 0,8537

-------------------------------------------------- ---------

Код: Ключевые особенности для определения результата

Python3

pd.Series(rf.feature_importances_,
index = X.columns).sort_values(ascending = False ).plot(kind = 'bar' ,
figsize = ( 14 , 6 ));

Выход:

Итак, согласно классификатору случайного леса наиболее важной функцией для прогнозирования результата является ежемесячный доход, а наименее важной функцией является jobRole_Manager .