CDA数据分析师 出品

作者:真达、Mika

数据:真达

后期:泽龙

【导读】

今天教大家如何用Python写一个员工流失预测模型。公众号后台,回复关键字“离职”获取完整数据。Show me data,用数据说话。

今天我们聊一聊 员工离职,说到离职的原因,可谓多种多样。人们归总了两点:

1. 钱没给到位

2. 心受委屈了

有人离职是因为“世界那么大,我想去看看”,也有人觉得“怀有绝技在身,不怕天下无路”。

另一方面,员工离职对于企业而言有什么影响呢?

要知道,企业培养人才需要大量的成本,为了防止人才再次流失,员工流失分析就显得十分重要了。这不仅仅是公司评估员工流动率的过程,通过找到导致员工流失的主要因素,预测未来的员工离职状况,从而进一步减少员工流失。

那么,哪些因素最容易导致员工离职呢?

这次我们用数据说话,

教你如何用Python写一个员工流失预测模型。

01、数据理解

我们分析了kaggle平台分享的员工离职相关的数据集,共有10个字段14999条记录。数据主要包括影响员工离职的各种因素(员工满意度、绩效考核、参与项目数、平均每月工作时长、工作年限、是否发生过工作差错、5年内是否升职、部门、薪资)以及员工是否已经离职的对应记录。字段说明如下:

02、读入数据

# 读入数据df = pd.read_csv('HR_comma_sep.csv')df.head() 
# 读入数据df = pd.read_csv('HR_comma_sep.csv')df.head() 
# 读入数据df = pd.read_csv('HR_comma_sep.csv')df.head() 
# 查看缺失值print(df.isnull().any().sum()) 
# 查看缺失值print(df.isnull().any().sum()) 
# 查看缺失值print(df.isnull().any().sum()) 

可以发现,数据质量良好,没有缺失数据。

03、探索性分析

描述性统计

df.describe().T

从上述描述性分析结果可以看出:

  • 员工满意度:范围0.09~1, 中位数0.640, 均值0.613, 总体来说员工对公司比较满意;
  • 绩效考核:范围0.36~1, 中位数0.72, 均值0.716, 员工平均考核水平在中等偏上;
  • 参与项目数:范围2~7, 中位数4, 均值3.8, 平均参加项目数约4个;
  • 平均每月工作时长:范围96~310小时, 中位数200, 均值201。
  • 工作年限:范围2~10年, 中位数3, 均值3.5。

离职人数占比

整理数据后发现,总共有14999人,其中红色部分代表离职人群,用数字1表示,蓝色为未离职人群,用数字0表示。离职人数为3571,占总人数的23.8%。

员工满意度

从直方图可以看出,离职员工的满意度评分明显偏低,平均值为0.44。满意度低于0.126分的离职率为97.2%。可见提升员工满意度可以有效防止人员流失。

df.groupby('left')['satisfaction_level'].describe() 
def draw_numeric_graph(x_series, y_series, title):    # 产生数据    sat_cut = pd.cut(x_series, bins=25)     cross_table = round(pd.crosstab(sat_cut, y_series, normalize='index'),4)*100    x_data = cross_table.index.astype('str').tolist()    y_data1 = cross_table[cross_table.columns[1]].values.tolist()    y_data2 = cross_table[cross_table.columns[0]].values.tolist()     # 条形图    bar = Bar(init_opts=opts.InitOpts(width='1350px', height='750px'))    bar.add_xaxis(x_data)    bar.add_yaxis(str(cross_table.columns[1]), y_data1, stack='stack1', category_gap='0%')    bar.add_yaxis(str(cross_table.columns[0]), y_data2, stack='stack1', category_gap='0%')    bar.set_global_opts(title_opts=opts.TitleOpts(title),                         xaxis_opts=opts.AxisOpts(name=x_series.name, name_location='middle', name_gap=30),                        yaxis_opts=opts.AxisOpts(name='百分比', name_location='middle', name_gap=30, min_=0, max_=100),                        legend_opts=opts.LegendOpts(orient='vertical', pos_top='15%', pos_right='2%'))    bar.set_series_opts(label_opts=opts.LabelOpts(is_show=False),                         itemstyle_opts=opts.ItemStyleOpts(border_color='black', border_width=0.3))    bar.set_colors(['#BF4C51', '#8CB9D0'])     return bar 
bar1 = draw_numeric_graph(df['satisfaction_level'], df['left'], )bar1.render() 

绩效考核

平均来看,绩效考核成绩在离职/未离职员工之间差异不大。在离职员工中,绩效考核低、能力不够和绩效考核较高但工作压力大、满意度低、对薪资不满意可能成为离职的原因。

平均每月工作时长

从直方图可以看出,月工作时长正常的员工离职率最低。而工时过低、过高的员工离职人数最多。证明恰当的工作任务分配是非常重要的。

参加项目数

从图中可以看出:除项目数为2以外,随着项目数的增多,离职率在增大,且项目数是7的时候,离职率达到了100%以上。综上两点,项目数2的离职率高,可能是这部分人工作能力不被认可。项目数6、7的总体少,离职率高,体现了他们的工作能力强,但同时工作压力太大导致他们离职。

员工工龄

可以看到7年及以上工龄的员工基本没有离职,只有工龄为5年的员工离职人数超过在职人数。可见工龄长于6年的员工,由于种种原因,其“忠诚度”较高。

而员工进入公司工作的第5年是一个较为“危险”的年份,也许是该企业的“5年之痒”,应当重点关注该阶段的员工满意度、职业晋升等情况,以顺利过渡。

工作事故

从图中可看出,是否发生工作事故对员工离职的影响较小,可推测该企业处理工作事故的方式有可取之处。

职位晋升

从条形图可以看出,在过去5年内获得未晋升的员工离职率为24.2%,比获得晋升的员工高4倍。设定良好的晋升通道可以很好的防止员工流失。

薪资水平

可明显看出,薪资越高离职人数越少。证明为了减少离职率,提升员工福利待遇是一个可行的手段。

不同部门

可见各部门离职率如上图,离职率由高到低,前三位分别是:人力部、财务部、科技部。之后依次是:支持部、销售部、市场部、IT部门、产品部、研发部、管理部。对于离职率过高的部门,应进一步分析关键原因。

04、数据预处理

由于sklearn在建模时不接受类别型变量,我们主要对数据做以下处理,以方便后续建模分析:

  • 薪资水平salary为定序变量, 因此将其字符型转化为数值型。
  • 岗位是定类型变量, 对其进行one-hot编码。
# 数据转换df['salary'] = df['salary'].map({"low": 0, "medium": 1, "high": 2})# 哑变量df_dummies = pd.get_dummies(df,prefix='sales')df_dummies.head() 

05、建模分析

我们使用决策树和随机森林进行模型建置,首先导入所需包:

from sklearn.model_selection import train_test_split, GridSearchCVfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import classification_report, f1_score, roc_curve, plot_roc_curve

然后划分训练集和测试集,采用分层抽样方法划分80%数据为训练集,20%数据为测试集。

train_pred = GS.best_estimator_.predict(X_train)test_pred = GS.best_estimator_.predict(X_test)print('训练集:', classification_report(y_train, train_pred))print('-' * 60) print('测试集:', classification_report(y_test, test_pred))

决策树

我们使用决策树进行建模,设置特征选择标准为gini,树的深度为5。输出分类的评估报告:

# 训练模型clf = DecisionTreeClassifier(criterion='gini', max_depth=5, random_state=25)clf.fit(X_train, y_train)train_pred = clf.predict(X_train)test_pred = clf.predict(X_test)  print('训练集:', classification_report(y_train, train_pred))print('-' * 60) print('测试集:', classification_report(y_test, test_pred))
训练集:               precision    recall  f1-score   support           0       0.98      0.99      0.98      9142           1       0.97      0.93      0.95      2857    accuracy                           0.98     11999   macro avg       0.97      0.96      0.97     11999weighted avg       0.98      0.98      0.97     11999------------------------------------------------------------测试集:               precision    recall  f1-score   support           0       0.98      0.99      0.98      2286           1       0.97      0.93      0.95       714    accuracy                           0.98      3000   macro avg       0.97      0.96      0.97      3000weighted avg       0.98      0.98      0.98      3000

假设我们关注的是1类(即离职类)的F1-score,可以看到训练集的分数为0.95,测试集分数为0.95。

# 重要性imp = pd.DataFrame([*zip(X_train.columns,clf.feature_importances_)], columns=['vars', 'importance'])imp.sort_values('importance', ascending=False)  imp = imp[imp.importance!=0]imp 

在属性的重要性排序中,员工满意度最高,其次是最新的绩效考核、参与项目数、每月工作时长。

然后使用网格搜索进行参数调优。

parameters = {'splitter':('best','random'),              'criterion':("gini","entropy"),              "max_depth":[*range(1, 20)],             }clf = DecisionTreeClassifier(random_state=25)GS = GridSearchCV(clf, parameters, cv=10)GS.fit(X_train, y_train)print(GS.best_params_)print(GS.best_score_) 
{'criterion': 'gini', 'max_depth': 15, 'splitter': 'best'}0.9800813177648042

使用最优的模型重新评估训练集和测试集效果:

train_pred = GS.best_estimator_.predict(X_train)test_pred = GS.best_estimator_.predict(X_test)print('训练集:', classification_report(y_train, train_pred))print('-' * 60) print('测试集:', classification_report(y_test, test_pred))
训练集:               precision    recall  f1-score   support           0       1.00      1.00      1.00      9142           1       1.00      0.99      0.99      2857    accuracy                           1.00     11999   macro avg       1.00      0.99      1.00     11999weighted avg       1.00      1.00      1.00     11999------------------------------------------------------------测试集:               precision    recall  f1-score   support           0       0.99      0.98      0.99      2286           1       0.95      0.97      0.96       714    accuracy                           0.98      3000   macro avg       0.97      0.98      0.97      3000weighted avg       0.98      0.98      0.98      3000

可见在最优模型下模型效果有较大提升,1类的F1-score训练集的分数为0.99,测试集分数为0.96。

随机森林

下面使用集成算法随机森林进行模型建置,并调整max_depth参数。

rf_model = RandomForestClassifier(n_estimators=1000, oob_score=True, n_jobs=-1,                                   random_state=0)parameters = {'max_depth': np.arange(3, 17, 1) }GS = GridSearchCV(rf_model, param_grid=parameters, cv=10)GS.fit(X_train, y_train)print(GS.best_params_) print(GS.best_score_) 
{'max_depth': 16}0.988582151793161
train_pred = GS.best_estimator_.predict(X_train)test_pred = GS.best_estimator_.predict(X_test)print('训练集:', classification_report(y_train, train_pred))print('-' * 60) print('测试集:', classification_report(y_test, test_pred))
训练集:               precision    recall  f1-score   support           0       1.00      1.00      1.00      9142           1       1.00      0.99      0.99      2857    accuracy                           1.00     11999   macro avg       1.00      1.00      1.00     11999weighted avg       1.00      1.00      1.00     11999------------------------------------------------------------测试集:               precision    recall  f1-score   support           0       0.99      1.00      0.99      2286           1       0.99      0.97      0.98       714    accuracy                           0.99      3000   macro avg       0.99      0.99      0.99      3000weighted avg       0.99      0.99      0.99      3000

可以看到在调优之后的随机森林模型中,1类的F1-score训练集的分数为0.99,测试集分数为0.98。

模型后续可优化方向:

  • 属性:数值型数据常常是模型不稳定的来源,可考虑对其进行分箱;重要属性筛选和字段扩充;
  • 算法:其他的集成方法;不同效能评估下的作法调整。

对项目分析感兴趣的朋友,可以后台给小编留言哦!

rapidminer员工离职分析_员工一言不合就离职怎么破?我有Python员工流失预警模型...相关推荐

  1. 员工一言不合就离职怎么办?用 Python 写了个员工流失预测模型

    作者 | 真达.Mika 来源 | CDA数据分析师(ID:cdacdacda) [导读] 今天教大家如何用 Python 写一个员工流失预测模型. Show me data,用数据说话. 今天我们聊 ...

  2. 员工一言不合就离职怎么办?我用 Python 写了个员工流失预测模型

    今天教大家如何用Python写一个员工流失预测模型.说道离职的原因,可谓多种多样.人们归总了两点: 1. 钱没给到位 2. 心受委屈了 有人离职是因为"世界那么大,我想去看看",也 ...

  3. 怎么让员工服从管理_职场 | 在职场中,遇到不服从管理的员工,该怎么办呢?...

    不懂点心理学,怎么玩转职场? 设为[星标]更方便 点击上方公号名称→右上角三个点→设为星标! 职场心理志,专注职场生活的方方面面 ID:Workplace-M 作者 | 佚名 文章来源 | 综合网络 ...

  4. 兔子数列python编程分析_九九乘法,兔子数列,杨辉三角|用Python生成器的妙解...

    很多同学还是对生成器的用法,感到怀疑,特别是有其他语言基础的同学,一下子很难理解和转换过来,那什么情况下会用到yield,建议是当需要在循环过程中依次处理一个序列中的元素的时候,就应该考虑生成器,其实 ...

  5. 银行客户流失预警模型——业务分析及代码(实战)

    DataMiningCase 点击跳转GitHub地址 流失预警模型(二分类),代码原型为本人在某银行做的流失模型,AUC:83%.召回率:19.4%,精确率:85%(数据是外部数据/代码已脱敏) 你 ...

  6. 腾讯QQ大数据:用户增长分析——用户流失预警

    1,前言:针对用户增长分析这个课题,本文主要从用户防流失的角度,阐述如何基于QQ社交网络数据构建用户流失预警模型,找出高潜流失用户,用于定向开展运营激活,从而有效控制用户流失风险,提升大盘用户的留存率 ...

  7. rapidminer员工离职分析_HR如何做好离职分析?

    做离职分析,估计百分之八十的人最先想到各种表格.当然表格是没错,但更重要的是思维.可以说,离职分析,最考验HR的境界. 很多HR是这么做的:有员工来离职,询问下离职员工,然后做离职统计-- 年底时,做 ...

  8. rapidminer员工离职分析_RapidMiner 9从根本上简化了分析团队的数据准备工作

    马萨诸塞州波士顿,2018年8月7日– RapidMiner™,领先的科学数据平台,数据分析团队,宣布RapidMiner 9.0与即将上市的Turbo准备.根据哈佛商业评论最近的一份出版物,分析团队 ...

  9. SAP License:员工离职分析

    今天早上在跟别的部门一个员工聊天的时候,才知道他想走,并且已经和他的经理说了.然后我详细询问了他想离职的原因,觉得他想离职,完全可以理解.其想离职的主要原因为: 1.本来应聘的是A工作内容,现在却要做 ...

  10. 怎么让员工服从管理_为什么现在的员工执行力和服从性越来越差,管理一严格就辞职?...

    当有负面情绪的时候, 不要说.管好自己的嘴, 有时候做哑巴,是一种境界. 现在的企业很多都存在这个问题,员工执行力越来越差,服从性也越来越差,管理者稍微一严格,员工就会辞职走人,留不住人. 到底是员工 ...

最新文章

  1. Spark学习之路(二)
  2. python 九宫重排_[蓝桥杯][历届试题]九宫重排 (Python代码)(bfs+集合)
  3. 《计算复杂性:现代方法》——0.2 判定问题/语言
  4. UVa 11475 - Extend to Palindrome
  5. java api帮助文档_JAVA的Swagger界面丑、功能弱怎么破?
  6. 用生产者和消费者模式实现奇数偶数不同线程交替输出
  7. 8个超棒的使用javascript开发的视觉特效网站
  8. layui table 分页 序号始终从”1“开始解决方法
  9. C#实现中国天气网JSON接口测试
  10. python量化交易通达信_分享一个可以实战的量化交易策略(适用于通达信系统)...
  11. 服务器专用影子系统,试试最牛X的影子系统!瞬间创建N个账号
  12. 时钟天气小插件显示没服务器,天气时钟小插件大全
  13. 不加群提取群成员_使用itchat分析指定微信群男女比例等成员数据
  14. SpringDataJpa原理及使用
  15. 经典案例悬臂梁受力有限元理论与程序设计_《数值计算与程序设计》系列课程之三
  16. ad采样正弦电压计算c语言程序,TMS320F2812 DSP编程之AD采样精度的校准算法(转)...
  17. PMP项目管理是什么意思?
  18. 【技术思路】极客时间-左耳听风-开篇词1
  19. python cadn面试题(摘抄)
  20. 隔空投送教程|如何将文件从iPhone或iPad空投到Mac计算机?

热门文章

  1. Jquery点点滴滴-draggable对象和droppable对象
  2. php编程 之php基础 表单
  3. 【BZOJ2839】集合计数【BZOJ3622】已经没有什么好害怕的了
  4. Java TCP协议传输
  5. Centos之常见目录作用介绍
  6. 移动端tap或touch类型事件的点透问题认识
  7. C#设计模式--外观模式
  8. VC2010常见问题的解决方案
  9. [wikioi]最长严格上升子序列
  10. 数据库信息查询(作者不是我)