@zhangyu756897669
2017-12-05T16:09:47.000000Z
字数 7363
阅读 1574
项目
一家大型公司想知道为什么最近一些非常好的并且有经验的员工离开了他们公司,并且希望能够员工对是否会离职进行预测。
kaggle上数据源
https://www.kaggle.com/ludobenistant/hr-analytics-1/data
此数据集为虚拟数据
收集更多的数据,选择更简单的模型,交叉验证,正则化,使用整体方法或更好的参数调整。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
df = pd.read_csv("C:/Users/zhangyu/Desktop/data_test/HR_comma_sep.csv", index_col = None)
读取本地数据HR_comma_sep.csv, 并以df来命名数据集
df.shape
返回:
(14999, 10)
数据总共有14999行, 10列
df.dtype
返回:
satisfaction_level float64
last_evaluation float64
number_project int64
average_montly_hours int64
time_spend_company int64
Work_accident int64
left int64
promotion_last_5years int64
sales object
salary object
dtype: object
#### 检查数据集是否有缺失值
返回:
satisfaction_level False
last_evaluation False
number_project False
average_montly_hours False
time_spend_company False
Work_accident False
left False
promotion_last_5years False
sales False
salary False
dtype: bool
每列中有缺失值返回True, 无缺失值返回False, 此数据集比较完整, 没有缺失值。
df.head()
df.tail(5)
df['sales'].unique()
返回:
array(['sales', 'accounting', 'hr', 'technical', 'support', 'management',
'IT', 'product_mng', 'marketing', 'RandD'], dtype=object)
df['salary'].unique()
返回:
array(['low', 'medium', 'high'], dtype=object)
df = df.rename(columns={'satisfaction_level': '员工满意程度','last_evaluation':'最终评价','number_project':'项目数量', 'average_montly_hours':'平均每月工作小时',
'time_spend_company':'在公司度过年限', 'Work_accident':'工作事故', 'left':'是否离职', 'promotion_last_5years':'5年内是否升职','sales':'部门',
'salary':'薪水分类'})
df.head()
从前面数据读取中我们可以知道, 部门和薪水分类列的内容是字符而不是数字, 我们要将其转化为数字值以便更好地进行对比。
部门列定义:
{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
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)
df['薪水分类'].replace(['low', 'medium', 'high'], [0, 1, 2], inplace = True)
df.head()
front = df['是否离职']
# 在原数据上删除, inplace = True , axis = 1, 删除对应的行
df.drop(labels = ['是否离职'],axis = 1, inplace = True)
# 插入列到表格中, 放在第一行,并用“是否离职”命名
df.insert(0, '是否离职', front) # 插入列到表格中, 放在第一行
df.head()
# 保留两位小数, 并对数据进行反转
df.describe().round(2).T
占比 = df.是否离职.value_counts()/14999
占比
返回
0 0.761917
1 0.238083
Name: 是否离职, dtype: float64
在数据集中, 在职员工大约占76.2%,离职员工大约占23.8%
是否离职_综述 = df.groupby('是否离职')
是否离职_综述.mean()
从数据中, 我们可以得出这些结论: 离职员工整体比在职员工工作更努力, 在公司度过时间长, 工作事故低, 但薪水也低,提升比例比在职员工低, 所以员工的满意度低, 从而选择离职。
然而, 我们还有一些问题并没有解决:
- 哪个变量影响其他因素最多?
- 变量两个之间的相关性有多大?
- 是否可以更深入的调查这些因素?
df['项目数量'].corr(df['最终评价'])
返回:
0.34933258851626214
这样的数值可能并不是很直观, 我们可以用热力图来进行展现。
#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']
# 显示负号
plt.rcParams['axes.unicode_minus']=False
#corr函数, 返回一组数据的相关系数
corr = df.corr()
corr = (corr)
# 制作热力图
sns.heatmap(corr,fmt='.2g',
xticklabels=corr.columns.values,
yticklabels=corr.columns.values)
sns.plt.title('矩阵相关热力图')
#精确到小数点后面2位数
corr.round(2)
从图中可以看出, 最终评价与项目数量,和平均每月工作小时存在着显著的正相关关系。
员工满意程度与是否离职存在着显著的负相关性,员工对公司不满意,离职率会增加。
员工满意程度与项目数量关系不大
# 建立图形个数与大小
f, axes = plt.subplots(ncols=3, figsize=(15, 6))
# 员工满意度分布
sns.distplot(df.员工满意程度, kde=False, color="g", ax=axes[0]).set_title('员工满意度分布')
axes[0].set_ylabel('员工人数')
# 员工评估分布
sns.distplot(df.最终评价, kde=False, color="r", ax=axes[1]).set_title('员工评估分布')
axes[1].set_ylabel('员工人数')
# 员工平均每月工作小时分布
sns.distplot(df.平均每月工作小时, kde=False, color="b", ax=axes[2]).set_title('员工平均每月工作小时分布')
axes[2].set_ylabel('员工人数')
从上图中, 我们可以看出:
员工满意度之间存在两极分化
最终评价在0.6一下和在0.8以上出现双峰分布
平均每月工作150小时以下和平均每月工作250小时以上出现双峰分布。
最终评价与员工每月工作小时的分布存在相似性, 也对应了我们在热力矩阵图中发现的最终评价与平均每月工作小时之间有高的相关性。
思考:
员工满意度差异是什么原因造成的
员工是否可以通过这些功能分组
最终评价和员工平均每月工作小时之间有关联吗?
f, ax = plt.subplots(figsize=(15, 4))
sns.countplot(y="薪水分类", hue='是否离职', data=df).set_title('在职与离职员工不同薪水之间人数的差异');
0 代表低薪水, 1代表中等薪水, 2代表高新薪水
得出:
我们可以看到, 在职员工 低薪水和中等薪水之间的人数几乎相同
大部分离职员工的薪水都是低水平,或中等水平
低薪水或中等薪水的员工更容易离职, 高薪水的员工不容易离职。
少部分高薪水的员工选择了离职
思考:
- 什么员工导致了低工资和中等薪水的员工产生了离职, 他们的工作环境是怎么样的
- 什么原因导致了部分高薪水的员工离职
#设置颜色格式
color_types = ['#78C850','#F08030','#6890F0','#A8B820','#A8A878','#A040A0','#F8D030',
'#E0C068','#EE99AC','#C03028','#F85888','#B8A038','#705898','#98D8D8','#7038F8']
sns.countplot(x='部门', data=df, palette=color_types).set_title('各部门人数分布')
f, ax = plt.subplots(figsize=(15, 5))
sns.countplot(y="部门", hue='是否离职', data=df).set_title('各部门在职与离职员工人数分布')
部门列定义: {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:开发研究
得出:
销售部门, 技术部门和支持部门是员工流失率最高的三个部门。
管理部门的人员流失数量最低
思考:
- 如果每个部门有更多的信息, 我们可以更直接的找出员工的流失原因吗?
ax= sns.barplot(x="项目数量", y="项目数量", hue="是否离职", data=df, estimator=lambda x: len(x) / len(df) * 100)
ax.set(ylabel="百分比")
得出:
项目数量为2, 6, 7 的员工更容易离职, 项目数量为7的员工全部离职。
项目数量为3, 4,,5 的员工不容易离职。
当项目超过三个, 随着项目数量的增加, 员工更容易离职。
思考:
对于项目数量为2个的员工是什么原因导致离职
对于项目数量在6个或以上的员工是什么原因导致离职
2个或2个以下的员工是否因员工不够努力或缺乏重视而离职
对于6个以上项目的员工是否因过度工作或薪资福利不够而离职
fig = plt.figure(figsize=(15,4),)
ax=sns.kdeplot(df.loc[(df['是否离职'] == 0),'最终评价'] , color='b',shade=True,label='在职')
ax=sns.kdeplot(df.loc[(df['是否离职'] == 1),'最终评价'] , color='g',shade=True, label='离职')
ax.set(xlabel='员工最终评分', ylabel='频率')
plt.title('员工最终评价分布 ')
结论:
绩效低的员工更容易离开公司
绩效高的员工更容易离开公司
绩效在0.6-0.8的员工不容易离开公司
fig = plt.figure(figsize=(15,4))
ax=sns.kdeplot(df.loc[(df['是否离职'] == 0),'平均每月工作小时'] , color='b',shade=True, label='在职')
ax=sns.kdeplot(df.loc[(df['是否离职'] == 1),'平均每月工作小时'] , color='r',shade=True, label='离职')
ax.set(xlabel='员工平均每月工作小时', ylabel='频率')
plt.title('员工平均每月工作小时分布—在职V.S.离职')
得出:
每月工作时间较少的员工更容易离开公司
每月工作时间过长的员工更容易离开公司
每月工作时间在160-240个小时的员工不容易离开公司
员工离开公司, 要么是工作不努力, 要么是过度劳累
员工工作时间越长, 最终评价越高。
fig = plt.figure(figsize=(15,4))
ax=sns.kdeplot(df.loc[(df['是否离职'] == 0),'员工满意程度'] , color='b',shade=True, label='在职')
ax=sns.kdeplot(df.loc[(df['是否离职'] == 1),'员工满意程度'] , color='r',shade=True, label='离职')
plt.title('员工满意程度分布- 在职 V.S. 离职')
将满意程度分为: 极度不满, 比较不满,一般满意, 比较满意, 特别满意
得出:
离职员工对公司的满意度分为:0—0.2,极度不满。 0.3—0.5, 比较不满。 0.7-0.9 , 比较满意
大部分离职员工对公司是不够满意的
大部门在职员工对公司是比较满意的
思考:
为什么大部分离职员工对公司不满意
为什么那些对公司比较满意的员工也离开了公司
import seaborn as sns
sns.boxplot(x="项目数量", y="平均每月工作小时", hue="是否离职", data=df)
plt.title('项目数量与平均每月工作小时- 在职 V.S. 离职')
得出:
- 当项目数量为2个时, 在职员工所用时间大于离职
- 随着项目数量的增加,平均每月工作小时也在增加
- 在职员工随着项目数量的增加, 平均每月工作小时并没有增加
- 离职员工随着项目数量的增加, 平均每月工作小时在持续增加。
思考:
- 为什么在职员工随着项目数量的增加, 平均每月工作小时并没有增加, 而离职员工工作小时在增加
sns.boxplot(x="项目数量", y="最终评价", hue="是否离职", data=df)
plt.title('项目数量与最终评价- 在职 V.S. 离职')
得出:
- 对于离职员工, 随着项目数量的增加, 最终评价分数也在增加。
- 对于在职员工, 随着项目数量的增加, 最终评分并没有变化
- 此图与 项目数量和每月工作小时关系图 特别接近
思考:
- 为什么在相同的项目数量下, 离职员工比在职员工得到的评价更高, 会不会是离职员工工作的时间更长
- 评估较低的员工是不是更容易离开
sns.lmplot(x='员工满意程度', y='最终评价', data=df,
fit_reg=False, # No regression line
hue='是否离职')
得出:
离职员工分为三种:
- 第一种(努力工作但对公司不满意)
员工满意程度小于0.2,但最终评价大于0.75。 这可能说明 这些离开的员工非常勤奋努力, 但公司让他们沮丧,产生不满, 从而离开公司。
- 第二种(评价不高对公司满意度也低)
员工满意程度在0.35-0.5之间, 评价在0.58以下。 这可能表明 这些评价不高的员工在平时的工作中对公司的满意度也比较低
- 第三种 (评价高且对公司比较满意)
员工满意程度在0.7-0.9 之间, 且评价也在0.8-1.0 之间。这可能说明这个部分的员工是最理想的, 他们对自己工作的满意度比较高且得到的评价也高。
思考:
- 第一种员工:
什么原因使得努力工作的员工感到特别不满, 工作过于辛苦, 员工过于劳累
- 第二种员工:
这个群体是否代表未"表现不佳"的员工
- 第三种员工:
员工离职是否是因为其他的原因, 有了其他的工作机会?
ax = sns.barplot(x="在公司度过年限", y="在公司度过年限", hue="是否离职", data=df, estimator=lambda x: len(x) / len(df) * 100)
ax.set(ylabel="百分比")
得出:
* 入职4年和5年的员工更容易离职
* 入职5年的员工更应该关注思考:
* 为什么3-5年的员工更容易离职
* 为何入职5年的员工离职率特别高