80后領導罵我就離職,員工一言不合就離職怎么辦?用 Python 寫了個員工流失預測模型

 2023-10-22 阅读 25 评论 0

摘要:作者 | 真達、Mika來源 | CDA數據分析師(ID:cdacdacda)【導讀】今天教大家如何用 Python 寫一個員工流失預測模型。80后領導罵我就離職?Show me data,用數據說話。今天我們聊一聊 員工離職。點擊下方視頻,先睹為快:說道離職的原因

作者 | 真達、Mika

來源 | CDA數據分析師(ID:cdacdacda)

【導讀】

今天教大家如何用 Python 寫一個員工流失預測模型。

80后領導罵我就離職?Show me data,用數據說話。

今天我們聊一聊 員工離職。

點擊下方視頻,先睹為快:

說道離職的原因,可謂多種多樣。人們歸總了兩點:

一言不合就跳槽?1. 錢沒給到位

2. 心受委屈了

有人離職是因為“世界那么大,我想去看看”,也有人覺得“懷有絕技在身,不怕天下無路”。?

另一方面,員工離職對于企業而言有什么影響呢?

要知道,企業培養人才需要大量的成本,為了防止人才再次流失,員工流失分析就顯得十分重要了。這不僅僅是公司評估員工流動率的過程,通過找到導致員工流失的主要因素,預測未來的員工離職狀況,從而進一步減少員工流失。?

90后員工一批評就辭職段子,那么,哪些因素最容易導致員工離職呢?

這次我們用數據說話,教你如何用 Python 寫一個員工流失預測模型。

數據理解

我們分析了 kaggle 平臺分享的員工離職相關的數據集,共有 10 個字段 14999 條記錄。數據主要包括影響員工離職的各種因素(員工滿意度、績效考核、參與項目數、平均每月工作時長、工作年限、是否發生過工作差錯、5年內是否升職、部門、薪資)以及員工是否已經離職的對應記錄。字段說明如下:

讀入數據

#?導入包
import?numpy?as?np?
import?pandas?as?pd?
import?matplotlib.pyplot?as?plt?
import?seaborn?as?sns?from?pyecharts.charts?import?Bar,?Pie,?Page
from?pyecharts?import?options?as?opts?
from?pyecharts.globals?import?SymbolType,?WarningType
WarningType.ShowWarning?=?False
plt.rcParams['font.sans-serif']?=?['SimHei']??#?用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus']?=?False??#?用來正常顯示負號
#?讀入數據
df?=?pd.read_csv('HR_comma_sep.csv')
df.head()?

df.info()
<class?'pandas.core.frame.DataFrame'>
RangeIndex:?14999?entries,?0?to?14998
Data?columns?(total?10?columns):#???Column?????????????????Non-Null?Count??Dtype??
---??------?????????????????--------------??-----??0???satisfaction_level?????14999?non-null??float641???last_evaluation????????14999?non-null??float642???number_project?????????14999?non-null??int64??3???average_montly_hours???14999?non-null??int64??4???time_spend_company?????14999?non-null??int64??5???Work_accident??????????14999?non-null??int64??6???left???????????????????14999?non-null??int64??7???promotion_last_5years??14999?non-null??int64??8???sales??????????????????14999?non-null??object?9???salary?????????????????14999?non-null??object?
dtypes:?float64(2),?int64(6),?object(2)
memory?usage:?1.1+?MB
#?查看缺失值
print(df.isnull().any().sum())可以發現,數據質量良好,沒有缺失數據。

探索性分析

1、?描述性統計

df.describe().T

從上述描述性分析結果可以看出:?

  • 90后不高興就辭職、員工滿意度:范圍 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。?

年輕人一言不合就辭職?2、離職人數占比

整理數據后發現,總共有 14999 人,其中紅色部分代表離職人群,用數字 1 表示,藍色為未離職人群,用數字 0 表示。離職人數為 3571,占總人數的 23.8%。


3、員工滿意度

從直方圖可以看出,離職員工的滿意度評分明顯偏低,平均值為 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)*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),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'],?title='滿意度評分與是否離職')
bar1.render()?

4、績效考核

只會python能找到工作嗎。平均來看,績效考核成績在離職/未離職員工之間差異不大。在離職員工中,績效考核低、能力不夠和績效考核較高但工作壓力大、滿意度低、對薪資不滿意可能成為離職的原因。

5、平均每月工作時長

從直方圖可以看出,月工作時長正常的員工離職率最低。而工時過低、過高的員工離職人數最多。證明恰當的工作任務分配是非常重要的。?

6、參加項目數

一言不合就什么。從圖中可以看出:除項目數為2以外,隨著項目數的增多,離職率在增大,且項目數是7的時候,離職率達到了100%以上。綜上兩點,項目數2的離職率高,可能是這部分人工作能力不被認可。項目數6、7的總體少,離職率高,體現了他們的工作能力強,但同時工作壓力太大導致他們離職。

7、員工工齡

可以看到7年及以上工齡的員工基本沒有離職,只有工齡為5年的員工離職人數超過在職人數。可見工齡長于6年的員工,由于種種原因,其“忠誠度”較高。

而員工進入公司工作的第5年是一個較為“危險”的年份,也許是該企業的“5年之癢”,應當重點關注該階段的員工滿意度、職業晉升等情況,以順利過渡。

8、工作事故

python找工作難嗎?從圖中可看出,是否發生工作事故對員工離職的影響較小,可推測該企業處理工作事故的方式有可取之處。

9、職位晉升

從條形圖可以看出,在過去5年內獲得未晉升的員工離職率為24.2%,比獲得晉升的員工高4倍。設定良好的晉升通道可以很好的防止員工流失。

10、薪資水平

可明顯看出,薪資越高離職人數越少。證明為了減少離職率,提升員工福利待遇是一個可行的手段。

一言不合就辭職的員工。11、不同部門

可見各部門離職率如上圖,離職率由高到低,前三位分別是:人力部、財務部、科技部。之后依次是:支持部、銷售部、市場部、IT 部門、產品部、研發部、管理部。對于離職率過高的部門,應進一步分析關鍵原因。

數據預處理

由于 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()?

python怎么找工作,

建模分析

我們使用決策樹和隨機森林進行模型建置,首先導入所需包:?

from?sklearn.model_selection?import?train_test_split,?GridSearchCV
from?sklearn.tree?import?DecisionTreeClassifier
from?sklearn.ensemble?import?RandomForestClassifier
from?sklearn.metrics?import?classification_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)
print(X_train.shape,?X_test.shape,?y_train.shape,?y_test.shape)?

1、決策樹

我們使用決策樹進行建模,設置特征選擇標準為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???support0???????0.98??????0.99??????0.98??????91421???????0.97??????0.93??????0.95??????2857accuracy???????????????????????????0.98?????11999macro?avg???????0.97??????0.96??????0.97?????11999
weighted?avg???????0.98??????0.98??????0.97?????11999------------------------------------------------------------
測試集:???????????????precision????recall??f1-score???support0???????0.98??????0.99??????0.98??????22861???????0.97??????0.93??????0.95???????714accuracy???????????????????????????0.98??????3000macro?avg???????0.97??????0.96??????0.97??????3000
weighted?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

使用最優的模型重新評估訓練集和測試集效果:

#?訓練模型
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???support0???????0.98??????0.99??????0.98??????91421???????0.97??????0.93??????0.95??????2857accuracy???????????????????????????0.98?????11999macro?avg???????0.97??????0.96??????0.97?????11999
weighted?avg???????0.98??????0.98??????0.97?????11999------------------------------------------------------------
測試集:???????????????precision????recall??f1-score???support0???????0.98??????0.99??????0.98??????22861???????0.97??????0.93??????0.95???????714accuracy???????????????????????????0.98??????3000macro?avg???????0.97??????0.96??????0.97??????3000
weighted?avg???????0.98??????0.98??????0.98??????3000

可見在最優模型下模型效果有較大提升,1類的 F1-score 訓練集的分數為 0.99,測試集分數為 0.96。

學python找不到工作,2、隨機森林

下面使用集成算法隨機森林進行模型建置,并調整 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???support0???????1.00??????1.00??????1.00??????91421???????1.00??????0.99??????0.99??????2857accuracy???????????????????????????1.00?????11999macro?avg???????1.00??????0.99??????1.00?????11999
weighted?avg???????1.00??????1.00??????1.00?????11999------------------------------------------------------------
測試集:???????????????precision????recall??f1-score???support0???????0.99??????0.98??????0.99??????22861???????0.95??????0.97??????0.96???????714accuracy???????????????????????????0.98??????3000macro?avg???????0.97??????0.98??????0.97??????3000
weighted?avg???????0.98??????0.98??????0.98??????3000

可以看到在調優之后的隨機森林模型中,1類的 F1-score 訓練集的分數為 0.99,測試集分數為 0.98。

模型后續可優化方向:

  • 屬性:數值型數據常常是模型不穩定的來源,可考慮對其進行分箱;重要屬性篩選和字段擴充;

  • 90后一言不合就辭職,算法:其他的集成方法;不同效能評估下的作法調整。


更多精彩推薦
?Kubernetes 并非靈丹妙藥...
?“云”話數字經濟:2020 騰訊全球數字生態大會定檔 9 月!
?螞蟻上市分給員工 7000 億股權,曾有人 28 歲財務自由,這次又將產生多少千萬富翁?
?MIT 更新最大自然災害圖像數據集,囊括 19 種災害事件
?閑魚的云原生故事:靠什么支撐起萬億的交易規模?
?云交易所已成資金盤、殺豬盤重災區,曾被寄予厚望,如今罪惡叢生
點分享點點贊點在看

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/160986.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息