[关闭]
@zhangyu756897669 2017-12-05T16:09:47.000000Z 字数 7363 阅读 1574

对Kaggle上的人力数据进行分析

项目


项目背景

一家大型公司想知道为什么最近一些非常好的并且有经验的员工离开了他们公司,并且希望能够员工对是否会离职进行预测。

项目数据

kaggle上数据源
https://www.kaggle.com/ludobenistant/hr-analytics-1/data

数据说明

此数据集为虚拟数据

项目步骤


  1. 获取数据, 并用python对数据进行读取
  2. 了解数据包含的内容,清洗数据, 删除无效数据, 填充空缺值
  3. 对数据进行探索分析,用相关矩阵分析对数据变量之间的相关性进行探究,用图形对变量之间的关系进行展示,并理解用什么类型的预测模型
  4. 选择用一种模型对员工是否离职进行预测, 交叉验证,检查模型的准确性,对模型进行优化
  5. 对数据分析结果进行解读:
    • 通过分析, 得出了什么结论
    • 什么因素主要导致了员工的流失
    • 哪些变量之间存在联系
    • 哪些数据集对预测结果影响较大
  6. 以后如何改进
    • 影响模型的主要因素, 今后如何改进
    • 如何避免过度拟合

      收集更多的数据,选择更简单的模型,交叉验证,正则化,使用整体方法或更好的参数调整。

项目过程

读取数据

导入数据包

  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. %matplotlib inline
  5. import seaborn as sns

导入数据源

  1. df = pd.read_csv("C:/Users/zhangyu/Desktop/data_test/HR_comma_sep.csv", index_col = None)

读取本地数据HR_comma_sep.csv, 并以df来命名数据集

检查数据的大小

  1. df.shape

返回:

  1. (14999, 10)

数据总共有14999行, 10列

展现数据的类型

  1. df.dtype

返回:

  1. satisfaction_level float64
  2. last_evaluation float64
  3. number_project int64
  4. average_montly_hours int64
  5. time_spend_company int64
  6. Work_accident int64
  7. left int64
  8. promotion_last_5years int64
  9. sales object
  10. salary object
  11. dtype: object
  1. #### 检查数据集是否有缺失值

返回:

  1. satisfaction_level False
  2. last_evaluation False
  3. number_project False
  4. average_montly_hours False
  5. time_spend_company False
  6. Work_accident False
  7. left False
  8. promotion_last_5years False
  9. sales False
  10. salary False
  11. dtype: bool

每列中有缺失值返回True, 无缺失值返回False, 此数据集比较完整, 没有缺失值。

读取数据前5行

  1. df.head()

数据前5行.png-10.1kB

读取数据后5行

  1. df.tail(5)

数据后5行.png-10.9kB

检查sales行与salar数据的唯一值

  1. df['sales'].unique()

返回:

  1. array(['sales', 'accounting', 'hr', 'technical', 'support', 'management',
  2. 'IT', 'product_mng', 'marketing', 'RandD'], dtype=object)

  1. df['salary'].unique()

返回:

  1. array(['low', 'medium', 'high'], dtype=object)

数据清洗

给列名更换名称以便于更好的阅读

  1. df = df.rename(columns={'satisfaction_level': '员工满意程度','last_evaluation':'最终评价','number_project':'项目数量', 'average_montly_hours':'平均每月工作小时',
  2. 'time_spend_company':'在公司度过年限', 'Work_accident':'工作事故', 'left':'是否离职', 'promotion_last_5years':'5年内是否升职','sales':'部门',
  3. 'salary':'薪水分类'})
  1. df.head()

换列名.png-10.4kB

特征转换

从前面数据读取中我们可以知道, 部门和薪水分类列的内容是字符而不是数字, 我们要将其转化为数字值以便更好地进行对比。

部门列定义:
{0} Sales / {1} Accounting / {2} HR / {3} Technical / {4} Support / {5} Management / {6} IT / {7} Product_Mng / {8} Marketing / {9} RandD

薪水分类列定义:
{0} Low / {1} Medium / {2} High

  1. df['部门'].replace(['sales', 'accounting', 'hr', 'technical', 'support', 'management','IT', 'product_mng', 'marketing', 'RandD'], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], inplace = True)
  2. df['薪水分类'].replace(['low', 'medium', 'high'], [0, 1, 2], inplace = True)
  3. df.head()

员工部门薪水用数字表示.png-9kB

将是否离职作放在表的第一列

  1. front = df['是否离职']
  2. # 在原数据上删除, inplace = True , axis = 1, 删除对应的行
  3. df.drop(labels = ['是否离职'],axis = 1, inplace = True)
  4. # 插入列到表格中, 放在第一行,并用“是否离职”命名
  5. df.insert(0, '是否离职', front) # 插入列到表格中, 放在第一行
  1. df.head()

将是否离职放在第一列微信截图_20171204234453.png-9.1kB

对数据进行探索分析

了解数据的基本统计信息

  1. # 保留两位小数, 并对数据进行反转
  2. df.describe().round(2).T

对数据进行统计描述.png-16.1kB

在职与离职在总数中的占比

  1. 占比 = df.是否离职.value_counts()/14999
  2. 占比

返回

  1. 0 0.761917
  2. 1 0.238083
  3. Name: 是否离职, dtype: float64

在数据集中, 在职员工大约占76.2%,离职员工大约占23.8%

在职和离职员工在其他条件下的平均值对比

  1. 是否离职_综述 = df.groupby('是否离职')
  2. 是否离职_综述.mean()

在职和离职在其他条件下的对比.png-9.4kB

从数据中, 我们可以得出这些结论: 离职员工整体比在职员工工作更努力, 在公司度过时间长, 工作事故低, 但薪水也低,提升比例比在职员工低, 所以员工的满意度低, 从而选择离职。

然而, 我们还有一些问题并没有解决:

  • 哪个变量影响其他因素最多?
  • 变量两个之间的相关性有多大?
  • 是否可以更深入的调查这些因素?

计算变量两个之间的相关系数

  1. df['项目数量'].corr(df['最终评价'])

返回:

  1. 0.34933258851626214

这样的数值可能并不是很直观, 我们可以用热力图来进行展现。

矩阵相关和热力图

  1. #用来正常显示中文标签
  2. plt.rcParams['font.sans-serif']=['SimHei']
  3. # 显示负号
  4. plt.rcParams['axes.unicode_minus']=False
  5. #corr函数, 返回一组数据的相关系数
  6. corr = df.corr()
  7. corr = (corr)
  8. # 制作热力图
  9. sns.heatmap(corr,fmt='.2g',
  10. xticklabels=corr.columns.values,
  11. yticklabels=corr.columns.values)
  12. sns.plt.title('矩阵相关热力图')
  13. #精确到小数点后面2位数
  14. corr.round(2)

矩阵相关.png-19.6kB

热力图.png-30.6kB

从图中可以看出, 最终评价与项目数量,和平均每月工作小时存在着显著的正相关关系。

员工满意程度与是否离职存在着显著的负相关性,员工对公司不满意,离职率会增加。

员工满意程度与项目数量关系不大

查看员工满意度, 最终评价, 平均每月工作小时之间的分布

  1. # 建立图形个数与大小
  2. f, axes = plt.subplots(ncols=3, figsize=(15, 6))
  3. # 员工满意度分布
  4. sns.distplot(df.员工满意程度, kde=False, color="g", ax=axes[0]).set_title('员工满意度分布')
  5. axes[0].set_ylabel('员工人数')
  6. # 员工评估分布
  7. sns.distplot(df.最终评价, kde=False, color="r", ax=axes[1]).set_title('员工评估分布')
  8. axes[1].set_ylabel('员工人数')
  9. # 员工平均每月工作小时分布
  10. sns.distplot(df.平均每月工作小时, kde=False, color="b", ax=axes[2]).set_title('员工平均每月工作小时分布')
  11. axes[2].set_ylabel('员工人数')

员工满意度, 评价, 工作小时分布.png-19.8kB

从上图中, 我们可以看出:

  • 员工满意度之间存在两极分化

  • 最终评价在0.6一下和在0.8以上出现双峰分布

  • 平均每月工作150小时以下和平均每月工作250小时以上出现双峰分布。

  • 最终评价与员工每月工作小时的分布存在相似性, 也对应了我们在热力矩阵图中发现的最终评价与平均每月工作小时之间有高的相关性。

思考:

  • 员工满意度差异是什么原因造成的

  • 员工是否可以通过这些功能分组

  • 最终评价和员工平均每月工作小时之间有关联吗?

在职员工与离职员工之间的薪水差异

  1. f, ax = plt.subplots(figsize=(15, 4))
  2. sns.countplot(y="薪水分类", hue='是否离职', data=df).set_title('在职与离职员工不同薪水之间人数的差异');

在职员工与离职员工薪水的差异.png-11.3kB

0 代表低薪水, 1代表中等薪水, 2代表高新薪水

得出:

  • 我们可以看到, 在职员工 低薪水和中等薪水之间的人数几乎相同

  • 大部分离职员工的薪水都是低水平,或中等水平

  • 低薪水或中等薪水的员工更容易离职, 高薪水的员工不容易离职。

  • 少部分高薪水的员工选择了离职

思考:

  • 什么员工导致了低工资和中等薪水的员工产生了离职, 他们的工作环境是怎么样的
  • 什么原因导致了部分高薪水的员工离职

不同部门之间离职人员比较

  1. #设置颜色格式
  2. color_types = ['#78C850','#F08030','#6890F0','#A8B820','#A8A878','#A040A0','#F8D030',
  3. '#E0C068','#EE99AC','#C03028','#F85888','#B8A038','#705898','#98D8D8','#7038F8']
  4. sns.countplot(x='部门', data=df, palette=color_types).set_title('各部门人数分布')

各部门人数分布.png-6.6kB

  1. f, ax = plt.subplots(figsize=(15, 5))
  2. sns.countplot(y="部门", hue='是否离职', data=df).set_title('各部门在职与离职员工人数分布')

各部门入离职人数分布.png-11.1kB

部门列定义: {0} Sales / {1} Accounting / {2} HR / {3} Technical / {4} Support / {5} Management / {6} IT / {7} Product_Mng / {8} Marketing / {9} RandD
依次对应:0:销售, 1:会计, 2:人力,3 :技术, 4:支持,5 :管理,6: it, 7:产品运营,8 :市场, 9:开发研究

得出:

  • 销售部门, 技术部门和支持部门是员工流失率最高的三个部门。

  • 管理部门的人员流失数量最低

思考:

  • 如果每个部门有更多的信息, 我们可以更直接的找出员工的流失原因吗?

人员离职、项目数量、员工满意度,最终评分、员工工作年限、 每月工作的时间两两之间的又有什么联系呢?

人员流失与项目数量的关系

  1. ax= sns.barplot(x="项目数量", y="项目数量", hue="是否离职", data=df, estimator=lambda x: len(x) / len(df) * 100)
  2. ax.set(ylabel="百分比")

人员流失与项目数量的关系.png-7.3kB

得出:

  • 项目数量为2, 6, 7 的员工更容易离职, 项目数量为7的员工全部离职。

  • 项目数量为3, 4,,5 的员工不容易离职。

  • 当项目超过三个, 随着项目数量的增加, 员工更容易离职。

思考:

  • 对于项目数量为2个的员工是什么原因导致离职

  • 对于项目数量在6个或以上的员工是什么原因导致离职

  • 2个或2个以下的员工是否因员工不够努力或缺乏重视而离职

  • 对于6个以上项目的员工是否因过度工作或薪资福利不够而离职

是否离职与最终评价之间的关系

  1. fig = plt.figure(figsize=(15,4),)
  2. ax=sns.kdeplot(df.loc[(df['是否离职'] == 0),'最终评价'] , color='b',shade=True,label='在职')
  3. ax=sns.kdeplot(df.loc[(df['是否离职'] == 1),'最终评价'] , color='g',shade=True, label='离职')
  4. ax.set(xlabel='员工最终评分', ylabel='频率')
  5. plt.title('员工最终评价分布 ')

是否离职与最终评价的关系.png-33.8kB

结论:

  • 绩效低的员工更容易离开公司

  • 绩效高的员工更容易离开公司

  • 绩效在0.6-0.8的员工不容易离开公司

是否离职与员工每月工作小时之间的关系

  1. fig = plt.figure(figsize=(15,4))
  2. ax=sns.kdeplot(df.loc[(df['是否离职'] == 0),'平均每月工作小时'] , color='b',shade=True, label='在职')
  3. ax=sns.kdeplot(df.loc[(df['是否离职'] == 1),'平均每月工作小时'] , color='r',shade=True, label='离职')
  4. ax.set(xlabel='员工平均每月工作小时', ylabel='频率')
  5. plt.title('员工平均每月工作小时分布—在职V.S.离职')

离职与员工每月工作小时之间的关系.png-35.3kB

得出:

  • 每月工作时间较少的员工更容易离开公司

  • 每月工作时间过长的员工更容易离开公司

  • 每月工作时间在160-240个小时的员工不容易离开公司

  • 员工离开公司, 要么是工作不努力, 要么是过度劳累

  • 员工工作时间越长, 最终评价越高。

离职与员工满意度之间的关系

  1. fig = plt.figure(figsize=(15,4))
  2. ax=sns.kdeplot(df.loc[(df['是否离职'] == 0),'员工满意程度'] , color='b',shade=True, label='在职')
  3. ax=sns.kdeplot(df.loc[(df['是否离职'] == 1),'员工满意程度'] , color='r',shade=True, label='离职')
  4. plt.title('员工满意程度分布- 在职 V.S. 离职')

离职与员工满意度之间的关系.png-33.1kB

将满意程度分为: 极度不满, 比较不满,一般满意, 比较满意, 特别满意

得出:

  • 离职员工对公司的满意度分为:0—0.2,极度不满。 0.3—0.5, 比较不满。 0.7-0.9 , 比较满意

  • 大部分离职员工对公司是不够满意的

  • 大部门在职员工对公司是比较满意的

思考:

  • 为什么大部分离职员工对公司不满意

  • 为什么那些对公司比较满意的员工也离开了公司

项目数量与每月工作小时之间的关系

  1. import seaborn as sns
  2. sns.boxplot(x="项目数量", y="平均每月工作小时", hue="是否离职", data=df)
  3. plt.title('项目数量与平均每月工作小时- 在职 V.S. 离职')

项目数量与每月工作小时之间的关系.png-17.7kB

得出:

  • 当项目数量为2个时, 在职员工所用时间大于离职
  • 随着项目数量的增加,平均每月工作小时也在增加
  • 在职员工随着项目数量的增加, 平均每月工作小时并没有增加
  • 离职员工随着项目数量的增加, 平均每月工作小时在持续增加。

思考:

  • 为什么在职员工随着项目数量的增加, 平均每月工作小时并没有增加, 而离职员工工作小时在增加

项目数量与最终评价之间的关系

  1. sns.boxplot(x="项目数量", y="最终评价", hue="是否离职", data=df)
  2. plt.title('项目数量与最终评价- 在职 V.S. 离职')

项目数量与最终评价之间的关系.png-17.1kB

得出:

  • 对于离职员工, 随着项目数量的增加, 最终评价分数也在增加。
  • 对于在职员工, 随着项目数量的增加, 最终评分并没有变化
  • 此图与 项目数量和每月工作小时关系图 特别接近

思考:

  • 为什么在相同的项目数量下, 离职员工比在职员工得到的评价更高, 会不会是离职员工工作的时间更长
  • 评估较低的员工是不是更容易离开

员工满意度与最终评价之间的关系

  1. sns.lmplot(x='员工满意程度', y='最终评价', data=df,
  2. fit_reg=False, # No regression line
  3. hue='是否离职')

员工满意度与最终评价之间的关系.png-59.8kB

得出:

离职员工分为三种:

  • 第一种(努力工作但对公司不满意)

员工满意程度小于0.2,但最终评价大于0.75。 这可能说明 这些离开的员工非常勤奋努力, 但公司让他们沮丧,产生不满, 从而离开公司。

  • 第二种(评价不高对公司满意度也低)

员工满意程度在0.35-0.5之间, 评价在0.58以下。 这可能表明 这些评价不高的员工在平时的工作中对公司的满意度也比较低

  • 第三种 (评价高且对公司比较满意)

员工满意程度在0.7-0.9 之间, 且评价也在0.8-1.0 之间。这可能说明这个部分的员工是最理想的, 他们对自己工作的满意度比较高且得到的评价也高。

思考:

  • 第一种员工:

什么原因使得努力工作的员工感到特别不满, 工作过于辛苦, 员工过于劳累

  • 第二种员工:

这个群体是否代表未"表现不佳"的员工

  • 第三种员工:

员工离职是否是因为其他的原因, 有了其他的工作机会?

是否离职与在公司司龄之间的关系

  1. ax = sns.barplot(x="在公司度过年限", y="在公司度过年限", hue="是否离职", data=df, estimator=lambda x: len(x) / len(df) * 100)
  2. ax.set(ylabel="百分比")

是否离职与员工司龄之间的关系.png-8.7kB

得出:
* 入职4年和5年的员工更容易离职
* 入职5年的员工更应该关注

思考:
* 为什么3-5年的员工更容易离职
* 为何入职5年的员工离职率特别高

分析了这么多原因, 我们又如何通过建立模型来评估员工离职的概率有多大呢。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注