【阿旭机器学习实战】【35】员工离职率预测---决策树与随机森林预测

简介: 【阿旭机器学习实战】【35】员工离职率预测---决策树与随机森林预测

1.获取数据

关注GZH:阿旭算法与机器学习,回复:“ML35”即可获取本文数据集、源码与项目文档

# 引入工具包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as matplot
import seaborn as sns
%matplotlib inline
# 读入数据到Pandas Dataframe "df"
df = pd.read_csv('HR_comma_sep.csv', index_col=None)

2.数据预处理

# 检测是否有缺失数据
df.isnull().any()
satisfaction_level       False
last_evaluation          False
number_project           False
average_montly_hours     False
time_spend_company       False
Work_accident            False
left                     False
promotion_last_5years    False
sales                    False
salary                   False
dtype: bool
# 数据的样例
df.head()
satisfaction_level last_evaluation number_project average_montly_hours time_spend_company Work_accident left promotion_last_5years sales salary
0 0.38 0.53 2 157 3 0 1 0 sales low
1 0.80 0.86 5 262 6 0 1 0 sales medium
2 0.11 0.88 7 272 4 0 1 0 sales medium
3 0.72 0.87 5 223 5 0 1 0 sales low
4 0.37 0.52 2 159 3 0 1 0 sales low

注:“turnover”列为标签:1表示离职,0表示不离职,其他列均为特征值

# 重命名
df = df.rename(columns={'satisfaction_level': 'satisfaction', 
                        'last_evaluation': 'evaluation',
                        'number_project': 'projectCount',
                        'average_montly_hours': 'averageMonthlyHours',
                        'time_spend_company': 'yearsAtCompany',
                        'Work_accident': 'workAccident',
                        'promotion_last_5years': 'promotion',
                        'sales' : 'department',
                        'left' : 'turnover'
                        })
# 将预测标签‘是否离职’放在第一列
front = df['turnover']
df.drop(labels=['turnover'], axis=1, inplace = True)
df.insert(0, 'turnover', front)
df.head()
turnover satisfaction evaluation projectCount averageMonthlyHours yearsAtCompany workAccident promotion department salary
0 1 0.38 0.53 2 157 3 0 0 sales low
1 1 0.80 0.86 5 262 6 0 0 sales medium
2 1 0.11 0.88 7 272 4 0 0 sales medium
3 1 0.72 0.87 5 223 5 0 0 sales low
4 1 0.37 0.52 2 159 3 0 0 sales low

3.分析数据

  • 14999 条数据, 每一条数据包含 10 个特征
  • 总的离职率: 24%
  • 平均满意度为 0.61
df.shape
(14999, 10)
# 特征数据类型. 
df.dtypes
turnover                 int64
satisfaction           float64
evaluation             float64
projectCount             int64
averageMonthlyHours      int64
yearsAtCompany           int64
workAccident             int64
promotion                int64
department              object
salary                  object
dtype: object
turnover_rate = df.turnover.value_counts() / len(df)
turnover_rate
0    0.761917
1    0.238083
Name: turnover, dtype: float64
# 显示统计数据
df.describe()
turnover satisfaction evaluation projectCount averageMonthlyHours yearsAtCompany workAccident promotion
count 14999.000000 14999.000000 14999.000000 14999.000000 14999.000000 14999.000000 14999.000000 14999.000000
mean 0.238083 0.612834 0.716102 3.803054 201.050337 3.498233 0.144610 0.021268
std 0.425924 0.248631 0.171169 1.232592 49.943099 1.460136 0.351719 0.144281
min 0.000000 0.090000 0.360000 2.000000 96.000000 2.000000 0.000000 0.000000
25% 0.000000 0.440000 0.560000 3.000000 156.000000 3.000000 0.000000 0.000000
50% 0.000000 0.640000 0.720000 4.000000 200.000000 3.000000 0.000000 0.000000
75% 0.000000 0.820000 0.870000 5.000000 245.000000 4.000000 0.000000 0.000000
max 1.000000 1.000000 1.000000 7.000000 310.000000 10.000000 1.000000 1.000000
# 分组的平均数据统计
turnover_Summary = df.groupby('turnover')
turnover_Summary.mean()
satisfaction evaluation projectCount averageMonthlyHours yearsAtCompany workAccident promotion
turnover
0 0.666810 0.715473 3.786664 199.060203 3.380032 0.175009 0.026251
1 0.440098 0.718113 3.855503 207.419210 3.876505 0.047326 0.005321

3.1 相关性分析

# 相关性矩阵
corr = df.corr()
#corr = (corr)
sns.heatmap(corr, 
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values)
corr
turnover satisfaction evaluation projectCount averageMonthlyHours yearsAtCompany workAccident promotion
turnover 1.000000 -0.388375 0.006567 0.023787 0.071287 0.144822 -0.154622 -0.061788
satisfaction -0.388375 1.000000 0.105021 -0.142970 -0.020048 -0.100866 0.058697 0.025605
evaluation 0.006567 0.105021 1.000000 0.349333 0.339742 0.131591 -0.007104 -0.008684
projectCount 0.023787 -0.142970 0.349333 1.000000 0.417211 0.196786 -0.004741 -0.006064
averageMonthlyHours 0.071287 -0.020048 0.339742 0.417211 1.000000 0.127755 -0.010143 -0.003544
yearsAtCompany 0.144822 -0.100866 0.131591 0.196786 0.127755 1.000000 0.002120 0.067433
workAccident -0.154622 0.058697 -0.007104 -0.004741 -0.010143 0.002120 1.000000 0.039245
promotion -0.061788 0.025605 -0.008684 -0.006064 -0.003544 0.067433 0.039245 1.000000


正相关的特征:

  • projectCount VS evaluation: 0.349333
  • projectCount VS averageMonthlyHours: 0.417211
  • averageMonthlyHours VS evaluation: 0.339742

负相关的特征:

  • satisfaction VS turnover: -0.388375
# 比较离职和未离职员工的满意度
emp_population = df['satisfaction'][df['turnover'] == 0].mean()
emp_turnover_satisfaction = df[df['turnover']==1]['satisfaction'].mean()
print( '未离职员工满意度: ' + str(emp_population))
print( '离职员工满意度: ' + str(emp_turnover_satisfaction) )
未离职员工满意度: 0.666809590479516
离职员工满意度: 0.44009801176140917

3.2 进行 T-Test


进行一个 t-test, 看离职员工的满意度是不是和未离职员工的满意度明显不同

import scipy.stats as stats
stats.ttest_1samp(a = df[df['turnover']==1]['satisfaction'], # 离职员工的满意度样本
                  popmean = emp_population)  # 未离职员工的满意度均值
Ttest_1sampResult(statistic=-51.3303486754725, pvalue=0.0)

T-Test 显示pvalue (0) 非常小, 所以他们之间是显著不同的

degree_freedom = len(df[df['turnover']==1])
LQ = stats.t.ppf(0.025,degree_freedom)  # 95%致信区间的左边界
RQ = stats.t.ppf(0.975,degree_freedom)  # 95%致信区间的右边界
print ('The t-分布 左边界: ' + str(LQ))
print ('The t-分布 右边界: ' + str(RQ))
The t-分布 左边界: -1.9606285215955626
The t-分布 右边界: 1.9606285215955621
# 概率密度函数估计
fig = plt.figure(figsize=(15,4),)
ax=sns.kdeplot(df.loc[(df['turnover'] == 0),'evaluation'] , color='b',shade=True,label='no turnover')
ax=sns.kdeplot(df.loc[(df['turnover'] == 1),'evaluation'] , color='r',shade=True, label='turnover')
ax.set(xlabel='Employee Evaluation', ylabel='Frequency')
ax.legend()
plt.title('Employee Evaluation Distribution - Turnover V.S. No Turnover')
Text(0.5, 1.0, 'Employee Evaluation Distribution - Turnover V.S. No Turnover')

# 概率密度函数估计
fig = plt.figure(figsize=(15,4))
ax=sns.kdeplot(df.loc[(df['turnover'] == 0),'averageMonthlyHours'] , color='b',shade=True, label='no turnover')
ax=sns.kdeplot(df.loc[(df['turnover'] == 1),'averageMonthlyHours'] , color='r',shade=True, label='turnover')
ax.legend()
ax.set(xlabel='Employee Average Monthly Hours', ylabel='Frequency')
plt.title('Employee AverageMonthly Hours Distribution - Turnover V.S. No Turnover')
Text(0.5, 1.0, 'Employee AverageMonthly Hours Distribution - Turnover V.S. No Turnover')

# 概率密度函数估计
fig = plt.figure(figsize=(15,4))
ax=sns.kdeplot(df.loc[(df['turnover'] == 0),'satisfaction'] , color='b',shade=True, label='no turnover')
ax=sns.kdeplot(df.loc[(df['turnover'] == 1),'satisfaction'] , color='r',shade=True, label='turnover')
plt.title('Employee Satisfaction Distribution - Turnover V.S. No Turnover')
ax.legend()
<matplotlib.legend.Legend at 0x281a5a6b820>

from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, precision_score, recall_score, confusion_matrix, precision_recall_curve
# 将string类型转换为整数类型
df["department"] = df["department"].astype('category').cat.codes
df["salary"] = df["salary"].astype('category').cat.codes
# 产生X, y
target_name = 'turnover'
X = df.drop('turnover', axis=1)
y = df[target_name]
# 将数据分为训练和测试数据集
# 注意参数 stratify = y 意味着在产生训练和测试数据中, 离职的员工的百分比等于原来总的数据中的离职的员工的百分比
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.15, random_state=123, stratify=y)
df.head()
turnover satisfaction evaluation projectCount averageMonthlyHours yearsAtCompany workAccident promotion department salary
0 1 0.38 0.53 2 157 3 0 0 7 1
1 1 0.80 0.86 5 262 6 0 0 7 2
2 1 0.11 0.88 7 272 4 0 0 7 2
3 1 0.72 0.87 5 223 5 0 0 7 1
4 1 0.37 0.52 2 159 3 0 0 7 1

4. 建立预测模型:Decision Tree V.S. Random Forest

from sklearn.metrics import roc_auc_score
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier
# 决策树
dtree = tree.DecisionTreeClassifier(
    criterion='entropy',
    #max_depth=3, # 定义树的深度, 可以用来防止过拟合
    min_weight_fraction_leaf=0.01 # 定义叶子节点最少需要包含多少个样本(使用百分比表达), 防止过拟合
    )
dtree = dtree.fit(X_train,y_train)
print ("\n\n ---决策树---")
dt_roc_auc = roc_auc_score(y_test, dtree.predict(X_test))
print ("决策树 AUC = %2.2f" % dt_roc_auc)
print(classification_report(y_test, dtree.predict(X_test)))
# 随机森林
rf = RandomForestClassifier(
    criterion='entropy',
    n_estimators=1000, 
    max_depth=None, # 定义树的深度, 可以用来防止过拟合
    min_samples_split=10, # 定义至少多少个样本的情况下才继续分叉
    #min_weight_fraction_leaf=0.02 # 定义叶子节点最少需要包含多少个样本(使用百分比表达), 防止过拟合
    )
rf.fit(X_train, y_train)
print ("\n\n ---随机森林---")
rf_roc_auc = roc_auc_score(y_test, rf.predict(X_test))
print ("随机森林 AUC = %2.2f" % rf_roc_auc)
print(classification_report(y_test, rf.predict(X_test)))
---决策树---
决策树 AUC = 0.93
              precision    recall  f1-score   support
           0       0.97      0.98      0.97      1714
           1       0.93      0.89      0.91       536
    accuracy                           0.96      2250
   macro avg       0.95      0.93      0.94      2250
weighted avg       0.96      0.96      0.96      2250
 ---随机森林---
随机森林 AUC = 0.97
              precision    recall  f1-score   support
           0       0.98      1.00      0.99      1714
           1       0.99      0.94      0.97       536
    accuracy                           0.98      2250
   macro avg       0.99      0.97      0.98      2250
weighted avg       0.98      0.98      0.98      2250

5. 模型评估

5.1ROC 图


# ROC 图
from sklearn.metrics import roc_curve
rf_fpr, rf_tpr, rf_thresholds = roc_curve(y_test, rf.predict_proba(X_test)[:,1])
dt_fpr, dt_tpr, dt_thresholds = roc_curve(y_test, dtree.predict_proba(X_test)[:,1])
plt.figure()
# 随机森林 ROC
plt.plot(rf_fpr, rf_tpr, label='Random Forest (area = %0.2f)' % rf_roc_auc)
# 决策树 ROC
plt.plot(dt_fpr, dt_tpr, label='Decision Tree (area = %0.2f)' % dt_roc_auc)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Graph')
plt.legend(loc="lower right")
plt.show()

5.2通过决策树分析不同的特征的重要性

## 画出决策树特征的重要性 ##
importances = rf.feature_importances_
feat_names = df.drop(['turnover'],axis=1).columns
indices = np.argsort(importances)[::-1]
plt.figure(figsize=(12,6))
plt.title("Feature importances by RandomForest")
plt.bar(range(len(indices)), importances[indices], color='lightblue',  align="center")
plt.step(range(len(indices)), np.cumsum(importances[indices]), where='mid', label='Cumulative')
plt.xticks(range(len(indices)), feat_names[indices], rotation='vertical',fontsize=14)
plt.xlim([-1, len(indices)])
plt.show()

## 画出决策树的特征的重要性 ##
importances = dtree.feature_importances_
feat_names = df.drop(['turnover'],axis=1).columns
indices = np.argsort(importances)[::-1]
plt.figure(figsize=(12,6))
plt.title("Feature importances by Decision Tree")
plt.bar(range(len(indices)), importances[indices], color='lightblue',  align="center")
plt.step(range(len(indices)), np.cumsum(importances[indices]), where='mid', label='Cumulative')
plt.xticks(range(len(indices)), feat_names[indices], rotation='vertical',fontsize=14)
plt.xlim([-1, len(indices)])
plt.show()


相关文章
|
8小时前
|
机器学习/深度学习 数据可视化 数据挖掘
从菜鸟到高手,一图胜千言!Python数据分析与机器学习中的数据可视化实战秘籍!
【7月更文挑战第24天】在数据科学中,数据可视化是探索与沟通的关键。从Matplotlib的基础绘图到Seaborn的统计图形,再到Plotly的交互式图表,这些工具助你成为数据叙事大师。示例代码涵盖正弦波图、小费散点图及鸢尾花分布图,展现从简单到复杂的可视化之旅。掌握这些技巧,你就能更有效地解析和呈现数据故事。
|
1天前
|
机器学习/深度学习 数据可视化 开发者
视觉的力量!Python 机器学习模型评估,Matplotlib 与 Seaborn 如何助力决策更明智?
【7月更文挑战第23天】在Python机器学习中,模型评估不可或缺。Matplotlib与Seaborn作为数据可视化工具,助力洞察模型性能。Matplotlib基础灵活,构建复杂图表;Seaborn在其上层,简化绘图,提升美观。从折线图追踪损失到条形图对比准确率,两者互补,促进高效决策制定。尽管Matplotlib掌控力强,但Seaborn友好快捷,适于统计图形。结合使用,可将数据转化成深刻见解。
|
7天前
|
机器学习/深度学习 算法 算法框架/工具
模型训练实战:选择合适的优化算法
【7月更文第17天】在模型训练这场智慧与计算力的较量中,优化算法就像是一位精明的向导,引领着我们穿越复杂的损失函数地形,寻找那最低点的“宝藏”——最优解。今天,我们就来一场模型训练的实战之旅,探讨两位明星级的优化算法:梯度下降和Adam,看看它们在不同战场上的英姿。
38 5
|
11天前
|
机器学习/深度学习 数据处理 Python
机器学习实战:房价预测项目
【7月更文挑战第13天】本文详细介绍了基于机器学习的房价预测项目的实战过程。从数据准备、特征工程、模型构建到结果评估,每一步都至关重要。通过合理的特征选择和模型优化,我们可以构建出性能优异的房价预测模型,为房地产行业的决策提供有力支持。未来,随着机器学习技术的不断发展和应用场景的不断拓展,房价预测模型将更加智能化和精准化。
|
11天前
|
机器学习/深度学习 算法 Python
强化学习(Reinforcement Learning, RL)** 是一种机器学习技术,其中智能体(Agent)通过与环境(Environment)交互来学习如何执行决策以最大化累积奖励。
强化学习(Reinforcement Learning, RL)** 是一种机器学习技术,其中智能体(Agent)通过与环境(Environment)交互来学习如何执行决策以最大化累积奖励。
|
22天前
|
数据采集 人工智能 监控
阿里云百炼模型训练实战流程:从入门到实战应用
【7月更文第2天】阿里云百炼是AI大模型开发平台,提供一站式服务,涵盖模型训练到部署。用户从注册登录、创建应用开始,选择模型框架,配置资源。接着,进行数据准备、预处理,上传至阿里云OSS。模型训练涉及设置参数、启动训练及调优。训练后,模型导出并部署为API,集成到应用中。平台提供监控工具确保服务性能。通过百炼,开发者能高效地进行大模型实战,开启AI创新。
229 2
|
27天前
|
机器学习/深度学习 数据采集 JavaScript
技术心得记录:机器学习——用逻辑回归及随机森林实现泰坦尼克号的生存预测
技术心得记录:机器学习——用逻辑回归及随机森林实现泰坦尼克号的生存预测
24 0
|
1月前
|
机器学习/深度学习 搜索推荐 数据挖掘
机器学习多场景实战(二 )
这是一个关于机器学习应用于电商平台用户行为分析的概要,包括以下几个关键点: 1. **月活跃用户分析**:通过购买记录确定活跃用户,计算每月活跃用户数。 2. **月客单价**:定义为月度总销售额除以月活跃用户数,衡量平均每位活跃用户的消费金额。 3. **新用户占比**:基于用户首次购买和最近购买时间判断新老用户,计算每月新用户的购买比例。 4. **激活率计算**:定义为当月与上月都有购买行为的用户数占上月购买用户数的比例,反映用户留存情况。 5. **Pandas数据操作**:使用Pandas库进行数据集合并(concat和merge),以及计算不同维度的组合。
|
1月前
|
机器学习/深度学习 数据采集 搜索推荐
机器学习多场景实战(一)
机器学习已广泛应用,从个性化推荐到金融风控,数据指标是评估其效果的关键。数据指标包括活跃用户(DAU, MAU, WAU)衡量用户粘性,新增用户量和注册转化率评估营销效果,留存率(次日、7日、30日)反映用户吸引力,行为指标如PV(页面浏览量)、UV(独立访客)和转化率分析用户行为。产品数据指标如GMV、ARPU、ARPPU和付费率关注业务变现,推广付费指标(CPM, CPC, CPA等)则关乎广告效率。找到北极星指标,如月销售额或用户留存,可指导业务发展。案例中涉及电商销售数据,计算月销售金额、环比、销量、新用户占比、激活率和留存率以评估业务表现。
|
1月前
|
机器学习/深度学习 人工智能 算法
【机器学习】AI在空战决策中的崛起:从理论到实践的跨越
【机器学习】AI在空战决策中的崛起:从理论到实践的跨越
142 0

热门文章

最新文章