跳至主要内容

用 Python 预测员工流失

分析员工流失。找出员工离职的原因,并学习如何预测哪些员工会离职。
· 14分钟 阅读

使用 AI 探索

过去,人们大多关注“比率”,例如离职率和留任率。人力资源经理计算历史比率,并尝试使用数据仓库工具预测未来比率。这些比率展示了流失的总体影响,但这只是半幅图景。另一种方法是,在总体数据之外,同时关注个体记录。

关于客户流失的案例研究非常多。在客户流失中,您可以预测客户何时、以及哪些客户会停止购买。员工流失与客户流失类似,但重点放在员工而非客户身上。在这里,您可以预测员工何时、以及哪些员工会终止服务。员工流失代价高昂,哪怕是渐进式的改进也能带来显著效果。它将帮助我们制定更好的留任计划并提升员工满意度。

员工流失分析

employee churn analysis in python


员工流失可以被定义为公司或组织的人才资产的“泄漏”或离开。换句话说,员工离开组织即称为流失。另一种定义是,当一个群体中的成员离开该群体,即为流失。

研究发现,员工流失会受到年龄、任期、薪酬、工作满意度、工资、工作条件、成长潜力以及员工对公平性的感知等因素的影响。其他一些变量,如年龄、性别、种族、教育程度和婚姻状况,也是预测员工流失的重要因素。在某些情况下,具备小众技能的员工更难替代,这会影响现有员工的在岗工作与生产力。招聘替代员工会产生成本,例如招聘成本和培训成本。此外,新员工需要时间才能在技术或业务专业知识方面达到老员工的类似水平。各组织正通过应用机器学习技术预测员工流失,从而帮助他们采取必要的措施。

以下要点有助于您更好地理解员工与客户流失:

  • 企业可以选择招聘哪些员工,而在市场营销中,您并不能选择您的客户。

  • 员工是公司对外的形象代表,并且所有公司产出都是由员工共同完成的。

  • 失去客户会影响营收和品牌形象。与留住现有客户相比,获取新客户更难且更昂贵。员工流失对公司和组织同样“痛苦”,因为寻找与培训替代者需要投入时间和精力。

员工流失相比客户流失有其独特的动态特征。它能帮助我们设计更好的员工留任计划并提升员工满意度。数据科学算法可以预测未来的流失。


探索性分析


探索性数据分析是分析的初始过程,您可以通过描述性统计与可视化来概括数据特征,如模式、趋势、离群点以及进行假设检验。

导入模块

#import modules
import pandas  # for dataframes
import matplotlib.pyplot as plt # for plotting graphs
import seaborn as sns # for plotting graphs
% matplotlib inline


加载数据集

首先使用 pandas 的 read CSV 函数加载所需的人力资源数据集。您可以从此链接下载数据。

data=pandas.read_csv('HR_comma_sep.csv')
data.head()

loading employee churn dataset

  • 此处给定数据集中,原始数据以逗号分隔符(“ , ”)分隔。
  • 您可以使用 pandas 库的 “head()” 函数更仔细地查看数据,它会返回前五条观测记录。
  • 类似地,“tail()” 会返回最后五条观测记录。

data.tail()

hr dataset


加载数据集后,您可能希望进一步了解数据。可以使用 info() 查看属性名称与数据类型。

 
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 14,999 entries, 0 to 14,998
Data columns (total 10 columns):
satisfaction_level       14999 non-null float64
last_evaluation          14999 non-null float64
number_project           14999 non-null int64
average_montly_hours     14999 non-null int64
time_spend_company       14999 non-null int64
Work_accident            14999 non-null int64
left                     14999 non-null int64
promotion_last_5years    14999 non-null int64
Departments              14999 non-null object
salary                   14999 non-null object
dtypes: float64(2), int64(6), object(2)
memory usage: 1.1+ MB
  • 该数据集包含 14,999 条样本与 10 个属性(6 个整数、2 个浮点、2 个对象)。
  • 没有变量列存在空/缺失值。


您可以按如下方式详细描述这 10 个属性:

  • satisfaction_level:员工满意度,范围 0-1。
  • last_evaluation:雇主对员工的绩效评估,同样范围 0-1。
  • number_projects:分配给员工的项目数量。
  • average_monthly_hours:员工每月平均工作小时数。
  • time_spent_company:在公司的工作年限,即员工在公司的年数。
  • work_accident:员工是否发生过工伤事故。
  • promotion_last_5years:员工在过去 5 年内是否获得过晋升。
  • Departments:员工所在部门/事业部。
  • Salary:员工薪资水平,如低、中和高。
  • left:员工是否已离开公司。


进入数据洞察

在给定数据集中,员工分为两类:留下的和离开的。因此,您可以将数据分成两组并比较其特征。这里,您可以使用 groupby() 和 mean() 函数计算两组的均值。

left = data.groupby('left')
left.mean()

data grouped by mean


由此可见,离开公司的员工满意度较低、晋升率较低、薪资较低,且相比留下的员工工作时间更长。

pandas 中的 describe() 函数可便捷地获取各种汇总统计信息。该函数返回数据的计数、均值、标准差、最小值与最大值,以及分位数。

 
data.describe()

data with describe panda function


数据可视化

离职员工数

我们来看看有多少员工离开了?

这里,您可以使用 Matplotlib 绘制条形图。条形图适用于展示离散变量的计数。

left_count=data.groupby('left').count()
plt.bar(left_count.index.values, left_count['satisfaction_level'])
plt.xlabel('Employees Left Company')
plt.ylabel('Number of Employees')
plt.show()

employees left graphy with matplotlib
 
data.left.value_counts()
0    11428
1     3571
Name: left, dtype: int64


可以看到,在约 15,000 名员工中,离职 3,571 人,留任 11,428 人。离职员工数约占总人数的 23%。

项目数量

同样,您也可以绘制条形图来统计有多少员工被分配到不同数量的项目上。

num_projects=data.groupby('number_project').count()
plt.bar(num_projects.index.values, num_projects['satisfaction_level'])
plt.xlabel('Number of Projects')
plt.ylabel('Number of Employees')
plt.show()

number of projects with matplotlib
  • 大多数员工承担 3-5 个项目。

在公司工作年限

同样,您可以绘制条形图,根据员工的工作年限统计员工数量。

time_spent=data.groupby('time_spend_company').count()
plt.bar(time_spent.index.values, time_spent['satisfaction_level'])
plt.xlabel('Number of Years Spend in Company')
plt.ylabel('Number of Employees')
plt.show()

time spent with company graph with matplotlib

大多数员工的工作年限在 2-4 年之间。此外,3 年与 4 年经验员工之间存在明显差距。

使用 Seaborn 的子图

逐一分析特征会比较耗时。更好的做法是使用 Seaborn 库,通过子图一次性绘制所有图形。

features=['number_project','time_spend_company','Work_accident','left', 'promotion_last_5years','Departments ','salary']
fig=plt.subplots(figsize=(10,15))
for i, j in enumerate(features):
    plt.subplot(4, 2, i+1)
    plt.subplots_adjust(hspace = 1.0)
    sns.countplot(x=j,data = data)
    plt.xticks(rotation=90)
    plt.title("No. of employee")

employee graphs with seaborn

从上述可视化中,您可以观察到:

  • 大多数员工承担 3-5 个项目。
  • 3 年与 4 年经验员工之间存在巨大落差。
  • 离职员工约占总人数的 23%。
  • 过去 5 年内获得晋升的员工比例很低。
  • 销售部门员工数量最多,其次是技术与支持部门。
  • 大多数员工的薪资为中等或较低。

fig=plt.subplots(figsize=(10,15))
for i, j in enumerate(features):
    plt.subplot(4, 2, i+1)
    plt.subplots_adjust(hspace = 1.0)
    sns.countplot(x=j,data = data, hue='left')
    plt.xticks(rotation=90)
    plt.title("No. of employee")

从上述可视化中,您可以观察到:

  • 承担项目数超过 5 个的员工更可能离职。
  • 完成 6 个和 7 个项目的员工离职较多,似乎是因为工作负荷过重。
  • 拥有 5 年经验的员工更易离职,原因是过去 5 年没有晋升;而拥有 6 年以上经验的员工因对公司更有感情,不太会离职。
  • 过去 5 年内获得晋升的员工没有离职;也就是说,离职者在过去 5 年内都未获得晋升。


数据分析与可视化小结:

以下特征对员工离职的影响最大:

  • 晋升:如果员工在过去 5 年没有获得晋升,他们更可能辞职。
  • 在职年限:三年节点似乎是员工职业生涯中的关键点,很多人在三年左右离职。另一个重要节点是第六年,员工极不可能离职。
  • 项目数量:员工参与度是影响离职的另一个关键因素。承担 3-5 个项目的员工较不容易离职;承担更少或更多项目的员工更可能离职。
  • 薪资:离职员工大多集中在中低薪资群体。


聚类分析:


让我们找出离职员工的分组。您会注意到,影响员工去留的最重要因素是满意度与绩效。因此,我们使用聚类分析将他们分组。

#import module
from sklearn.cluster import KMeans
# Filter data
left_emp =  data[['satisfaction_level', 'last_evaluation']][data.left == 1]
# Create groups using K-means clustering.
kmeans = KMeans(n_clusters = 3, random_state = 0).fit(left_emp)
# Add new column "label" annd assign cluster labels.
left_emp['label'] = kmeans.labels_
# Draw scatter plot
plt.scatter(left_emp['satisfaction_level'], left_emp['last_evaluation'], c=left_emp['label'],cmap='Accent')
plt.xlabel('Satisfaction Level')
plt.ylabel('Last Evaluation')
plt.title('3 Clusters of employees who left')
plt.show()

cluster analysis for employee analysis


离开公司的员工可分为三类:

  • 高满意度与高评估(图中以绿色阴影表示),也可称为“赢家”。
  • 低满意度与高评估(图中以蓝色阴影表示),也可称为“受挫者”。
  • 中等满意度与中等评估(图中以灰色阴影表示),也可称为“不匹配”。


构建预测模型


数据预处理

许多机器学习算法需要数值型输入数据,因此需要将分类列表示为数值列。

为对这些数据进行编码,您可以将每个取值映射为一个数字。例如,Salary 列的取值可表示为 low:0、medium:1、high:2。

此过程称为标签编码,sklearn 可使用 LabelEncoder 为您便捷完成。

# Import LabelEncoder
from sklearn import preprocessing
#creating labelEncoder
le = preprocessing.LabelEncoder()
# Converting string labels into numbers.
data['salary']=le.fit_transform(data['salary'])
data['Departments ']=le.fit_transform(data['Departments '])


此处,您导入了 preprocessing 模块并创建了 Label Encoder 对象。使用该 LabelEncoder 对象,您对 "salary" 与 "Departments " 列进行了拟合与转换,将其转为数值列。

划分训练集与测试集

为了评估模型性能,将数据集划分为训练集与测试集是一个良好策略。

让我们使用 train_test_split() 函数划分数据集。您需要传入 3 个参数:特征、目标与测试集大小。此外,您可以使用 random_state 随机选择记录。

#Spliting data into Feature and
X=data[['satisfaction_level', 'last_evaluation', 'number_project',
       'average_montly_hours', 'time_spend_company', 'Work_accident',
       'promotion_last_5years', 'Departments ', 'salary']]
y=data['left']
# Import train_test_split function
from sklearn.model_selection import train_test_split

# Split dataset into training set and test set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)  # 70% training and 30% test


此处,数据集按 70:30 的比例拆分。即 70% 的数据用于模型训练,30% 用于模型测试。

模型构建

让我们构建一个员工流失预测模型。

这里,您将使用梯度提升分类器来预测流失。

首先,导入 GradientBoostingClassifier 模块,并使用 GradientBoostingClassifier() 函数创建梯度提升分类器对象。

然后,使用 fit() 在训练集上拟合模型,并使用 predict() 在测试集上进行预测。

#Import Gradient Boosting Classifier model
from sklearn.ensemble import GradientBoostingClassifier

#Create Gradient Boosting Classifier
gb = GradientBoostingClassifier()

#Train the model using the training sets
gb.fit(X_train, y_train)

#Predict the response for test dataset
y_pred = gb.predict(X_test)


评估模型性能

 
#Import scikit-learn metrics module for accuracy calculation
from sklearn import metrics
# Model Accuracy, how often is the classifier correct?
print("Accuracy:",metrics.accuracy_score(y_test, y_pred))
# Model Precision
print("Precision:",metrics.precision_score(y_test, y_pred))
# Model Recall
print("Recall:",metrics.recall_score(y_test, y_pred))
Accuracy: 0.971555555556
Precision: 0.958252427184
Recall: 0.920708955224

不错,分类准确率达到 97%,可视为较高的准确度。

精确率(Precision):强调“精准”。换言之,当模型做出预测时,它有多常是正确的。在您的预测中,当梯度提升模型预测某位员工将要离职时,该员工有 95% 的概率确实会离职。

召回率(Recall):如果测试集中存在离职员工,您的梯度提升模型有 92% 的概率将其识别出来。

结论


恭喜您读完本教程!

在本教程中,您学习了什么是员工流失、它与客户流失有何不同,使用 matplotlib 和 seaborn 对员工流失数据集进行探索性数据分析与可视化,以及使用 Python scikit-learn 包进行建模与评估。

期待您的反馈与问题。您可以通过留言提问,我会尽力解答。

如果您希望进一步学习 Python,欢迎查看 DataCamp 的 中级 Python 数据科学课程。

主题