项目背景:
对于任何一家公司来讲,员工队伍的稳定性对于企业的发展都至关重要。之前马老师也说过,员工离职无非两个原因,其一是工资没有给到位,其二是员工干的不爽。所以员工离职预测的价值就愈发的凸显出来了,尤其对于HR部门,较早的预测可以帮助企业未雨绸缪,尽可能降低因为人员变动而给公司带来的损失。
本项目的目标:
读取员工离职数据集 初步的探索性分析 建立决策树模型 建立支持向量机模型、模型评估、项目总结。
本项目算法说明:
一、Decision Tree是一种用来分类和回归的无参监督学习方法。其目的是创建一种模型从数据特征中学习简单的决策规则来预测一个目标变量的值。
例如,在下面的图片中,决策树通过if-then-else的决策规则来学习数据,从而估测数一个正选函数图像,决策树越深入,决策树规则就越复杂并且对数据的拟合越好。
决策树的优点:
1、便于理解和解释,树的结构可以可视化出来。
2、训练需要的数据少。其他的机器学习模型通常需要数据规范化,比如构建虚拟变量和移除缺失值,不过需要注意的是,这种模型不支持缺失值。
3、由于训练决策树的数据点的数量导致决策树的使用开销呈指数分布(训练树模型的时间复杂度是参与训练数据点的对数值)
4、能够处理数值型数据和分类数据。其他的技术通常只能用来专门分析某一种变量行的数据集。
5、使用白盒模型。如果某种给定的情况在该模型中是可以观察的,那么就可以轻易的通过布尔值逻辑来解释这种情况。相比之下,在黑盒模型中的结果就很难说明清楚
6、可以通过数值统计测试来验证该模型。这对解释验证该模型的可靠性成为可能。
7、即使该模型假设的结果与真实模型所提供的数据有些违反,其表现依旧良好。
决策树的缺点包括:
1、决策树模型容易产生一个过于复杂的模型,这样的模型对数据的泛化性能会很差。这就是所谓的过拟合.一些策略像剪枝、设置叶节点所需的最小样本数或设置数的最大深度是避免出现 该问题最为有效地方法。
2、决策树可能是不稳定的,因为数据中的微小变化可能会导致完全不同的树生成。这个问题可以通过决策树的集成来得到缓解。
3、在多方面性能最优和简单化概念的要求下,学习一棵最优决策树通常是一个NP难问题。因此,实际的决策树学习算法是基于启发式算法,例如在每个节点进 行局部最优决策的贪心算法。这样的算法不能保证返回全局最优决策树。这个问题可以通过集成学习来训练多棵决策树来缓解,这多棵决策树一般通过对特征和样本有放回的随机采样来生成。
4、有些概念很难被决策树学习到,因为决策树很难清楚的表述这些概念。例如XOR,奇偶或者复用器的问题。
如果某些类在问题中占主导地位会使得创建的决策树有偏差。因此,我们建议在拟合前先对数据集进行平衡。
二、支持向量机(SVM)
1、支持向量机可以用于监督学习算法下的:分类、回归和异常检测;
2、支持向量机的优势:
1、在高维空间中非常高效。
2、即使在数据维度比样本数量大的情况下仍然有效。
3、在决策函数中使用训练集的子集,因此他也是高效利用内存的。
4、通用型:不同的核函数与特定的决策函数一一队形,常见的kernel已经提供,也可以指定定制的内核。
3、支持向量机的缺点:
1、如果也正数量比样本数量大的多,在选择核函数时要避免过度拟合,而且正则化项是非常重要的。
2、支持向量机不直接提供概率估计,这些都是使用岗位的五次交叉验证计算的。
读取数据
# 导入第三方库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns;sns.set()
%matplotlib inline
# 读取数据
df = pd.read_csv('/HR_comma_sep.csv')
df.head()
# 查看数据集的基本信息
df.info()
# 查看数据集的统计结果
df.describe().T
平均工作满意度在61%左右 平均绩效在72%左右 平均参与项目的数量为3.8 平均每月工作时间为201小时 该公司员工平均工作年限为3.5年 2%的员工在过去5年内得到岗位上的晋升 该公司的离职率为24%。
#查看数据集的大小
df.shape
df.columns
初步探索性分析
# 绘制箱形图,观察不同特征与离职之间的关系
plt.figure(figsize=(12,12))
plt.subplot(2,2,1)
sns.boxplot(x='left',y='satisfaction_level',data=df)
plt.subplot(2,2,2)
sns.boxplot(x='left',y='last_evaluation',data=df)
plt.subplot(2,2,3)
sns.boxplot(x='left',y='average_montly_hours',data=df)
plt.subplot(2,2,4)
sns.boxplot(x='left',y='time_spend_company',data=df)
离职员工的工作满意度在40%左右,未离职员工的工作满意度在70%左右。 离职员工的绩效评估较高,在0.8左右。 离职员工的工作时长较长,在225小时左右。 离职员工的工作年限在4年左右。
# 观察离职与参与项目的数量关系
sns.countplot(x='number_project',hue='left',data = df)
建立决策树模型
# 查看字段类型
df.dtypes
# 对类别变量进行处理
df['salary'].unique()
df['department'].unique()
# 将类别数据转换成数值数据并替换原有的数据
department_map = {'sales':0, 'accounting':1, 'hr':2, 'technical':3, 'support':4, 'management':5,
'IT':6, 'product_mng':7, 'marketing':8, 'RandD':9}
salary_map = {'low':0, 'medium':1, 'high':2}
df['department'] = df['department'].map(department_map)
df['salary'] = df['salary'].map(salary_map)
对类别型变量最常用的处理方式是one_hot_encoding编码方式。上面我采用的是映射的方式,将每一个类别值都映射为一个单独的数字编码。但是这种做法也存在一个问题,将类别特征映射为1,2,3等数值,计算机会认为它们之间存在着相对的大小关系。所以推荐大家使用one_hot_encoding编码。
# 热独编码
df1 = df
df1 = pd.get_dummies(df1)
df1.head()
# 切分训练集、测试集
label = df['left']
train = df.drop('left',axis = 1)
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(train,label,test_size = 0.3,random_state = 0)
# 导入决策树模型
from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier()
tree.fit(X_train,y_train)
tree.score(X_test,y_test)
# 测试集的预测结果
y_pred = tree.predict(X_test)
# 打出混淆矩阵值
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test,y_pred,labels=[0,1])
df['left'].value_counts()
#检查模型的各项评估指标
accuracy = (3402+1007)/(3402 + 60 + 31 +1007)
precision = 1007/(1007+31)
recall = 1007/(1007+60)
print(accuracy,precision,recall)
从三种评估指标可以看出,该树模型的效果还可以。 直接使用classification_report方法更加的方便,可以直接打印出recall,precision,f1-score
支持向量机SVM算法预测
from sklearn.svm import SVC
clf = SVC()
clf.fit(X_train,y_train)
y_pred = clf.predict(X_test)
confusion_matrix(y_test,y_pred,labels=[0,1])
svc_accuracy = (3462 + 94)/(3462 + 94 +0 + 944)
svc_recall = 94/(94+944)
svc_precision = 94/(94+0)
print(svc_accuracy,svc_recall,svc_precision)
在SVC算法中,使用算法默认的参数,其recall值和精度都较低。将未离职的人预测为离职的有0人,将离职的预测为未离职的人有944人。
# 使用Gridsearch函数,对模型进行参数调优
import time
from sklearn.model_selection import GridSearchCV
clf = SVC()
param_grid = {'C':[0.01,0.1,1,10,100],'gamma':[0.001,0.01,0.1,1,10] }
grid = GridSearchCV(clf,param_grid = param_grid,cv = 3,n_jobs = -1,verbose = 2)
t1 = time.time()
grid.fit(X_train,y_train)
t2 = time.time()
print('The train time usage:{}'.format(round((t2-t1),3)))
print(grid.best_score_)
print(grid.best_params_)
#采用最优的参数再次构建SVC模型
svc = SVC(C = 100,gamma = 0.01)
svc.fit(X_train,y_train)
y_pred = svc.predict(X_test)
confusion_matrix(y_test,y_pred,labels = [0,1])
accuracy = (3374+956)/(3374 + 88 + 82 + 956)
recall = 956/(956+82)
precision = 979/(956+88)
print(accuracy,recall,precision)
通过参数调整,SVC模型的预测准确度较原始模型有了较大的提升。
#展示决策树和支持向量机算法的预测结果
result = {'Decisiontree':[0.9786,0.9730,0.9369],'SVC':[0.9622,0.9210,0.9377]}
pd.DataFrame(result,index = ['accuracy','recall','precision'])
项目总结
1.理解数据,理解数据集中每个特征的实际意义。
2.探索性分析,理解影响因素与最终结果之间的关系,做到心中有数。此处定性的分析,也只能表达其相关性。
3.建立决策树模型和支持向量机模型,其中支持向量机模型涉及到了参数优化。通过accuracy,recall,precision评估两个模型的效果。
4.通过对比两个模型的效果,最终选择决策树算法。原因有两点,决策树算法简单,计算效率高,可解释性非常好。