机器学习实战-员工离职预测-分类预测模型(决策树、朴素贝叶斯、支持向量机)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


概述

提示:可以先看看这篇[员工离职预测模型-机器学习实战-逻辑回归-CSDN博客](http://t.csdnimg.cn/E8Dgt)

根据给定的影响员工离职的因素和员工是否离职的记录,分别建立多个分类预测模型:基于信息增益的决策树模型、基于基尼指数的决策树模型、朴素贝叶斯模型、支持向量机模型,预测有可能离职的员工;并对各模型进行模型评估。

在上篇博客中,我们通过用pandas进行数据清洗,数据转换,以及特征提取;用sklearn进行模型构建,模型评估,并进行相关预测。(用特征工程和相关分析的方法),从给定的影响员工离职的因素和员工是否离职的记录(训练集),建立一个逻辑回归模型预测有可能离职的员工。并在测试集上进行预测,给出每位员工离职的概率。

在本文中,我们会应用决策树、朴素贝叶斯、支持向量机这三个分类器,应用于上文的结果,看看分类的效果比较一下哪个分类器效果更好


一、预处理测试集

首先我们要知道,分类其实是一个有监督模型,有监督学习是机器学习的一个重要分支,其特点是使用带有标签的数据进行训练。训练数据包括输入特征和对应的目标标签。模型通过学习这些特征和标签之间的关系,来进行预测。

其次,分类问题是一种预测性建模问题,其中模型的目标是从给定的输入数据中预测离散类别的标签。输入数据由多个特征组成,目标是将每个样本分配到预定义的类别之一。

所以,在上篇博客中,我们得到的是predicted_probabilities.csv,里面只有这几个特征和Predicted Attrition Probability,是员工离职的概率,我们首先需要根据这个Predicted Attrition Probability的值,为我们的测试集打上标签,方便我们后续的分类任务。

而选择Predicted Attrition Probability超过多少时作为我们的正样本呢?
我是先看了一下训练集,其中共有1101个员工,里面有178个离职。为了使这个比值更加接近,经过对于不同阈值的测试,我发现,在设置阈值为0.5时,测试集有38个离职,测试集共有351个员工,所以这个阈值我认为划分的是比较合理的。

于是,代码如下,先增加一列Attrition,然后把Predicted Attrition Probability值大于0.5的打上标签1,小于等于0.5的打上标签0。最后还要删除Predicted Attrition Probability这一列,因为这对于我们的分类是没作用的,是一个干扰

import pandas as pd

# 加载数据
data_path = "YourPath\\predicted_probabilities.csv"
data = pd.read_csv(data_path)

# 添加“Attrition”列
data['Attrition'] = data['Predicted Attrition Probability'].apply(lambda x: 1 if x > 0.5 else 0)

# 删除“Predicted Attrition Probability”列
data = data.drop(columns=['Predicted Attrition Probability'])

# 查看处理后的数据
print(data.head())

# 保存处理后的数据到文件
processed_data_path = "YourPath\\test_data.csv"
data.to_csv(processed_data_path, index=False)

二、使用决策树进行分类(分别基于信息增益和基尼指数)

1.引入库和加载数据

因为后面要可视化把决策树画出来,所有要使用matplotlib,需要设置Matplotlib支持中文显示

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
from sklearn.metrics import accuracy_score

# 设置Matplotlib支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像时负号 '-' 显示为方块的问题

# 1. 加载数据
train_data_path = "YourPath\\pfm_train.csv"
test_data_path = "YourPath\\test_data.csv"
train_data = pd.read_csv(train_data_path)
test_data = pd.read_csv(test_data_path)

2.数据预处理

对非数值型特征进行编码

我们的数据里面的特征是非常多的,但并不是所有的都是数值型的比如特征Department和JobRole,于是我采用label_encoders对对非数值型特征进行编码,它可以将分类变量转换为数值型标签。执行过程就是对训练数据的每一列进行检查,如果列的数据类型是对象(字符串类型),就使用 LabelEncoder 进行编码。

为什么用label_encoders进行编码?
LabelEncoder 是一个简单而常用的工具,可以将分类文本数据转换为数值标签。例如,假设某列包含类别 [“red”, “blue”, “green”],LabelEncoder 会将其转换为 [0, 1, 2]。
于是,代码如下:

# 2. 数据预处理
# 对非数值型特征进行编码
label_encoders = {}
for column in train_data.columns:
    if train_data[column].dtype == 'object':
        label_encoders[column] = LabelEncoder()
        train_data[column] = label_encoders[column].fit_transform(train_data[column])

for column in test_data.columns:
    if test_data[column].dtype == 'object':
        if column in label_encoders:
            test_data[column] = label_encoders[column].transform(test_data[column])
        else:
            label_encoders[column] = LabelEncoder()
            test_data[column] = label_encoders[column].fit_transform(test_data[column])

细心的小伙伴可能发现了,为什么有的地方用的是fit_transform,而有的地方用的transform呢?
他们的区别如下:
fit_transform:首先拟合数据,然后转换它。通常用于训练数据。
transform:直接转换数据,而不进行拟合。通常用于测试数据,确保使用与训练数据相同的编码方式。

提取特征和目标变量

这里就没什么可以过多的介绍了,我们的目标变量是Attrition,除了目标变量的,就都是我们的特征了。代码如下:

# 提取特征和目标变量
X_train = train_data.drop(columns=['Attrition'])
y_train = train_data['Attrition']
X_test = test_data.drop(columns=['Attrition'])
y_test = test_data['Attrition']

3. 使用信息增益构建决策树

这里直接调用sklearn库里面的函数DecisionTreeClassifier即可,criterion='entropy’指定了决策树在选择划分特征时使用的信息增益(entropy)作为衡量标准。然后把随机数种子设置成了42,保证了代码的可重复性,每次运行代码时,决策树的结构会保持一致。后面使用fit()函数来拟合模型,也就是训练模型,拟合其中的特征与目标变量。总体代码如下:

dt_info_gain = DecisionTreeClassifier(criterion='entropy', random_state=42)
dt_info_gain.fit(X_train, y_train)

4. 使用基尼指数构建决策树

同上,只需要把criterion改成gini即可,不写也行,默认使用的就是基尼指数。

# 4. 使用基尼指数构建决策树
dt_gini = DecisionTreeClassifier(criterion='gini', random_state=42)
dt_gini.fit(X_train, y_train)

5. 预测并获取分类结果

调用predict()函数进行预测,选择accuracy_score作为评判性能的指标。

# 预测并获取分类结果
y_pred_info_gain = dt_info_gain.predict(X_test)
accuracy_info_gain = accuracy_score(y_test, y_pred_info_gain)
print(f"信息增益决策树的准确率: {accuracy_info_gain:.2f}")

y_pred_gini = dt_gini.predict(X_test)
accuracy_gini = accuracy_score(y_test, y_pred_gini)
print(f"基尼指数决策树的准确率: {accuracy_gini:.2f}")

6. 可视化处理

使用matplotlib进行画图可视化,把特征名字转化成列表,代码如下:

# 可视化信息增益决策树
plt.figure(figsize=(60, 25))
plot_tree(dt_info_gain, feature_names=X_train.columns.tolist(), class_names=['Not Attrition', 'Attrition'], filled=True, fontsize=12)
plt.title('信息增益决策树分类器',fontsize=20)
plt.show()

# 可视化基尼指数决策树
plt.figure(figsize=(60, 25))
plot_tree(dt_gini, feature_names=X_train.columns.tolist(), class_names=['Not Attrition', 'Attrition'], filled=True, fontsize=12)
plt.title('基尼指数决策树分类器',fontsize=20)
plt.show()

7. 结果展示

准确度:

在这里插入图片描述

信息增益决策分类树

在这里插入图片描述

基尼指数决策分类树

在这里插入图片描述
这两棵树实在太大了,实在是设计的不美观,确实不知道怎么兼顾树的图形和字的大小。

三、基于朴素贝叶斯的分类器模型

1.导包和数据预处理

基本都同上,没什么区别,代码如下:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score, classification_report

# 1. 加载数据
train_data_path = "YourPath\\pfm_train.csv"
test_data_path = "YourPath\\test_data.csv"
train_data = pd.read_csv(train_data_path)
test_data = pd.read_csv(test_data_path)

# 2. 数据预处理
# 对非数值型特征进行编码
label_encoders = {}
for column in train_data.columns:
    if train_data[column].dtype == 'object':
        label_encoders[column] = LabelEncoder()
        train_data[column] = label_encoders[column].fit_transform(train_data[column])

for column in test_data.columns:
    if test_data[column].dtype == 'object':
        if column in label_encoders:
            test_data[column] = label_encoders[column].transform(test_data[column])
        else:
            label_encoders[column] = LabelEncoder()
            test_data[column] = label_encoders[column].fit_transform(test_data[column])

# 提取特征和目标变量
X_train = train_data.drop(columns=['Attrition'])
y_train = train_data['Attrition']
X_test = test_data.drop(columns=['Attrition'])
y_test = test_data['Attrition']

2.训练朴素贝叶斯模型

调用sklearn库里面的GaussianNB,并用fit来拟合函数,代码如下:

# 3. 训练朴素贝叶斯模型
nb_model = GaussianNB()
nb_model.fit(X_train, y_train)

3.预测并评估模型

使用accuracy_score计算准确率,并根据这个打印分类报告,代码如下:

# 4. 预测并评估模型
y_pred = nb_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"朴素贝叶斯模型的准确率: {accuracy:.2f}")

# 打印分类报告
print("分类报告:")
print(classification_report(y_test, y_pred, target_names=['Not Attrition', 'Attrition']))

4.运行结果

在这里插入图片描述

四、基于支持向量机的分类器模型

1.导包和数据预处理

跟上面的过程基本相同,代码如下:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report

# 1. 加载数据
train_data_path = "YourPath\\pfm_train.csv"
test_data_path = "YourPath\\test_data.csv"
train_data = pd.read_csv(train_data_path)
test_data = pd.read_csv(test_data_path)

# 2. 数据预处理
# 对非数值型特征进行编码
label_encoders = {}
for column in train_data.columns:
    if train_data[column].dtype == 'object':
        label_encoders[column] = LabelEncoder()
        train_data[column] = label_encoders[column].fit_transform(train_data[column])

for column in test_data.columns:
    if test_data[column].dtype == 'object':
        if column in label_encoders:
            test_data[column] = label_encoders[column].transform(test_data[column])
        else:
            label_encoders[column] = LabelEncoder()
            test_data[column] = label_encoders[column].fit_transform(test_data[column])

# 提取特征和目标变量
X_train = train_data.drop(columns=['Attrition'])
y_train = train_data['Attrition']
X_test = test_data.drop(columns=['Attrition'])
y_test = test_data['Attrition']

但是,这个要多一个步骤,特征标准化,因为这个支持向量机的算法特性和对于距离的敏感性有关,代码如下:

# 特征标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

2.训练SVM模型

采用线性的SVM进行拟合模型,看看效果怎么样,如果不行,则再换高斯的SVM进行拟合模型,代码如下:

# 3. 训练SVM模型
svm_model = SVC(kernel='linear', random_state=42)
svm_model.fit(X_train, y_train)

3.预测并评估模型

没什么可说的,代码如下:

# 4. 预测并评估模型
y_pred = svm_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"SVM模型的准确率: {accuracy:.2f}")

# 打印分类报告
print("分类报告:")
print(classification_report(y_test, y_pred, target_names=['Not Attrition', 'Attrition']))

运行结果

在这里插入图片描述

结果对比

决策树(信息增益):准确率:0.83
决策树(基尼指数):准确率:0.84
朴素贝叶斯:准确率:0.79
支持向量机(SVM):准确率:0.95

结果分析

  1. 决策树:信息增益和基尼指数的决策树表现相近,这两种方法在处理数据集时可能会有略微不同的选择和划分,导致最终准确率有些许差异。但这俩的差别不大,说明在这个数据集上两者的表现基本一致。
  2. 朴素贝叶斯模型的性能相对于决策树和SVM模型较低。特别是在处理少数类别时,精准率和F1分数较低,但召回率较高。这是因为朴素贝叶斯假设特征之间相互独立,而在实际数据中,这种假设往往不成立,导致模型在某些情况下表现不佳。
  3. SVM模型表现最好,准确率达到了0.95。SVM通过找到最大化类别间隔的超平面来进行分类,通常在高维空间下表现出色。其对异常值和噪声有较好的鲁棒性,能够有效处理复杂的数据分布。

总结

本文归纳使用了一下分类算法里面常见的模型,比如决策树、朴素贝叶斯、支持向量机,应用在我们的这个员工离职预测里面,而应用分类器模型的常见思路就是:导包、数据预处理、训练模型、预测评估、可视化或者直接打印输出结果。

希望对您能有帮助,如果可以的话,希望您能给我点个赞,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值