欢迎光临
我们一直在努力

如何使用Keras和TensorFlow构建一个深度学习模型来预测员工保留

作为Write for DOnations计划的一部分,作者选择了女性 代码来接受捐赠。

介绍

Keras是一个用Python编写的神经网络API。 它运行在TensorFlowCNTKTheano 之上 它是这些深度学习框架的高级抽象,因此使实验更快更容易。 Keras是模块化的,这意味着实现是无缝的,因为开发人员可以通过添加模块快速扩展模型。

TensorFlow是一个用于机器学习的开源软件库。 它适用于涉及数组的计算; 因此,对于您将在本教程中构建的模型,它是一个很好的选择。 此外,TensorFlow允许在CPU或GPU上执行代码,这是一个非常有用的功能,尤其是当您使用大量数据集时。

在本教程中,您将构建一个深度学习模型,用于预测员工离开公司的可能性。 保留最好的员工是大多数组织的重要因素。 要构建模型,您将使用Kaggle提供的此数据集该数据集具有衡量公司员工满意度的功能。 要创建此模型,您将使用Keras 顺序图层为模型构建不同的图层。

先决条件

在开始本教程之前,您需要以下内容:

第1步 – 数据预处理

数据预处理对于以深度学习模型可以接受的方式准备数据是必要的。 如果数据中存在分类变量 ,则必须将它们转换为数字,因为算法只接受数字。 分类变量表示由名称表示的定量数据。 在此步骤中,您将使用pandas加载数据集, pandas是一个数据操作Python库。

在开始数据预处理之前,您将激活您的环境并确保为您的计算机安装了所有必需的软件包。 使用conda来安装kerastensorflow是有利的,因为它将处理这些包的任何必要依赖项的安装,并确保它们与kerastensorflow兼容。 通过这种方式,使用Anaconda Python发行版是数据科学相关项目的不错选择。

进入您在先决条件教程中创建的环境:

conda activate my_env

运行以下命令以安装kerastensorflow

conda install tensorflow keras

现在,打开Jupyter Notebook开始吧。 通过在终端上键入以下命令打开Jupyter Notebook:

jupyter notebook

注意:如果您是从远程服务器工作,则需要使用SSH隧道来访问您的笔记本。 请重新访问必备教程的第2步 ,以获取有关设置SSH隧道的详细说明。 您可以使用本地计算机中的以下命令来启动SSH隧道:

ssh -L 8888:localhost:8888 your_username@your_server_ip

访问Jupyter Notebook后,单击anaconda3文件,然后单击屏幕顶部的New ,并选择Python 3以加载新笔记本。

现在,您将导入项目所需的模块,然后将数据集加载到笔记本单元格中。 您将加载pandas模块以操作数据,并将numpy加载为将数据转换为numpy数组。 您还将所有字符串格式的列转换为要处理的计算机的数值。

将以下代码插入笔记本单元格,然后单击“运行”

import pandas as pdimport numpy as npdf = pd.read_csv("https://raw.githubusercontent.com/mwitiderrick/kerasDO/master/HR_comma_sep.csv")

你已经进口了numpypandas 然后,您使用pandas加载模型的数据集。

您可以使用head()来查看正在使用的数据集。 这是一个来自pandas的有用功能,允许您查看数据帧的前五个记录。 将以下代码添加到笔记本单元格,然后运行它:

df.head()

Alt检查数据集的头部

您现在将继续将分类列转换为数字。 您可以通过将它们转换为虚拟变量来实现 虚拟变量通常是1和0,表示存在或不存在分类特征。 在这种情况下,您还可以通过删除第一个虚拟对象来避免虚拟变量陷阱

注意:虚拟变量陷阱是两个或多个变量高度相关的情况。 这会导致您的模型表现不佳。 因此,您将丢弃一个虚拟变量以始终保留N-1个虚拟变量。 可以删除任何虚拟变量,因为只要您保留N-1个虚拟变量就没有偏好。 例如,如果您有一个开/关开关。 创建虚拟变量时,您将获得两列: on列和off列。 您可以删除其中一列,因为如果该开关未打开,则它将关闭。

将此代码插入下一个笔记本单元格并执行它:

feats = ['department','salary']df_final = pd.get_dummies(df,columns=feats,drop_first=True)

feats = ['department','salary']定义要为其创建虚拟变量的两列。 pd.get_dummies(df,columns=feats,drop_first=True)将生成员工保留模型所需的数字变量。 它通过将您定义的feats从分类转换为数字变量来实现。

第1步

您已加载数据集并将薪水和部门列转换为keras深度学习模型可以接受的格式。 在下一步中,您将数据集拆分为训练和测试集。

第2步 – 分离您的培训和测试数据集

您将使用scikit-learn将数据集拆分为训练和测试集。 这是必要的,因此您可以使用部分员工数据来训练模型及其中的一部分来测试其性能。 在构建深度学习模型时,以这种方式拆分数据集是一种常见的做法。

在数据集中实现此拆分非常重要,因此您构建的模型在培训过程中无权访问测试数据。 这可确保模型仅从训练数据中学习,然后您可以使用测试数据测试其性能。 如果您在培训过程中将模型暴露给测试数据,那么它会记住预期的结果。 因此,它无法准确预测未见的数据。

您将首先从scikit-learn包导入train_test_split模块。 这是将提供拆分功能的模块。 将此代码插入下一个笔记本单元格并运行:

from sklearn.model_selection import train_test_split

导入train_test_split模块后,您将使用数据集中的左列来预测员工是否将离开公司。 因此,您的深度学习模型必须不与本专栏联系。 将以下内容插入单元格以删除左列:

X = df_final.drop(['left'],axis=1).valuesy = df_final['left'].values

您的深度学习模型希望将数据作为数组获取。 因此,您使用numpy将数据转换为具有.values属性的numpy数组。

您现在已准备好将数据集转换为测试和训练集。 您将使用70%的数据进行培训,30%的数据用于测试。 训练比率超过测试比率,因为您需要将大部分数据用于训练过程。 如果需要,您还可以试验训练集的80%和测试集的20%。

现在将此代码添加到下一个单元格并运行以将训练和测试数据拆分为指定的比率:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

第2步

您现在已将数据转换为Keras期望的数据( numpy数组),并将您的数据拆分为训练和测试集。 您将在本教程后面将此数据传递给keras模型。 您需要先转换数据,然后在下一步中完成。

第3步 – 转换数据

在构建深度学习模型时,通常很好的做法是扩展数据集以使计算更有效。 在此步骤中,您将使用StandardScaler缩放数据; 这将确保您的数据集值具有零均值和单位变量。 这会将数据集转换为正态分布。 您将使用scikit-learn StandardScaler将功能扩展到相同的范围内。 这会将值转换为平均值为0且标准差为1.此步骤非常重要,因为您要比较具有不同测量值的要素; 因此通常在机器学习中需要它。

要缩放训练集和测试集,请将此代码添加到笔记本单元格并运行它:

from sklearn.preprocessing import StandardScalersc = StandardScaler()X_train = sc.fit_transform(X_train)X_test = sc.transform(X_test)

在这里,您首先导入StandardScaler并调用它的实例。 然后,您可以使用其fit_transform方法来扩展训练和测试集。

您已将所有数据集要素缩放到相同范围内。 您可以在下一步开始构建人工神经网络。

第4步 – 构建人工神经网络

现在,您将使用keras构建深度学习模型。 为此,您将导入keras ,默认情况下将使用tensorflow作为后端。 keras ,您将导入Sequential模块以初始化人工神经网络 人工神经网络是使用来自人脑工作的灵感构建的计算模型。 您还将导入Dense模块,这将为您的深度学习模型添加图层。

构建深度学习模型时,通常指定三种图层类型:

  • 输入图层是您将传递数据集要素的图层。 此层中没有计算。 它用于将功能传递给隐藏层。
  • 隐藏层通常是输入层和输出层之间的层 – 并且可以有多个层。 这些层执行计算并将信息传递到输出层。
  • 输出层代表神经网络的一层,它将在训练模型后为您提供结果。 它负责生成输出变量。

要导入KerasSequentialDense模块,请在笔记本单元格中运行以下代码:

import kerasfrom keras.models import Sequentialfrom keras.layers import Dense

您将使用Sequential初始化线性层。 由于这是一个分类问题 ,您将创建一个分类器变量。 分类问题是您已标记数据并希望根据标记数据进行一些预测的任务。 将此代码添加到笔记本中以创建分类器变量:

classifier = Sequential()

您已使用Sequential初始化分类器。

您现在可以开始向网络添加图层。 在下一个单元格中运行此代码:

classifier.add(Dense(9, kernel_initializer = "uniform",activation = "relu", input_dim=18))

您可以在分类器上使用.add()函数添加图层并指定一些参数:

  • 第一个参数是网络应具有的节点数。 不同节点之间的连接形成了神经网络。 确定节点数量的策略之一是获取输入层和输出层中节点的平均值。

  • 第二个参数是kernel_initializer. 当您适合深度学习模型时,权重将初始化为接近零但不为零的数字。 要实现此目的,请使用均匀分布初始化程序。 kernel_initializer是初始化权重的函数。

  • 第三个参数是activation功能。 您的深度学习模型将通过此功能学习。 通常有线性和非线性激活功能。 您使用relu激活功能,因为它可以很好地概括您的数据。 线性函数不适合这类问题,因为它们形成一条直线。

  • 最后一个参数是input_dim ,它表示数据集中的input_dim数。

现在,您将添加将为您提供预测的输出图层:

classifier.add(Dense(1, kernel_initializer = "uniform",activation = "sigmoid"))

输出层采用以下参数:

  • 输出节点的数量。 您希望得到一个输出:如果员工离开公司。 因此,您指定一个输出节点。

  • 对于kernel_initializer您使用sigmoid激活功能,以便您可以获得员工离开的概率。 如果您正在处理两个以上的类别,则可以使用softmax激活函数,该函数是sigmoid激活函数的变体。

接下来,您将向神经网络应用梯度下降 这是一种优化策略,可以在培训过程中减少错误。 梯度下降是通过降低成本函数来调整神经网络中随机分配的权重的方式, 成本函数是神经网络根据其预期输出执行的程度的度量。

梯度下降的目的是获得误差最小的点。 这是通过找到成本函数最小值的位置来完成的,这被称为局部最小值 在梯度下降中,您可以区分以找到特定点的斜率,并找出斜率是负还是正 – 您将下降到成本函数的最小值。 有几种类型的优化策略,但在本教程中您将使用一种称为adam的流行方法。

将此代码添加到笔记本单元格并运行它:

classifier.compile(optimizer= "adam",loss = "binary_crossentropy",metrics = ["accuracy"])

应用梯度下降是通过compile函数完成的,该函数采用以下参数:

  • optimizer是梯度下降。
  • loss是您将在梯度下降中使用的函数。 由于这是二进制分类问题,因此使用binary_crossentropy loss函数。
  • 最后一个参数是您将用于评估模型的指标。 在这种情况下,您希望在进行预测时根据其准确性对其进行评估。

您已准备好将分类器适合您的数据集。 .fit()通过.fit()方法实现了这一点。 为此,请将以下代码插入笔记本并运行它以使模型适合您的数据集:

classifier.fit(X_train, y_train, batch_size = 10, epochs = 1)

拟合数据集

.fit()方法需要几个参数:

  • 第一个参数是具有这些功能的训练集。

  • 第二个参数是您正在进行预测的列。

  • batch_size表示在每轮训练中将通过神经网络的样本数。

  • epochs表示数据集将通过神经网络传递的次数。 时间越长,运行模型所需的时间越长,这也会给您带来更好的结果。

第4步

您已经创建了深度学习模型,对其进行了编译,并将其拟合到您的数据集中。 您已准备好使用深度学习模型进行一些预测。 在下一步中,您将开始使用模型尚未看到的数据集进行预测。

第5步 – 在测试集上运行预测

要开始进行预测,您将在您创建的模型中使用测试数据集。 Keras使您可以使用.predict()函数进行预测。

在下一个笔记本单元格中插入以下代码以开始进行预测:

y_pred = classifier.predict(X_test)

由于您已经使用训练集训练了分类器,因此该代码将使用训练过程中的学习来对测试集进行预测。 这将为您提供员工离职的可能性。 您将以50%及以上的概率工作,以表明员工离开公司的可能性很高。

在笔记本单元格中输入以下代码行以设置此阈值:

y_pred = (y_pred > 0.5)

您已使用预测方法创建预测,并设置阈值以确定员工是否可能离开。 为了评估模型对预测的执行情况,接下来将使用混淆矩阵

第6步 – 检查混淆矩阵

在此步骤中,您将使用混淆矩阵来检查正确和不正确预测的数量。 混淆矩阵(也称为误差矩阵)是方阵,其报告分类器的真阳性(tp),假阳性(fp),真阴性(tn)和假阴性(fn)的数量。

  • 真正的正面是模型正确预测正类(也称为敏感性或回忆)的结果。
  • 真正的否定是模型正确预测负类的结果。
  • 误报是模型错误地预测正类的结果。
  • 假阴性是模型错误地预测负类的结果。

要实现这一点,您将使用scikit-learn提供的混淆矩阵。

在下一个笔记本单元格中插入此代码以导入scikit-learn混淆矩阵:

from sklearn.metrics import confusion_matrixcm = confusion_matrix(y_test, y_pred)cm

混淆矩阵输出意味着您的深度学习模型产生了3305 + 375正确预测和106 + 714错误预测。 您可以使用以下公式计算精度: (3305 + 375) / 4500 数据集中的观察总数为4500.这使您的准确率达到81.7%。 这是一个非常好的准确率,因为您可以从模型中获得至少81%的正确预测。

array([[3305,  106],       [ 714,  375]])

您已使用混淆矩阵评估了模型。 接下来,您将使用您开发的模型进行单一预测。

第7步 – 进行单一预测

在此步骤中,您将根据模型中的一名员工的详细信息进行单一预测。 您将通过预测单个员工离开公司的可能性来实现这一目标。 您将此员工的功能传递给predict方法。 正如您之前所做的那样,您也将扩展功能并将它们转换为numpy数组。

要传递员工的功能,请在单元格中运行以下代码:

new_pred = classifier.predict(sc.transform(np.array([[0.26,0.7 ,3., 238., 6., 0.,0.,0.,0., 0.,0.,0.,0.,0.,1.,0., 0.,1.]])))

这些功能代表单个员工的功能。 如第1步中的数据集所示,这些功能表示:满意度,最后评估,项目数量等。 正如您在第3步中所做的那样,您必须以深度学习模型可以接受的方式转换要素。

使用以下代码添加50%的阈值:

new_pred = (new_pred > 0.5)new_pred

该阈值表示如果概率超过50%,员工将离开公司。

您可以在输出中看到员工不会离开公司:

array([[False]])

您可能决定为模型设置更低或更高的阈值。 例如,您可以将阈值设置为60%:

new_pred = (new_pred > 0.6)new_pred

这个新门槛仍然显示员工不会离开公司:

array([[False]])

在此步骤中,您已经了解了如何根据单个员工的功能进行单一预测。 在下一步中,您将致力于提高模型的准确性。

第8步 – 提高模型的准确性

如果您多次训练模型,您将获得不同的结果。 每次训练的准确性都有很大的差异。 为了解决这个问题,您将使用K-fold交叉验证 通常,K设置为10.在该技术中,模型在前9次折叠上进行训练并在最后一次折叠上进行测试。 此迭代继续,直到使用了所有折叠。 每次迭代都给出了自己的准确性。 模型的准确性成为所有这些精度的平均值。

keras使您能够通过KerasClassifier包装器实现K-fold交叉验证。 这个包装器来自scikit-learn交叉验证。 您将首先导入cross_val_score交叉验证函数和KerasClassifier 为此,请在笔记本单元格中插入并运行以下代码:

from keras.wrappers.scikit_learn import KerasClassifierfrom sklearn.model_selection import cross_val_score

要创建要传递给KerasClassifier的函数,请将此代码添加到下一个单元格:

def make_classifier():    classifier = Sequential()    classifier.add(Dense(9, kernel_initializer = "uniform", activation = "relu", input_dim=18))    classifier.add(Dense(1, kernel_initializer = "uniform", activation = "sigmoid"))    classifier.compile(optimizer= "adam",loss = "binary_crossentropy",metrics = ["accuracy"])    return classifier

在这里,您创建一个您将传递给KerasClassifier的函数 – 该函数是分类器所期望的参数之一。 该函数是您之前使用的神经网络设计的包装器。 传递的参数也类似于本教程前面使用的参数。 在函数中,首先使用Sequential()初始化分类器,然后使用Dense添加输入和输出层。 最后,编译分类器并返回它。

要将您构建的函数传递给KerasClassifier ,请将以下代码行添加到笔记本中:

classifier = KerasClassifier(build_fn = make_classifier, batch_size=10, nb_epoch=1)

KerasClassifier有三个参数:

  • build_fn :具有神经网络设计的功能
  • batch_size :每次迭代中通过网络传递的样本数
  • nb_epoch :网络将运行的时期数

接下来,使用Scikit-learn的cross_val_score应用交叉验证。 将以下代码添加到笔记本单元格并运行它:

accuracies = cross_val_score(estimator = classifier,X = X_train,y = y_train,cv = 10,n_jobs = -1)

由于您已将折叠数指定为10,因此,此功能将为您提供十个精度。因此,您将其分配给精度变量,然后使用它来计算平均精度。 它需要以下参数:

  • estimator :您刚刚定义的分类estimator
  • X :训练集功能
  • y :训练集中要预测的值
  • cv :折叠次数
  • n_jobs :要使用的CPU数量(将其指定为-1将使用所有可用的CPU)

现在您已应用交叉验证,您可以计算精度的均值和方差。 要实现此目的,请将以下代码插入笔记本:

mean = accuracies.mean()mean

在您的输出中,您将看到平均值为83%:

0.8343617910685696

要计算精度的方差,请将此代码添加到下一个笔记本单元格:

variance = accuracies.var()variance

您看到方差为0.00109。 由于方差非常低,这意味着您的模型表现非常好。

0.0010935021002275425

通过使用K-Fold交叉验证,您已经提高了模型的准确性。 在下一步中,您将处理过度拟合问题。

第9步 – 添加Dropout正则化以对抗过度拟合

预测模型容易出现称为过度拟合的问题。 这是一种场景,模型会记录训练集中的结果,并且无法概括它未见过的数据。 通常,当您的精度差异非常大时,您会观察到过度拟合。 为了帮助您在模型中过度拟合,您将为模型添加一个图层。

在神经网络中, 辍学正则化是通过在神经网络中添加Dropout层来抵抗过度拟合的技术。 它有一个rate参数,指示每次迭代时将停用的神经元数量。 停用神经元的过程通常是随机的。 在这种情况下,您指定0.1作为速率意味着1%的神经元将在训练过程中停用。 网络设计保持不变。

要添加Dropout图层,请将以下代码添加到下一个单元格:

from keras.layers import Dropoutclassifier = Sequential()classifier.add(Dense(9, kernel_initializer = "uniform", activation = "relu", input_dim=18))classifier.add(Dropout(rate = 0.1))classifier.add(Dense(1, kernel_initializer = "uniform", activation = "sigmoid"))classifier.compile(optimizer= "adam",loss = "binary_crossentropy",metrics = ["accuracy"])

您已在输入和输出图层之间添加了Dropout图层。 设置辍学率为0.1意味着在训练过程中15个神经元将停用,以使分类器不会过度拟合训练集。 添加Dropout和输出图层后,您就像之前一样编译了分类器。

你通过Dropout层努力在这一步中过度拟合。 接下来,您将通过调整创建模型时使用的参数来进一步改进模型。

第10步 – 超参数调整

网格搜索是一种可用于试验不同模型参数的技术,以获得能够提供最佳精度的参数。 该技术通过尝试不同的参数并返回给出最佳结果的参数来实现此目的。 您将使用网格搜索来搜索深度学习模型的最佳参数。 这有助于提高模型的准确性。 scikit-learn提供GridSearchCV函数来启用此功能。 您现在将继续修改make_classifier函数以尝试不同的参数。

将此代码添加到笔记本中以修改make_classifier函数,以便您可以测试不同的优化器函数:

from sklearn.model_selection import GridSearchCVdef make_classifier(optimizer):    classifier = Sequential()    classifier.add(Dense(9, kernel_initializer = "uniform", activation = "relu", input_dim=18))    classifier.add(Dense(1, kernel_initializer = "uniform", activation = "sigmoid"))    classifier.compile(optimizer= optimizer,loss = "binary_crossentropy",metrics = ["accuracy"])    return classifier

您已经开始导入GridSearchCV 然后,您已对make_classifier函数进行了更改,以便您可以尝试使用不同的优化器。 您已初始化分类器,添加了输入和输出层,然后编译了分类器。 最后,您已经返回了分类器,因此您可以使用它。

与第4步中一样,插入此行代码以定义分类器:

classifier = KerasClassifier(build_fn = make_classifier)

您已使用KerasClassifier定义了分类器,该分类器需要通过build_fn参数的函数。 您调用了KerasClassifier并传递了make_classifier创建的make_classifier函数。

现在,您将继续设置一些您想要试验的参数。 将此代码输入单元格并运行:

params = {    'batch_size':[20,35],    'epochs':[2,3],    'optimizer':['adam','rmsprop']}

在这里,您添加了不同的批量大小,时期数和不同类型的优化器功能。

对于像您这样的小型数据集,批量大小在20-35之间是好的。 对于大型数据集,重要的是尝试更大的批量大小。 使用较少的时间数来确保您在短时间内获得结果。 但是,您可以尝试使用更大的数字,这需要一段时间才能完成,具体取决于服务器的处理速度。 来自kerasadamrmsprop优化器是这种神经网络的不错选择。

现在,您将使用您定义的不同参数来使用GridSearchCV函数搜索最佳参数。 将其输入下一个单元格并运行它:

grid_search = GridSearchCV(estimator=classifier,                           param_grid=params,                           scoring="accuracy",                           cv=2)

网格搜索功能需要以下参数:

  • estimator :您正在使用的分类estimator
  • param_grid :您要测试的参数集。
  • scoring :您正在使用的指标。
  • cv :你要测试的折叠数量。

接下来,您将此grid_search适合您的训练数据集:

grid_search = grid_search.fit(X_train,y_train)

您的输出将类似于以下内容,请稍等片刻才能完成:

Epoch 1/25249/5249 [==============================] - 1s 228us/step - loss: 0.5958 - acc: 0.7645Epoch 2/25249/5249 [==============================] - 0s 82us/step - loss: 0.3962 - acc: 0.8510Epoch 1/25250/5250 [==============================] - 1s 222us/step - loss: 0.5935 - acc: 0.7596Epoch 2/25250/5250 [==============================] - 0s 85us/step - loss: 0.4080 - acc: 0.8029Epoch 1/25249/5249 [==============================] - 1s 214us/step - loss: 0.5929 - acc: 0.7676Epoch 2/25249/5249 [==============================] - 0s 82us/step - loss: 0.4261 - acc: 0.7864

将以下代码添加到笔记本单元格中,以使用best_params_属性从此搜索中获取最佳参数:

best_param = grid_search.best_params_best_accuracy = grid_search.best_score_

您现在可以使用以下代码检查模型的最佳参数:

best_param

您的输出显示最佳批量大小为20 ,最佳时期数为2 ,并且adam优化程序最适合您的模型:

{'batch_size': 20, 'epochs': 2, 'optimizer': 'adam'}

您可以检查模型的最佳精度。 best_accuracy number表示运行网格搜索后从最佳参数获得的最高精度:

best_accuracy

您的输出将类似于以下内容:

0.8533193637489285

您已经使用GridSearch来确定分类器的最佳参数。 您已经看到最好的batch_size是20,最好的optimizeradam优化器,最佳的历元数是2.您还获得了85%的分类器的最佳准确度。 您已经构建了一个员工保留模型,能够预测员工是否留下或离开的准确率高达85%。

结论

在本教程中,您使用Keras构建了一个人工神经网络,用于预测员工离开公司的可能性。 您结合使用scikit-learn在机器学习方面的先前知识来实现​​这一目标。 要进一步改进模型,您可以尝试使用keras不同激活函数优化器函数 您还可以尝试不同数量的折叠,或者甚至构建具有不同数据集的模型。

对于机器学习领域中的其他教程或使用TensorFlow,您可以尝试构建神经网络来识别手写数字或其他DigitalOcean 机器学习教程

赞(0) 打赏
未经允许不得转载:老赵部落 » 如何使用Keras和TensorFlow构建一个深度学习模型来预测员工保留

评论 抢沙发