在本文中,我们将使用Keras构建一个简单的神经网络。现在让我们继续解决一个真正的业务问题:保险公司希望您开发一个模型来帮助他们预测哪些索赔看起来很欺诈。
在本文中,我们将使用Keras构建一个简单的神经网络 。我们假设您已经掌握了机器学习软件包的先验知识,例如 scikit-learn和其他科学软件包,如 Pandas 和 Numpy。
训练人工神经网络涉及以下步骤:
权重随机初始化为接近零但不为零的数字。
将数据集的观察结果输入到输入图层。
前向传播(从左到右):激活神经元并获得预测值。
将预测结果与实际值进行比较并测量误差。
向后传播(从右到左):调整权重。
重复步骤1-5
当整个训练集通过神经网络时,实现了一个时代。
现在让我们继续解决一个真正的业务问题。一家保险公司已向您提供其客户先前索赔的数据集。保险公司希望您开发一个模型,以帮助他们预测哪些索赔看起来很欺诈。通过这样做,您希望每年为公司节省数百万美元。这是一个分类问题。这些是我们数据集中的列。
与许多业务问题一样,我们不会处理所提供的数据。因此,我们必须以我们的算法接受它的方式准备它。我们从数据集中看到,我们有一些分类列。我们需要将它们转换为零和一,以便我们的深度学习模型能够理解它们。另外需要注意的是,我们必须将数据集作为numpy数组提供给模型。下面我们导入必要的包,然后加载我们的数据集。
将pandas导入为pd导入numpy为npdf = pd.read_csv('Datasets / claims / insurance_claims.csv')
然后我们将分类列转换为虚拟变量。
在这种情况下,我们使用drop_first = True来避免虚拟变量陷阱。例如,如果您将a,b,c,d作为类别,则可以将d作为虚拟变量删除。这是因为如果某些东西不属于a,b或c,那么肯定是d。这被称为多重共线性。
我们使用 sklearn的 train_test_split将数据分成训练集和测试集。
来自sklearn.model_selection import train_test_split
接下来,我们确保删除我们预测的列,以防止它泄漏到训练集和测试集中。我们必须避免使用相同的数据集来训练和测试模型。我们 在数据集的末尾设置 .values以获取numpy数组。这是我们的深度学习模型接受数据的方式。这一步很重要,因为我们的机器学习模型需要数组形式的数据。
然后,我们将数据拆分为训练和测试集。我们使用0.7的数据进行训练,使用0.3进行测试。
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.3)
接下来,我们必须使用Sklearn的StandardScaler来扩展我们的数据集 。 由于深度学习中发生了大量计算,因此必须进行特征缩放。特征缩放标准化了我们的自变量范围。
来自sklearn.preprocessing导入StandardScalersc = StandardScaler()X_train = sc.fit_transform(X_train)X_test = sc.transform(X_test)
我们需要做的第一件事是导入Keras。默认情况下,Keras将使用TensorFlow作为其后端。
进口keras
接下来我们需要从Keras导入一些模块。Sequential模块需要初始化ANN,而Dense模块需要构建ANN的层。
来自keras.models导入顺序来自keras.layers导入密集
接下来,我们需要通过创建Sequential实例来初始化ANN。Sequential函数初始化线性堆栈层。这允许我们稍后使用Dense模块添加更多图层。
classifier = Sequential()
我们使用add方法为ANN添加不同的图层。第一个参数是要添加到此图层的节点数。关于应添加多少个节点,没有经验法则。但是,常见的策略是选择节点数作为输入层中节点的平均值和输出层中的节点数。
比如说你有五个自变量和一个输出。然后你会得到它的总和除以2,即3。您还可以决定尝试一种称为参数调整的技术。第二个参数, kernel_initializer, 是将被用于初始化权重的功能。在这种情况下,它将使用均匀分布来确保权重是接近零的小数字。下一个参数是激活功能。我们使用整流器功能,缩短为relu。我们大多使用此函数作为ANN中的隐藏层。最后一个参数是input_dim,它是输入层中的节点数。它代表自变量的数量。
classsifier.add( 密集(3,kernel_initializer ='uniform', activation ='relu',input_dim = 5))
添加第二个隐藏层类似于添加第一个隐藏层。
classsifier.add( 密集(3,kernel_initializer ='uniform', activation ='relu'))
我们不需要指定input_dim参数,因为我们已经在第一个隐藏层中指定了它。在第一个隐藏层中,我们指定了这个,以便让图层知道预期的输入节点数。在第二个隐藏层中,ANN已经知道预期有多少输入节点,因此我们不需要重复。
classifier.add( 密集(1,kernel_initializer ='uniform', activation ='sigmoid'))
我们更改第一个参数,因为在我们的输出节点中我们期望一个节点。这是因为我们只想知道索赔是否是欺诈性的。我们更改激活功能,因为我们希望获得声明是欺诈性的概率。我们通过使用Sigmoid激活函数来做到这一点。如果您正在处理具有两个以上类别的分类问题(即对猫,狗和猴子进行分类),我们需要更改两件事。我们将第一个参数更改为3并将激活功能更改为softmax。Softmax是一个sigmoid函数,适用于具有两个以上类别的自变量
classifier.compile(optimizer ='adam', loss ='binary_crossentropy', metrics = ['accuracy'])
编译基本上是将随机梯度下降应用于整个神经网络。第一个参数是您想要用于在神经网络中获得最佳权重集的算法。这里使用的算法是随机梯度算法。这有很多变种。亚当是一个非常有效的方法。第二个参数是随机梯度算法中的损失函数。由于我们的类别是二进制的,我们使用 binary_crossentropy 损失函数。否则我们会使用 categorical_crossentopy。 最后一个参数是我们用来评估模型的标准。在这种情况下,我们使用准确性。
classifier.fit(X_train,y_train,batch_size = 10,epochs = 100)
X_train表示我们用于训练ANN的自变量,y_train表示我们预测的列。Epochs表示我们将通过ANN传递完整数据集的次数。Batch_size是在更新权重之后的观察数。
y_pred = classifier.predict(X_test)
这将向我们显示索赔被欺诈的可能性。然后,我们设定了50%的门槛,将索赔归类为欺诈。这意味着任何概率为0.5或更高的索赔都将归类为欺诈性索赔。
y_pred =(y_pred> 0.5)
通过这种方式,保险公司可以首先跟踪不可疑的索赔,然后花更多的时间来评估被标记为欺诈的索赔。
来自sklearn.metrics import confusion_matrixcm = confusion_matrix(y_test,y_pred)
混淆矩阵可以解释如下。在2000个观测值中,正确预测了1550 + 175个观测值,而错误预测了230 + 45个观测值。您可以通过将正确预测的数量除以预测总数来计算准确度。在这种情况下(1550 + 175)/ 2000,它给你86%。
假设保险公司给你一个索赔。他们想知道索赔是否是欺诈性的。你会怎么做才能找到答案?
new_pred = classifier.predict(sc.transform(np.array([[a,b,c,d]])))
其中a,b,c,d代表您拥有的功能。
new_pred =(new_prediction> 0.5)
由于我们的分类器需要numpy数组,我们必须将单个观察转换为numpy数组并使用标准缩放器来缩放它。
在对模型进行一到两次训练后,您会注意到您不断获得不同的准确度。所以你不确定哪一个是正确的。这引入了偏差方差权衡。从本质上讲,我们正在尝试训练一个准确的模型,并且在多次训练时没有太多的准确度差异。为了解决这个问题,我们使用K倍交叉验证,K等于10.这将训练集分成10倍。然后我们将对我们的模型进行9次训练并在剩余的折叠上进行测试。由于我们有10个折叠,我们将通过10种组合迭代地执行此操作。每次迭代都会给我们准确性。然后我们将找到所有精度的均值并将其用作模型精度。我们还计算方差以确保它是最小的。
Keras有一个scikit学习包装器(KerasClassifier),它使我们能够在我们的keras代码中包含K-fold交叉验证。
来自keras.wrappers.scikit_learn导入KerasClassifier
接下来,我们从scikit_learn导入k-fold交叉验证函数
来自sklearn.model_selection import cross_val_score
KerasClassifier期望它的一个参数是一个函数,因此我们需要构建该函数。该函数的目的是构建我们的ANN的体系结构。
此函数将构建分类器并将其返回以供下一步使用。我们在这里做的唯一事情就是将我们以前的ANN架构包装在一个函数中并返回分类器。
然后,我们使用K-fold交叉验证创建一个新的分类器,并将参数build_fn 作为我们刚刚创建的函数传递 。接下来,我们传递批量大小和时期数,就像我们在之前的分类器中所做的那样。
classiifier = KerasClassifier(build_fn = make_classifier, batch_size = 10,nb_epoch = 100)
要应用k-fold交叉验证函数,我们可以使用scikit-learn的 cross_val_score 函数。估计器是我们刚用make_classifier构建的分类器 ,n_jobs = -1将使用所有可用的CPU。cv是折叠的数量,10是典型的选择。该 cross_val_score 将返回在计算中使用的十个测试褶皱的十项精度。
准确度= cross_val_score(estimator = classifier, X = X_train, y = y_train, cv = 10, n_jobs = -1)
为了获得相对的准确度,我们得到了精确度的平均值。
mean = accuracies.mean()
方差可以如下获得:
variance = accuracies.var()
目标是在准确度之间有一个小的差异。
当模型学习训练集中的细节和噪声以使其在测试集上表现不佳时,机器学习中的过度拟合就会发生。当我们在测试集和训练集的准确度之间存在巨大差异时,或者在应用k折交叉验证时观察到高差异时,可以观察到这种情况。在人工神经网络中,我们使用称为丢失正则化的技术来抵消这种情况。辍学正规化的工作原理是在训练的每次迭代中随机禁用一些神经元,以防止它们过于依赖彼此。
在这种情况下,我们在第一个隐藏层之后和第二个隐藏层之后应用丢失。使用0.1的速率意味着在每次迭代时将禁用1%的神经元。建议以0.1的速率开始。但是你永远不应该超过0.4,因为你现在开始变得不合适了。
获得准确度后,您可以调整参数以获得更高的准确度。网格搜索使我们能够测试不同的参数,以获得最佳参数。
这里的第一步是从sklearn 导入 GridSearchCV 模块。
来自sklearn.model_selection导入GridSearchCV
我们还需要修改make_classifier函数,如下所示。我们创建了一个名为optimizer 的新变量 ,它允许我们在params变量中添加多个优化器。
我们仍将使用KerasClassifier,但我们不会传递批量大小和时期数,因为这些是我们想要调整的参数。
classifier = KerasClassifier(build_fn = make_classifier)
下一步是创建一个包含我们想要调整的参数的字典 - 在这种情况下是批量大小,时期数和优化器函数。我们仍然使用adam作为优化器并添加一个名为rmsprop的新的。Keras文档在处理递归神经网络时建议使用rmsprop。但是我们可以尝试这个ANN,看看它是否给我们带来了更好的结果。
params = { '的batch_size':[20,35], 'nb_epoch':[150500], '优化器':['adam','rmsprop' ]}
然后,我们使用网格搜索来测试这些参数。网格搜索功能需要我们的估算器,我们刚刚定义的参数,评分指标和k倍数。
grid_search = GridSearchCV(estimator = classifier, param_grid =参数, 得分=“精度”, CV = 10)
与之前的对象一样,我们需要适合我们的训练集。
grid_search = grid_search.fit(X_train,y_train)
我们可以使用网格搜索对象中的best_params 获得最佳参数选择 。同样,我们使用best_score_来获得最佳分数。
best_param = grid_search.best_params_best_accuracy = grid_search.best_score_
重要的是要注意,此过程将花费一些时间来搜索最佳参数。
人工神经网络只是一种深度神经网络。还有其他网络,如回归神经网络(RNN),卷积神经网络(CNN)和玻尔兹曼机器。RNN可以预测未来股票的价格是上涨还是下跌。CNN用于计算机视觉 - 在一组图像中识别猫和狗或识别脑图像中存在的癌细胞。Boltzmann机器用于编程推荐系统。也许我们可以在将来覆盖其中一个神经网络。
干杯。
Bio:Derrick Mwiti是一名数据分析师,作家和导师。他在每项任务中都取得了很好的成绩,并且是Lapid Leaders Africa的导师。
原创。转载许可。
评论专区