原文链接:http:///?p=8522分类问题属于机器学习问题的类别,其中给定一组特征,任务是预测离散值。分类问题的一些常见示例是,预测肿瘤是否为癌症,或者学生是否可能通过考试。在本文中,鉴于银行客户的某些特征,我们将预测客户在6个月后是否可能离开银行。客户离开组织的现象也称为客户流失。因此,我们的任务是根据各种客户特征预测客户流失。 $ pip install pytorch 数据集让我们将所需的库和数据集导入到我们的Python应用程序中: import torch 我们可以使用 dataset = pd.read_csv(r'E:Datasetscustomer_data.csv') 让我们输出数据集 : dataset.shape 输出: (10000, 14) 输出显示该数据集具有1万条记录和14列。我们可以使用 dataset.head() 输出: 您可以在我们的数据集中看到14列。根据前13列,我们的任务是预测第14列的值,即 探索性数据分析让我们对数据集进行一些探索性数据分析。我们将首先预测6个月后实际离开银行并使用饼图进行可视化的客户比例。让我们首先增加图形的默认绘图大小: fig_size = plt.rcParams["figure.figsize"] 以下脚本绘制该 dataset.Exited.value_counts().plot(kind='pie', autopct='%1.0f%%', colors=['skyblue', 'orange'], explode=(0.05, 0.05)) 输出: 输出显示,在我们的数据集中,有20%的客户离开了银行。这里1代表客户离开银行的情况,0代表客户没有离开银行的情况。让我们绘制数据集中所有地理位置的客户数量: 输出显示,几乎一半的客户来自法国,而西班牙和德国的客户比例分别为25%。 现在,让我们绘制来自每个唯一地理位置的客户数量以及客户流失信息。我们可以使用库中的 输出显示,尽管法国客户总数是西班牙和德国客户总数的两倍,但法国和德国客户离开银行的客户比例是相同的。同样,德国和西班牙客户的总数相同,但是离开银行的德国客户数量是西班牙客户的两倍,这表明德国客户在6个月后离开银行的可能性更大。 数据预处理在训练PyTorch模型之前,我们需要预处理数据。如果查看数据集,您将看到它具有两种类型的列:数值列和分类列。数字列包含数字信息。 让我们再次输出数据集中的所有列,并找出哪些列可以视为数字列,哪些列应该视为类别列。 Index(['RowNumber', 'CustomerId', 'Surname', 'CreditScore', 'Geography', 'Gender', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'HasCrCard', 'IsActiveMember', 'EstimatedSalary', 'Exited'], dtype='object') 从我们的数据列,我们将不使用的 numerical_columns = ['CreditScore', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'EstimatedSalary'] 最后,输出( 我们已经创建了分类,数字和输出列的列表。但是,目前,分类列的类型不是分类的。您可以使用以下脚本检查数据集中所有列的类型: RowNumber int64 您可以看到 现在,如果再次绘制数据集中各列的类型,您将看到以下结果: 输出量 RowNumber int64 现在让我们查看 Index(['France', 'Germany', 'Spain'], dtype='object') 当您将列的数据类型更改为类别时,该列中的每个类别都会分配一个唯一的代码。例如,让我们绘制列的前五行, 输出: 0 France 以下脚本在该列的前五行中绘制了值的代码 输出: 0 0 输出显示法国已编码为0,西班牙已编码为2。 将分类列与数字列分开的基本目的是,可以将数字列中的值直接输入到神经网络中。但是,必须首先将类别列的值转换为数字类型。分类列中的值的编码部分地解决了分类列的数值转换的任务。 由于我们将使用PyTorch进行模型训练,因此需要将分类列和数值列转换为张量。首先让我们将分类列转换为张量。在PyTorch中,可以通过numpy数组创建张量。我们将首先将四个分类列中的数据转换为numpy数组,然后将所有列水平堆叠,如以下脚本所示: geo = dataset['Geography'].cat.codes.values 上面的脚本输出分类列中前十条记录。输出如下:输出: array([[0, 0, 1, 1], 现在要从上述numpy数组创建张量,您只需将数组传递给模块的 输出: tensor([[0, 0, 1, 1], 在输出中,您可以看到类别数据的numpy数组现在已转换为 numerical_data = np.stack([dataset[col].values for col in numerical_columns], 1) 输出: tensor([[6.1900e+02, 4.2000e+01, 2.0000e+00, 0.0000e+00, 1.0000e+00, 1.0135e+05], 在输出中,您可以看到前五行,其中包含我们数据集中六个数字列的值。最后一步是将输出的numpy数组转换为 tensor([1, 0, 1, 0, 0]) 现在,让我们绘制分类数据,数值数据和相应输出的形状: 输出: torch.Size([10000, 4]) 在训练模型之前,有一个非常重要的步骤。我们将分类列转换为数值,其中唯一值由单个整数表示。例如,在该 我们需要为所有分类列定义矢量大小。关于维数没有严格的规定。定义列的嵌入大小的一个好的经验法则是将列中唯一值的数量除以2(但不超过50)。例如,对于该 categorical_column_sizes = [len(dataset[column].cat.categories) for column in categorical_columns] 输出: [(3, 2), (2, 1), (2, 1), (2, 1)] 使用训练数据对监督型深度学习模型(例如我们在本文中开发的模型)进行训练,并在测试数据集上评估模型的性能。因此,我们需要将数据集分为训练集和测试集,如以下脚本所示: total_records = 10000 我们的数据集中有1万条记录,其中80%的记录(即8000条记录)将用于训练模型,而其余20%的记录将用于评估模型的性能。注意,在上面的脚本中,分类和数字数据以及输出已分为训练集和测试集。为了验证我们已正确地将数据分为训练和测试集: print(len(categorical_train_data)) 输出: 8000 创建预测模型我们将数据分为训练集和测试集,现在是时候定义训练模型了。为此,我们可以定义一个名为的类 class Model(nn.Module): 接下来,要查找输入层的大小,将类别列和数字列的数量加在一起并存储在
在后 接下来,在该 embeddings = []
x_numerical = self.batch_norm_num(x_numerical) 最后,将嵌入的分类列 训练模型要训练模型,首先我们必须创建 您可以看到我们传递了分类列的嵌入大小,数字列的数量,输出大小(在我们的例子中为2)以及隐藏层中的神经元。您可以看到我们有三个分别具有200、100和50个神经元的隐藏层。 print(model) 输出: Model( 您可以看到,在第一线性层中, 在实际训练模型之前,我们需要定义损失函数和将用于训练模型的优化器。以下脚本定义了损失函数和优化器: loss_function = nn.CrossEntropyLoss() 现在,我们训练模型。以下脚本训练模型: epochs = 300 神经元元数设置为300,这意味着要训练模型,完整的数据集将使用300次。 上面脚本的输出如下: epoch: 1 loss: 0.71847951 epoch: 26 loss: 0.57145703 epoch: 51 loss: 0.48110831 epoch: 76 loss: 0.42529839 epoch: 101 loss: 0.39972275 epoch: 126 loss: 0.37837571 epoch: 151 loss: 0.37133673 epoch: 176 loss: 0.36773482 epoch: 201 loss: 0.36305946 epoch: 226 loss: 0.36079505 epoch: 251 loss: 0.35350436 epoch: 276 loss: 0.35540250 epoch: 300 loss: 0.3465710580 以下脚本绘制了各个时期的损失函数: plt.plot(range(epochs), aggregated_losses) plt.ylabel('Loss') plt.xlabel('epoch');` 输出: 输出显示,最初损失函数迅速降低。在250个步长之后,损失几乎没有减少。 做出预测最后一步是对测试数据进行预测。为此,我们只需要将 with torch.no_grad(): 输出: Loss: 0.36855841 测试集上的损失为0.3685,比训练集上获得的0.3465略多,这表明我们的模型有些过拟合。由于我们指定输出层将包含2个神经元,因此每个预测将包含2个值。例如,前5个预测值如下所示: print(y_val[:5]) 输出: tensor([[ 1.2045, -1.3857], 这种预测的思想是,如果实际输出为0,则索引0处的值应大于索引1处的值,反之亦然。我们可以使用以下脚本检索列表中最大值的索引: y_val = np.argmax(y_val, axis=1) 输出:现在让我们再次输出 print(y_val[:5]) 输出: tensor([0, 0, 0, 0, 0]) 由于在最初预测的输出列表中,对于前五个记录,零索引处的值大于第一索引处的值,因此可以在已处理输出的前五行中看到0。 最后,我们可以使用从 `from sklearn.metrics import classification_report, confusion_matrix, accuracy_score print(confusion_matrix(test_outputs,y_val)) print(classification_report(test_outputs,y_val)) print(accuracy_score(test_outputs, y_val))` 输出: [[1527 83] [ 224 166]] precision recall f1-score support micro avg 0.85 0.85 0.85 2000 macro avg 0.77 0.69 0.71 2000 weighted avg 0.83 0.85 0.83 2000 0.8465` 输出结果表明,我们的模型达到了84.65%的精度,考虑到我们随机选择神经网络模型的所有参数这一事实,这非常令人印象深刻。我建议您尝试更改模型参数,例如训练/测试比例,隐藏层的数量和大小等,以查看是否可以获得更好的结果。 结论PyTorch是Facebook开发的常用深度学习库,可用于各种任务,例如分类,回归和聚类。本文介绍了如何使用PyTorch库对表格数据进行分类。 |
|