作者:振达,Mika数据:振达后期:泽龙【攻略】今天教大家用Python写一个员工离职预测模型。公众号背景,回复关键词“辞职”获取完整数据。_给我看数据,用数据说话。_今天我们来说说员工离职。说起离职原因,可谓是五花八门。人们总结了两点:1.钱没有付到位2.觉得委屈。有人离职是因为“世界那么大,我想去看看”,也有人觉得“身怀绝技,不怕天下无路”。另一方面,员工离职对企业有什么影响?要知道,企业培养人才需要付出很大的成本。为了防止人才再次流失,员工流失的分析非常重要。这不仅仅是企业评估员工离职的过程,而是通过找出导致员工离职的主要因素,预测未来员工离职,进一步降低员工离职率。那么,哪些因素最容易导致员工离职呢?这次我们用数据说话,教大家如何用Python编写员工离职预测模型。_01、_数据理解我们分析了kaggle平台分享的员工离职相关数据集,共有10个领域14999条记录。数据主要包括影响员工离职的各种因素(员工满意度、绩效考核、参与项目数、月平均工时、工作年限、是否有工作失误、5年内是否晋升、部门、薪酬)以及是否雇员相应的离职记录。字段说明如下:_02,_readdataimportpackageimportnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltimportseabornassnsfrompyecharts.chartsimportBar,Pie,Pagefrompyechartsimportoptionsasoptsfrompyecharts.globalsimportSymbolType,WarningTypeWarningType.ShowWarning=Falseplt.rcParams['font.sans-serif']=['SimHei']#用来正常显示中文标签plt.rcParams['axes.unicode_minus']=False#用来正常显示负号读取数据df=pd.read_csv('HR_comma_sep.csv')df.head()df.info()RangeIndex:14999entries,0to14998Datacolumns(total10columns):#ColumnNon-NullCountDtype----------------------------0satisfaction_level14999non-nullfloat641last_evaluationon919float642number_project14999非空int643average_montly_hours14999非空int644time_spend_company14999非空int64nu5149llint646左14999非零INT647properion_last_5years14999non-nullint648销售14999非零对象9薪水14999非零对象dtypes:float64(2),int64(6),int64(6),对象(2),对象(2)+MB检查缺失值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。97.2%的员工离职率低于0.126分。可见,提高员工满意度可以有效防止员工流失。df.groupby('left')['satisfaction_level'].describe()defdraw_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)*100x_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),opt=optyaxis.'百分比',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=),itemstyle_opts=opts.ItemStyleOpts(border_color='black',border_width=0.3))bar.set_colors(['#BF4C51','#8CB9D0'])returnbarbar1=draw_numeric_graph(df_['ti'],sleft'],title='满意度和是否离职')bar1.render()绩效考核平均而言,离职员工和未离职员工的绩效考核差别不大。离职员工中,绩效考核低、能力不足、绩效考核高但工作压力大、满意度低、对薪酬不满意等可能是离职原因。平均月工时从直方图可以看出,月工时正常的员工离职率最低。工作时间太短和太长的员工离职最多。证明工作任务的正确分配非常重要。从图中可以看出参与的项目数:除项目数为2个外,随着项目数的增加,成交率增加,当项目数为7个时,成交率达到100%以上.综合以上两点,2号项目离职率高,可能是因为这些人的工作能力没有得到认可。项目6、7的人数普遍较少,离职率较高,反映出他们工作能力强,但同时工作压力过大,离职。从员工工龄来看,可以看到工龄7年及以上的员工基本没有离职,只有工龄5年的员工离职人数超过了在职人数。可见,工龄6年以上的员工,由于种种原因,“忠诚度”更高。员工进入公司的第五年,是比较“危险”的一年,或许是公司的“五年之痒”。现阶段应关注员工满意度和职业发展,确保平稳过渡。工伤事故从图中可以看出,工伤事故的发生对员工流失率影响不大。由此可见,该公司处理工伤事故的方式是有可取之处的。职位晋升从柱状图可以看出,近5年未晋升员工的离职率为24.2%,是晋升员工的4倍。建立良好的晋升渠道可以防止员工流失。从薪酬水平可以明显看出,薪酬越高,离职人数越少。事实证明,要想降低离职率,提高员工福利是一个可行的手段。不同部门可以看到每个部门的离职率如上图所示。周转率从高到低。排名前三位的是:人力资源部、财政部、科技部。依次为:支持部、销售部、市场部、IT部、产品部、研发部、管理部。对于离职率高的部门,应进一步分析关键原因。_04、_数据预处理由于sklearn在建模时不接受分类变量,所以我们主要对数据进行如下处理,方便后续建模分析:薪水级别salary是一个序数变量,因此将其字符类型转换为数值类型。Position是一个固定类型的变量,它是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,_建模分析我们使用决策树和随机森林进行模型构建,首先导入需要的包:fromsklearn.model_selectionimporttrain_test_split,GridSearchCVfromsklearn.treeimportDecisionTreeClassifierfromsklearn.ensembleimportRandomForestClassifierfromsklearn.metricsimportclassification_report,f1_score,roc_curve,plot_roc_curve然后划分训练集和测试集,采用分层抽样的方法,将80%的数据划分到训练集,20%的数据划分到测试集。x=df_dummies.drop('left',axis=1)y=df_dummies['left']X_train,X_test,y_train,y_test=train_test_split(x,y,test_size=0.2,stratify=y,random_state=2020)打印(X_train.shape,X_test.shape,y_train.shape,y_test.shape)Decisiontree我们使用决策树进行建模,设置特征选择标准为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('trainingset:',classification_report(y_train,train_pred))print('-'*60)print('testset:',classification_report(y_test,test_pred))trainingset:precisionrecallf1-score支持。090090.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?avg0.970.960.973000weightedavg0.980.980.983000假设我们重点是类别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('Trainingset:',classification_report(y_train,train_pred))print('-'*60)print('测试测试:',classification_report(y__test,test_pred))训练集:精密记忆回忆f1得分支持01.001.001.001.001.001.001.00914211.001.000.990.992857精度1.0011999MACROAVG1.000.991.0011999weightAVG1.001.001.0011999测试集: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训练Thescoreofthesetis0.99,andthescoreofthetestsetis0.96RandomForestNext,usetheensemblealgorithmRandomForesttobuildthemodel,andadjustthemax_depthparameter.rf_model=randomforestClassifier(n_estimators=1000,oob_score=true,n_jobs=-1,andand_state=0)parameters={'max_depth':np.arange(3,17,17,1)=10)GS.fit(X_train,y_train)print(GS.best_params_)print(GS.best_score_){'max_depth':16}0.988582151793161train_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))训练集:精度召回0支持0.01.001.00914211.000.990.992857准确性1.0011999宏观AVG1.001.001.001.0011999重量AVG1.001.001.001.00119999测试.991.000.99228610.990.970.98714Accuracy0.993000MacroAVG0.990.990.993000WeightedAVG0.990.990.993000在f1-SCORE训练器的随机森林模型中可以看到0.9-type9,0.9-type9测试集得分为0.98。模型未来可以优化:属性:数值数据往往是模型不稳定的来源,可以考虑分箱;重要属性筛选和领域拓展;算法:其他积分方法;根据不同的绩效评估实践进行调整。对项目分析感兴趣的朋友可以后台给小编留言哦!