【阿旭机器学习实战】【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()


相关文章
|
机器学习/深度学习 存储 算法
决策树和随机森林在机器学习中的应用
在机器学习领域,决策树(Decision Tree)和随机森林(Random Forest)是两种非常流行且强大的分类和回归算法。它们通过模拟人类决策过程,将复杂的数据集分割成易于理解和处理的子集,从而实现对新数据的准确预测。
539 10
|
机器学习/深度学习 算法 前端开发
【机器学习】Bagging和随机森林
【机器学习】Bagging和随机森林
|
机器学习/深度学习 数据可视化 大数据
机器学习与大数据分析的结合:智能决策的新引擎
机器学习与大数据分析的结合:智能决策的新引擎
755 15
|
机器学习/深度学习 数据采集 算法
机器学习在医疗诊断中的前沿应用,包括神经网络、决策树和支持向量机等方法,及其在医学影像、疾病预测和基因数据分析中的具体应用
医疗诊断是医学的核心,其准确性和效率至关重要。本文探讨了机器学习在医疗诊断中的前沿应用,包括神经网络、决策树和支持向量机等方法,及其在医学影像、疾病预测和基因数据分析中的具体应用。文章还讨论了Python在构建机器学习模型中的作用,面临的挑战及应对策略,并展望了未来的发展趋势。
1081 1
|
机器学习/深度学习 数据采集 监控
探索机器学习:从数据到决策
【9月更文挑战第18天】在这篇文章中,我们将一起踏上一段激动人心的旅程,穿越机器学习的世界。我们将探讨如何通过收集和处理数据,利用算法的力量来预测未来的趋势,并做出更加明智的决策。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和思考方式。
|
机器学习/深度学习 算法 Python
从菜鸟到大师:一棵决策树如何引领你的Python机器学习之旅
【9月更文挑战第9天】在数据科学领域,机器学习如同璀璨明珠,吸引无数探索者。尤其对于新手而言,纷繁复杂的算法常让人感到迷茫。本文将以决策树为切入点,带您从Python机器学习的新手逐步成长为高手。决策树以其直观易懂的特点成为入门利器。通过构建决策树分类器并应用到鸢尾花数据集上,我们展示了其基本用法及效果。掌握决策树后,还需深入理解其工作原理,调整参数,并探索集成学习方法,最终将所学应用于实际问题解决中,不断提升技能。愿这棵智慧之树助您成为独当一面的大师。
207 3
|
机器学习/深度学习 算法 前端开发
R语言基础机器学习模型:深入探索决策树与随机森林
【9月更文挑战第2天】决策树和随机森林作为R语言中基础且强大的机器学习模型,各有其独特的优势和适用范围。了解并熟练掌握这两种模型,对于数据科学家和机器学习爱好者来说,无疑是一个重要的里程碑。希望本文能够帮助您更好地理解这两种模型,并在实际项目中灵活应用。
|
机器学习/深度学习 算法 Python
决策树下的智慧果实:Python机器学习实战,轻松摘取数据洞察的果实
【9月更文挑战第7天】当我们身处数据海洋,如何提炼出有价值的洞察?决策树作为一种直观且强大的机器学习算法,宛如智慧之树,引领我们在繁复的数据中找到答案。通过Python的scikit-learn库,我们可以轻松实现决策树模型,对数据进行分类或回归分析。本教程将带领大家从零开始,通过实际案例掌握决策树的原理与应用,探索数据中的秘密。
212 1
|
机器学习/深度学习 算法 数据可视化
【机器学习】决策树------迅速了解其基本思想,Sklearn的决策树API及构建决策树的步骤!!!
【机器学习】决策树------迅速了解其基本思想,Sklearn的决策树API及构建决策树的步骤!!!
|
6月前
|
机器学习/深度学习 数据采集 人工智能
【机器学习算法篇】K-近邻算法
K近邻(KNN)是一种基于“物以类聚”思想的监督学习算法,通过计算样本间距离,选取最近K个邻居投票决定类别。支持多种距离度量,如欧式、曼哈顿、余弦相似度等,适用于分类与回归任务。结合Scikit-learn可高效实现,需合理选择K值并进行数据预处理,常用于鸢尾花分类等经典案例。(238字)

热门文章

最新文章