![e1452c367cd2674945be85740b609f5c.png](https://i-blog.csdnimg.cn/blog_migrate/658a4764dbeef58d51ff765f6247c424.jpeg)
CDA数据分析师 出品
前言:
大数据使企业能够确定变量,预测自家公司的员工离职率。" ——《哈佛商业评论》2017年8月
"员工流失分析就是评估公司员工流动率的过程,目的是预测未来的员工离职状况,减少员工流失情况。" ——《福布斯》2016年3月
一、背景介绍
1. 数据来源
本项目数据集来自DataCastle训练赛。
【私信我领取】
2. 数据说明
比赛所用到的数据取自于IBM Watson Analytics分析平台分享的样例数据。我们只选取了其中的子集,并对数据做了一些预处理使数据更加符合逻辑回归分析模型的要求。
数据主要包括影响员工离职的各种因素(工资、出差、工作环境满意度、工作投入度、是否加班、是否升职、工资提升比例等)以及员工是否已经离职的对应记录。 数据分为训练数据和测试数据,分别保存在pfmtrain.csv和pfmtest.csv两个文件中。
![a05cbd5155194c578860ed41d8d8ae2d.png](https://i-blog.csdnimg.cn/blog_migrate/384ad9b9b25c9992c2399c8a7ab09cb1.jpeg)
![87856a0c25c5ab2ec19f63704f913e57.png](https://i-blog.csdnimg.cn/blog_migrate/d47e846825a38a0e92564c1738b779a0.jpeg)
![a0329cb99cc15d45b861fdc55d8d7c00.png](https://i-blog.csdnimg.cn/blog_migrate/7e72b3c95f5792c922cdc420fc9836bb.jpeg)
3. 分析目的
测试数据主要包括350条记录,30个字段,跟训练数据的不同是测试数据并不包括员工是否已经离职的记录,学员需要通过由训练数据所建立的模型以及所给的测试数据,得出测试数据相应的员工是否已经离职的预测。
二、数据探索性分析
1. 数据读取
pd.set_option('max_columns',50)train = pd.read_csv('pfm_train.csv')train.head()test = pd.read_csv('pfm_test.csv')test.head()
![38e653cca947c891f7db2983f46f2b80.png](https://i-blog.csdnimg.cn/blog_migrate/79e1c01af1c9d3d5006738bd5822154e.jpeg)
2. 数据信息探索
train.info()
![efdcae2ce25a4f51906ac670e8cafd33.png](https://i-blog.csdnimg.cn/blog_migrate/8f1302fd9023e727be2c3e07f9c0b49d.jpeg)
3. 删除无用特征
train['Over18'].value_counts() # 只包含一种属性train = train.drop(['EmployeeNumber','Over18'],axis=1) # 删除无用特征
4. 描述性统计
4.1 年龄、性别与是否离职关系图
f,ax=plt.subplots(1,2,figsize=(18,8))sns.violinplot("Gender","Age", hue="Attrition", data=train,split=True,ax=ax[0])ax[0].set_title('Gender and Age vs Attrtion');
![72a374da084c855265807a2cea5cafe0.png](https://i-blog.csdnimg.cn/blog_migrate/16fe7f8e35c53b1251260a2b22ca4f94.jpeg)
4.2 工作水平、部门与是否离职关系图
f,ax=plt.subplots(1,2,figsize=(20,8))sns.countplot('JobLevel',hue='Attrition',data=train,ax=ax[0])ax[0].set_title('JobLevel vs Attrition')sns.countplot('Department',hue='Attrition',data=train,ax=ax[1])ax[1].set_title('Department vs Attrition');
![7e0e9189bc075a261c6375edbaea392e.png](https://i-blog.csdnimg.cn/blog_migrate/241efbd00e4628d725b2edba8a03c571.jpeg)
4.3 月收入与离职情况关系图
f,ax=plt.subplots(1,2,figsize=(20,8))sns.distplot(train[train['Attrition']==1].MonthlyIncome,ax=ax[0])ax[0].set_title('MonthlyIncome vs Attrition=1')sns.distplot(train[train['Attrition']==0].MonthlyIncome,ax=ax[1])ax[1].set_title('MonthlyIncome vs Attrition=0');
![83b3d94790fc7d75b26cc00cdbba2a6b.png](https://i-blog.csdnimg.cn/blog_migrate/f310b8571ca24b400ee942a62bff80bc.jpeg)
4.4 婚姻状况、性别与是否离职关系图
sns.factorplot('MaritalStatus','Attrition',data=train,col='Gender');
![180d0adefae80ced20adee96ad2d622c.png](https://i-blog.csdnimg.cn/blog_migrate/e62c2678815a75b27a0e6ab838e92c0b.jpeg)
4.5 出差情况与是否离职关系图
f,ax=plt.subplots(1,2,figsize=(20,8))sns.barplot('BusinessTravel','Attrition',data=train,ax=ax[0])ax[0].set_title('BusinessTravel vs Attrition')sns.factorplot('BusinessTravel','Attrition',data=train,ax=ax[1])ax[1].set_title('BusinessTravel vs Attrition')plt.close(2);
![d0ce8fa33b369e9ba6a176f91665825b.png](https://i-blog.csdnimg.cn/blog_migrate/2c67babc11df0bd59dd231a257114ca0.jpeg)
综上图可以看出,离职人员特征包括偏年轻化,男性稍多,单身,月收入较低,加班等。
三、数据预处理
1. 字符型变量数值化
sklearn只允许数值类型变量进入模型学,所以需要提前将字符型变量数值化,为后续建模做准备。
# 筛选出字符型的变量col = []for i in train.columns: if train.loc[:,i].dtype=='object': col.append(i) # 导入相关模块进行数据类型转换from sklearn.preprocessing import OrdinalEncodertrain.loc[:,col] = OrdinalEncoder().fit_transform(train.loc[:,col])train.loc[:,col].head()
2. 相关性检验
逻辑回归属于广义线性回归,对自变量间的独立性有所要求,所以在这里我们使用皮尔逊相关系数对自变量进行相关性检验,对相关性较高的特征进行进一步筛选。
sns.heatmap(train.corr(),annot=True) #train.corr()-->correlation matrixfig=plt.gcf()fig.set_size_inches(20,20);
![6f3e3577584ae90e878042393c13d1ca.png](https://i-blog.csdnimg.cn/blog_migrate/8503af9c16d2bd5c8054eae2fd9db1e7.jpeg)
其中月收入与职位级别相关性呈强正相关关系,在这里我们保留职位级别,将月收入自变量删除。
3. 分类变量独热编码
为什么使用独热编码?
将离散特征通过one-hot编码映射到欧式空间,是因为,在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。
使用独热编码的优缺点?
· 优点:独热编码解决了分类器不好处理属性数据的问题,在一定程度上也起到了扩充特征的作用。它的值只有0和1,不同的类型存储在垂直的空间。
· 缺点:当类别的数量很多时,特征空间会变得非常大。在这种情况下,一般可以用PCA来减少维度。而且one hot encoding+PCA这种组合在实际中也非常有用。
X = train.loc[:,train.columns!='Attrition']Y = train.loc[:,'Attrition']X_onehot = X.drop(['Age','NumCompaniesWorked','PercentSalaryHike','TotalWorkingYears','YearsAtCompany','YearsInCurrentRole', 'YearsSinceLastPromotion', 'YearsWithCurrManager'],axis=1)from sklearn.preprocessing import OneHotEncoderX_onehot = OneHotEncoder().fit_transform(X_onehot)X_onehot = X_onehot.toarray()X_other = X.loc[:,['Age','NumCompaniesWorked','PercentSalaryHike','TotalWorkingYears','YearsAtCompany','YearsInCurrentRole', 'YearsSinceLastPromotion', 'YearsWithCurrManager']]X_other.shapeX = pd.concat([pd.DataFrame(X_onehot),X_other],axis=1)X.shape
四、模型学习
1. 划分训练集和验证集
from sklearn.model_selection import train_test_splitXtrain,Xtest,Ytrain,Ytest = train_test_split(X,Y,test_size=0.2,random_state=42)Xtrain.shape
2. 逻辑回归模型构建
from sklearn.linear_model import LogisticRegressionLR = LogisticRegression().fit(Xtrain,Ytrain)LR.score(Xtest,Ytest)
初步模型结果为0.84,还需待进一步调参。
3. 模型评估
from sklearn.metrics import recall_scorerecall_score(Ytest,LR.predict(Xtest))
1类样本召回率略低,只有0.42。可以考虑是否要做样本不均衡性处理。
五、模型调参
from sklearn.model_selection import GridSearchCVparams = {'penalty':['l1','l2'], 'C':np.arange(1,10,0.1)}gd = GridSearchCV(LogisticRegression(solver='liblinear'),param_grid=params,cv=10)gd.fit(Xtrain,Ytrain)print(gd.best_score_)print(gd.best_params_)LR_o = LogisticRegression(penalty='l1',C=1.2000000000000002).fit(Xtrain,Ytrain)LR_o.score(Xtest,Ytest)
![d1fcd558509ce91eccdb3626fccca0ca.png](https://i-blog.csdnimg.cn/blog_migrate/6ce9cd73781ae41f12795260a9883b4a.jpeg)
调参结果不错,训练集准确率提升到了0.88,验证集准确率也达到了0.85.
六、预测分析
模型建立完成之后,就需要读入测试集并进行预测。这里注意,需要对测试集按照训练集进行相同处理:包括删除变量、转换数据类型、独热编码等操作。
test = test.drop(['EmployeeNumber','Over18','MonthlyIncome'],axis=1)# 筛选出字符型的变量col = []for i in test.columns: if test.loc[:,i].dtype=='object': col.append(i) from sklearn.preprocessing import OrdinalEncodertest.loc[:,col] = OrdinalEncoder().fit_transform(test.loc[:,col])test.loc[:,col].head()test_onehot = test.drop(['Age','NumCompaniesWorked','PercentSalaryHike','TotalWorkingYears','YearsAtCompany','YearsInCurrentRole', 'YearsSinceLastPromotion', 'YearsWithCurrManager'],axis=1) from sklearn.preprocessing import OneHotEncodertest_onehot = OneHotEncoder().fit_transform(test_onehot)test_onehot = test_onehot.toarray()test_other = test.loc[:,['Age','NumCompaniesWorked','PercentSalaryHike','TotalWorkingYears','YearsAtCompany','YearsInCurrentRole', 'YearsSinceLastPromotion', 'YearsWithCurrManager']]test_other.shapeX = pd.concat([pd.DataFrame(test_onehot),test_other],axis=1)X.shapesolution = pd.DataFrame({'result':LR_o.predict(X)})solution
solution是通过我们已经调整好的模型对测试集做预测的最终结果。
![3837643fa621aa7dee309f3622bb5d2e.png](https://i-blog.csdnimg.cn/blog_migrate/39659e4b48a3068c6e6ce7f0ef7c9fed.jpeg)
得到结果之后,我们就可以上传至竞赛平台与真实值进行对比了。本课件中的代码结果在测试集中预测准确率达0.91428,预测结果显著并可以为实际业务进行辅助决策。
![26924df7e7b39527533421b2412f6d68.png](https://i-blog.csdnimg.cn/blog_migrate/6d148e7f1ace9f5c4322459b4f34f7b1.jpeg)
七、总结
通过对测试集的观察,该公司的员工离职现状可以总结如下:
· 当前离职率为11.82%;
· 由于企业培养人才是需要大量的成本, 为了防止人才再次流失, 因此应当注重解决人才的流失问题, 也就是留人, 另外如果在招人时注意某些问题, 也能在一定程度上减少人才流失. 因此, 这里可将对策分为两种, 一种是留人对策, 一种是招人对策。
留人对策
· 建立良好的薪酬制度
· 建立明朗的晋升机制
· 完善奖惩机制, 能者多劳, 也应多得
· 实现福利多样化, 增加员工对企业的忠诚度
· 重视企业文化建设, 树立共同的价值观
· 鼓励员工自我提升
· ………………
招人对策
· 明确企业招聘需求, 员工的能力应当与岗位需求相匹配,而不是为指标而招
· 与应聘者坦诚相见,不得为了指标而诓骗应聘者
· 招聘期间给予的相关承诺需要建立完备的兑现政策
· 欢迎优秀流失人才回归
· …………
![4552bd8d8b8ec74b1868bd55911559a6.png](https://i-blog.csdnimg.cn/blog_migrate/c2188cf124856134c975a102770d1381.jpeg)