版权声明:本文为博主原创文章。未经博主同意不得转载。 https://blog.csdn.net/kMD8d5R/article/details/83542978

https://mmbiz.qpic.cn/mmbiz_gif/y2fhgP4leTj804F6eWg06denf5Gdeqz307pm7PcP1QmWWzk13k7WVFw1lO2A4W49gb35H0rkxkwFMhFqA3eJSA/640?wx_fmt=gif" alt="640?wx_fmt=gif" />

https://mmbiz.qpic.cn/mmbiz_png/y2fhgP4leTj804F6eWg06denf5Gdeqz3uHxEIfS9h60ymX2D6YnLL2I6yezRjh7aYDRfRaTIQ9QVndEbtbSgsg/640?

wx_fmt=png" alt="640?

wx_fmt=png" />

作者简单介绍

糖甜甜甜,R语言中文社区专栏作者

公众号:经管人学数据分析

在实验室搬砖之后,继续我们的kaggle数据分析之旅,这次数据也是答主在kaggle上选择的比較火的一份关于人力资源的数据集,关注点在于员工离职的分析和预測,依旧还是从数据读取,数据预处理,EDA和机器学习建模这几个部分開始进行,最后使用集成学习中比較火的random forest算法来预測离职情况。

数据读取


setwd("E:/kaggle/human resource")
library(data.table)
library(plotly)
library(corrplot)
library(randomForest)
library(pROC)
library(tidyverse)
library(caret)
hr<-as.tibble(fread("HR_comma_sep.csv"))
glimpse(hr)
sapply(hr,function(x){sum(is.na(x))})
————————————————————————————————————————————————————————————————————————————————————
Observations: 14,999
Variables: 10
$ satisfaction_level    <dbl> 0.38, 0.80, 0.11, 0.72, 0.37, 0.41, 0.10, 0.92, 0.89, 0.42, 0.45, 0.11, 0.84, 0.41, 0.36, 0.38, 0.45, 0.78, 0.45, 0.76, 0.11, 0.3...
$ last_evaluation       <dbl> 0.53, 0.86, 0.88, 0.87, 0.52, 0.50, 0.77, 0.85, 1.00, 0.53, 0.54, 0.81, 0.92, 0.55, 0.56, 0.54, 0.47, 0.99, 0.51, 0.89, 0.83, 0.5...
$ number_project        <int> 2, 5, 7, 5, 2, 2, 6, 5, 5, 2, 2, 6, 4, 2, 2, 2, 2, 4, 2, 5, 6, 2, 6, 2, 2, 5, 4, 2, 2, 2, 6, 2, 2, 2, 4, 6, 2, 2, 6, 2, 5, 2, 2, ...
$ average_montly_hours  <int> 157, 262, 272, 223, 159, 153, 247, 259, 224, 142, 135, 305, 234, 148, 137, 143, 160, 255, 160, 262, 282, 147, 304, 139, 158, 242,...
$ time_spend_company    <int> 3, 6, 4, 5, 3, 3, 4, 5, 5, 3, 3, 4, 5, 3, 3, 3, 3, 6, 3, 5, 4, 3, 4, 3, 3, 5, 5, 3, 3, 3, 4, 3, 3, 3, 6, 4, 3, 3, 4, 3, 5, 3, 3, ...
$ Work_accident         <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
$ left                  <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
$ promotion_last_5years <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
$ sales                 <chr> "sales", "sales", "sales", "sales", "sales", "sales", "sales", "sales", "sales", "sales", "sales", "sales", "sales", "sales", "sa...
$ salary                <chr> "low", "medium", "medium", "low", "low", "low", "low", "low", "low", "low", "low", "low", "low", "low", "low", "low", "low", "low...

satisfaction_level       last_evaluation        number_project  average_montly_hours    time_spend_company         Work_accident                  left
                   0                     0                     0                     0                     0                     0                     0
promotion_last_5years                 sales                salary
                   0                     0                     0

数据集情况例如以下。一共10维数据,14999个观測值。变量的代表名称各自是
satisfaction_level--惬意度,last_evaluation--最后一次评估,number_project--參与项目数量。average_montly_hours--每月平均工作时间。time_spend_company--公司停留时间。Work_accident--工作事故次数,left--是否离职。promotion_last_5years--过去五年升值状况,sales--工种,salary--工资。

并且简单的观測了一下。没有发现缺失值,那么我就能够直接进入数据分析阶段了。

数据预处理

依据每个特征的数值情况。我们能够将不少特征因子化,方便后期做不同类别的差异分析。


hr$sales<-as.factor(hr$sales)
hr$salary<-as.factor(hr$salary)
hr$left<-as.factor(hr$left)
hr$Work_accident<-as.factor(hr$Work_accident)
hr$left<-recode(hr$left,'1'="yes",'0'="no")
hr$promotion_last_5years<-as.factor(hr$promotion_last_5years)

看的出大部分数据都是数值型的。我们使用相关性来衡量不同变量之间的相关性高低:


cor.hr<-hr %>% select(-sales,-salary)
cor.hr$Work_accident<-as.numeric(as.character(cor.hr$Work_accident))
cor.hr$promotion_last_5years<-as.numeric(as.character(cor.hr$promotion_last_5years))
cor.hr$left<-as.numeric(as.character(cor.hr$left))
corrplot(corr = cor(cor.hr),type = "lower",method = "square",title="变量相关性",order="AOE")

直观的来看。是否离职和惬意度高低就有非常高的关联性啊。

EDA


ggplot(group_by(hr,sales),aes(x=sales,fill=sales))+geom_bar(width = 1)+coord_polar(theta = "x")+ggtitle("不同职业的人数")
ggplot(hr,aes(x=sales,y=satisfaction_level,fill=sales))+geom_boxplot()+ggtitle("不同职业的惬意度")+stat_summary(fun.y = mean,size=3,color='white',geom = "point")+
 theme(legend.position = "none")
ggplot(hr,aes(x=sales,y=satisfaction_level,fill=left))+geom_boxplot()+ggtitle("不同职业的惬意度")
ggplot(hr,aes(x=sales,y=average_montly_hours,fill=left))+geom_boxplot()+ggtitle("不同职业的工作时长")
ggplot(hr,aes(x=sales,y=number_project,fill=left))+geom_boxplot()+ggtitle("不同职业的项目情况")

首先观察不同岗位的工作人数。搞销售的人数真的是不少。难道有不少我大生科的同学吗??(哈哈哈哈哈哈哈。开个玩笑而已,只是说实话做生物真的非常累啊)。

销售,后期支持,和技术岗人数占领人数排行榜前三。

不同的职业惬意度的分布大体相当。只是accounting的小伙伴们似乎打分都不高哦,其它的几个工种均值和中位数都没有明显区别,接下来我们看看不同职业是否离职的情况和打分的高低情况:

https://mmbiz.qpic.cn/mmbiz_jpg/J9rT6MJZsD3HBSy3HeJpugBpZyerbAic3CqgsKiaBAicU70xI2MLjiaiaohGPoHsjrYcIwSy2TksbW98nYfrX5YSwicA/640?wx_fmt=jpeg" alt="640?wx_fmt=jpeg" />

和想象中结果差点儿没有区别,离职和不离职的打分区分度非常高,和职业差点儿没有关系。

https://mmbiz.qpic.cn/mmbiz_jpg/J9rT6MJZsD3HBSy3HeJpugBpZyerbAic3LTed9VWQbRV0T7SicSjDoE9UMeeyMn2orSZmZxPicKWIoAUo99WSQibUw/640?wx_fmt=jpeg" alt="640?wx_fmt=jpeg" />

那么不同职业的平均工作时长呢,看图而言,没有离职的人群工作时间都非常稳定。可是离职人群的工作时间呈现两极分化的趋势。看来太忙和太闲都不是非常好。这对hr的考验还是非常大的。

后面我们来一次关注一下不同特征和离职的关系问题:


ggplot(hr,aes(x=satisfaction_level,color=left))+geom_line(stat = "density")+ggtitle("惬意度和离职的关系")
ggplot(hr,aes(x=salary,fill=left))+geom_histogram(stat="count")+ggtitle("工资和离职的关系")
ggplot(hr,aes(x=promotion_last_5years,fill=left))+geom_histogram(stat="count")+ggtitle("近5年升值和离职的关系")
ggplot(hr,aes(x=last_evaluation,color=left))+geom_point(stat = "count")+ggtitle("最后一次评价和离职的关系")
hr %>% group_by(sales) %>% ggplot(aes(x=sales,fill=Work_accident))+geom_bar()+coord_flip()+
 theme(axis.text.x = element_blank(),axis.title.x = element_blank(),axis.title.y = element_blank())+scale_fill_discrete(labels=c("no accident","at least once"))

wx_fmt=jpeg" />

没有离职的人群打分已知非常稳定,而离职人群的打分就有点难以估摸了

还是那句话。“有钱好办事啊”

wx_fmt=jpeg" alt="640?wx_fmt=jpeg" />

你不给宝宝升职,宝宝就生气离职

wx_fmt=jpeg" />

和前面的面积图几乎相同,hr也要警惕那些最后一次打分非常高的,尽管大部分是不准备离职的。可是有些为了给老东家面子还是会来点“善意的谎言”的。

wx_fmt=jpeg" alt="640?wx_fmt=jpeg" />

不出错是不可能的,出错人数多少基本和总人数成正比,所以这个对于离职来说不是问题。

模型构建和评估


index<-sample(2,nrow(hr),replace = T,prob = c(0.7,0.3))
train<-hr[index==1,];test<-hr[index==2,]
model<-randomForest(left~.,data = train)
predict.hr<-predict(model,test)
confusionMatrix(test$left,predict.hr)

prob.hr<-predict(model,test,type="prob")
roc.hr<-roc(test$left,prob.hr[,2],levels=levels(test$left))
plot(roc.hr,type="S",col="red",main = paste("AUC=",roc.hr$auc,sep = ""))

依据前面的特征分析,本次答主并没有认为有非常好的特征来提取。就直接扔进算法里面计算去了,计算出来的混淆矩阵的情况效果还是杠杠的:


Confusion Matrix and Statistics

         Reference
Prediction   no  yes
      no  3429    5
      yes   28 1010
                                         
              Accuracy : 0.9926          
                95% CI : (0.9897, 0.9949)
   No Information Rate : 0.773          
   P-Value [Acc > NIR] : < 2.2e-16      
                                         
                 Kappa : 0.9791          
Mcnemar's Test P-Value : 0.0001283      
                                         
           Sensitivity : 0.9919          
           Specificity : 0.9951          
        Pos Pred Value : 0.9985          
        Neg Pred Value : 0.9730          
            Prevalence : 0.7730          
        Detection Rate : 0.7668          
  Detection Prevalence : 0.7679          
     Balanced Accuracy : 0.9935          
                                         
      'Positive' Class : no              
                                         

acc=0.9926,recall=0.9951,precision=0.9730,基本都是逆天的数据了,看来kaggle的数据集已经清洗的非常棒了,rf算法也是一如既往地给力。最后贴出ROC曲线的图

写在最后

本次分析事实上并没有非常多的技巧可言,答主的ggplot2水平也遇到了瓶颈期,后期须要不断加强,并且仅仅会调包不懂算法后面的原理更是不能够的,所以近期在慢慢把概率论。线性代数,还是统计学捡起来,当然R语言的数据分析实践还是不会停下来的,答主英语还不错,能够和实验室的老外教授“忽悠”几句。也算是有了不少的进步。

道阻且长,大家共勉~~~

往期回想

词云一分钟了解周董的歌词

R语言实现统计分析——非參数如果检验

《我不是药神》30亿票房后分析徐峥的选角眼光

wx_fmt=jpeg" alt="640?wx_fmt=jpeg" />

公众号后台回复keyword就可以学习

回复 爬虫            爬虫三大案例实战  
回复 Python       1小时破冰入门

回复 数据挖掘     R语言入门及数据挖掘
回复 人工智能     三个月入门人工智能
回复 数据分析师  数据分析师成长之路 
回复 机器学习      机器学习的商业应用
回复 数据科学      数据科学实战
回复 经常使用算法      经常使用数据挖掘算法

用R语言分析与预測员工离职的更多相关文章

  1. R语言分析朝阳医院数据

    R语言分析朝阳医院数据 本次实践通过分析朝阳医院2016年销售数据,得出“月均消费次数”.“月均消费金额”.“客单价”.“消费趋势”等结果,并据此作出可视化图形. 一.读取数据: library(op ...

  2. 用R语言分析我的fitbit计步数据

    目标:把fitbit的每日运动记录导入到R语言中进行分析,画出统计图表来 已有原始数据:fitbit2014年每日的记录电子表格文件,全部数据点此下载,示例如下: 日期 消耗卡路里数 步 距离 攀爬楼 ...

  3. 使用R语言分析股价波动

    今天看的R语言.做个笔记. 使用R语言读取雅虎財经数据.分析微软公司(股票代码:MSFT)在2015年股价波动超过百分之十的日期. 然后通过检索新闻的方式,看看微软当天有什么新闻发生,导致股价波动. ...

  4. R语言分析(一)-----基本语法

      一, R语言所处理的工作层: 解释一下: 最下面的一层为数据源,往上是数据仓库层,往上是数据探索层,包括统计分析,统计查询,还有就是报告 再往上的三层,分别是数据挖掘,数据展现和数据决策. 由上图 ...

  5. 92、R语言分析案例

    1.读取数据 > bank=read.table("bank-full.csv",header=TRUE,sep=";") > 2.查看数据结构 & ...

  6. R语言分析(二)——薛毅R语言第二章后面习题解析

    包括2.2—2.6中间的习题,2.2的习题中第三问和第四问,应该有其他的解答方法,但我看他的题目,似乎是在A和B的基础上进行,所以就选择了使用for循环的方法 做着习题,又不断查着书,这样,书籍也熟悉 ...

  7. R语言重要数据集分析研究——需要整理分析阐明理念

    1.R语言重要数据集分析研究需要整理分析阐明理念? 上一节讲了R语言作图,本节来讲讲当你拿到一个数据集的时候如何下手分析,数据分析的第一步,探索性数据分析. 统计量,即统计学里面关注的数据集的几个指标 ...

  8. 大数据时代的精准数据挖掘——使用R语言

    老师简介: Gino老师,即将步入不惑之年,早年获得名校数学与应用数学专业学士和统计学专业硕士,有海外学习和工作的经历,近二十年来一直进行着数据分析的理论和实践,数学.统计和计算机功底强悍. 曾在某一 ...

  9. R语言安装xlsx包,读入excel表格

    开学的时候,男神给了数据(.xlsx格式)让用R语言分析分析,作为编程小白,读了一天都没读近R,更别提如何分析了. 现在小伙伴们都喜欢读txt 和csv格式的,好多xlsx的表格读不进R,将xlsx格 ...

随机推荐

  1. git之一: git基础

    参考: SourceTree使用 git教程 廖学风git  文档1 文档2 1. git 概念介绍 工作区: 就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区,工作区下面有. ...

  2. P1118 [USACO06FEB]数字三角形`Backward Digit Su`… 回溯法

    有这么一个游戏: 写出一个11至NN的排列a_iai​,然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少11,直到只剩下一个数字位置.下面是一 ...

  3. JavaSE | 接口| 枚举| 注释| 异常

    包: 1.包的作用:(1)避免类的同名(区分类):类的全名称:包.类名 回忆:java.util.Scannerjava.util.Arraysjava.lang.Stringj(2)可以限定某些类或 ...

  4. day 55 jQuery-part2

    这里有一个DOM对象转换成jQuery对象的方法,在jQuery对象后面加上索引值0即可得到效果如图所示: $("#btn")[0] 这里我们这里的索引值为0 只是一种写法而已,只 ...

  5. Largest Rectangle in a Histogram POJ - 2559 (单调栈)

    Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...

  6. Ef 自动迁移,日志

    Ef 迁移 在vs打开程序控制台 2,选择程序集 ,如果是初次,输入 Enable-Migrations,启动迁徙 3  添加迁移,完成修改 4,之后会自动生成迁移配置文件. 然后再上下文类中加入 两 ...

  7. A - Character Encoding HDU - 6397 - 方程整数解-容斥原理

    A - Character Encoding HDU - 6397 思路 : 隔板法就是在n个元素间的(n-1)个空中插入k-1个板,可以把n个元素分成k组的方法 普通隔板法 求方程 x+y+z=10 ...

  8. Spark 常见问题集合

    一.Spark 为什么比 MapReduce 要高效? 举一个例子: select a.state,count(*),AVERAGE(c.price) from a join b on (a.id=b ...

  9. How to use the Custom Material node and create Metaballs 官方视频学习笔记

    这个视频Youtube没有字幕着实蛋疼,本人英语很渣,几乎听不懂,里面有很多文档没讲的重要信息(文档讲的东西太少了). 不过学习过后你可以解锁好几个姿势.这个视频主要是教你做DistanceField ...

  10. getchar getche getch

    转至:https://blog.csdn.net/hairetz/article/details/4161954 (1) getch()和getche()函数     这两个函数都是从键盘上读入一个字 ...