如何用二分类学习器解决多分类问题

使用二分类学习器解决多分类问题的基本思路是“拆解法”,也就是将多分类任务拆分成多个二分类任务求解。这里主要介绍如何对多分类任务进行拆分,以及对拆分的多个分类器进行集成。

主要有三种拆分策略:“一对一”(One vs One,简称OvO)、“一对其余”(One vs Rest,简称OvR)和“多对多”(Many vs Many,简称MvM).

一、“一对一”(OvO)

假设要对N个类别进行分类。OvO将这N个类别两两配对,所以一共产生\frac{N(N-1)}{2}个二分类任务,对应\frac{N(N-1)}{2}个分类器。

  • 训练阶段:按照正常的二分类算法进行训练
  • 测试阶段:新样本同时提交给所有分类器,于是我们得到\frac{N(N-1)}{2}个分类结果,最终的结果可用过投票产生:即把被预测得到最多的类别作为最终分类结果。

例:对四个类别进行分类,A、B、C、D。

训练阶段产生6个分类器:

测试阶段,若测试的结果为:

f1(x) = A、f2(x) = C、f3(x) = A、f4(x) = C、f5(x) = D、f6(x) = C

有3个分类器的结果都为C,所以就把C作为最终的结果。可以看出一对一训练的分类器多,所以训练的速度会比较慢。

二、“一对其余”(OvR)

OvR是每次将一个类的样例作为正例、所有其他类的样例作为反例来训练N个分类器。在测试时:

  • 若仅有一个分类器预测为正类,则对应的类别标记作为最终分类结果;
  • 若有多个分类器预测为正类,则通常考虑各个分类器的预测置信度,选择置信度最大的类别标记作为最终结果。

同样还是以上面的问题为例,产生4个分类器:

测试阶段:

f1(x) = -1、f2(x) = -1、f3(x) = +1、f4(x) = -1

所以x属于C类。


比较OvR和OvO:

可以发现,OvR训练的是N个分类器,而OvO训练的是\frac{N(N-1)}{2}个分类器。因此OvR的存储开销和测试时间都比OvO小。但是,从训练时每个学习器使用的样本数来看:OvR每个学习器使用了所有的样本,而OvO的每个学习器只用到两个类别的样本。因此在类别很多时,OvO的训练时间往往会比OvR小。

对于预测性能取决于数据的分布,在多数情形下差别不大.

三、“多对多”(MvM)

MvM是每次将若干个类作为正类,若干个其他类作为反类。可以看出MvM是OvR和OvO更一般的形式。

对于MvM正、反类的构造一种常用的技术是“纠错输出码”(Error Correcting Output Codes,简称ECOC).主要分为两步:

  • 编码:对N个类别做M次划分,每次划分将一部分类别划分为正类,一部分类别划分为反类,从而形成一个二分类训练集;这样一共产生M个训练集,可训练出M个分类器。
  • 解码:测试时,M个分类器分别对测试样本x进行预测,这样预测的结果就形成了一个编码。将这个编码与每个类别各自的编码进行比较,找到距离最短的类别作为最终分类的结果。

还是以上面问题为例,假定M=5。训练结果如下:

测试阶段:

f1(x) = -1、f2(x) = -1、f3(x) = +1、f4(x) = -1、f5(x) = +1

所以测试样本的编码为(-1,-1,+1,-1,+1),到A、B、C、D对应编码的欧式距离为2\sqrt{3}, 4, 2, 2\sqrt{2}。比较发现距离C类最近,所以预测的结果就是C类。

       之所以称为纠错输出码,是因为在测试阶段,即使某个分类器预测错了,但是距离可能还是最小的。例如上面的测试样本正确的编码为(-1,+1,+1,-1,+1)也就是f2出错,但是还是能产生正确的分类C。

       一般来说,对于同一个学习任务,ECOC编码越长,纠错能力越强。但是,这意味着所需要的分类器就越多,开销就越大;另一方面,对有限类别数,可能的组合数目是有限的,码长超过一定的范围后就失去了意义。


参考资料:周志华老师《机器学习》

  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于PyTorch来说,解决二分问题通常需要以下几个步骤: 1. 数据准备:首先,你需要准备你的数据集。这包括将数据划分为训练集和测试集,并将其转换为PyTorch的数据加载(DataLoader)对象。如果你的数据是图像数据,你可以使用PyTorch提供的torchvision库来加载和预处理图像。 2. 构建模型:接下来,你需要构建一个适合二分类任务的模型。你可以使用PyTorch提供的nn.Module类来定义你的模型。常见的二分类模型包括全连接神经网络(FCN)、卷积神经网络(CNN)或循环神经网络(RNN)。你可以根据你的任务和数据集的特点选择适合的模型。 3. 定义损失函数和优化:对于二分问题,常用的损失函数是交叉熵损失函数(CrossEntropyLoss)。你可以使用torch.nn.CrossEntropyLoss来定义该损失函数。同时,你需要选择一个优化来更新模型的参数。常见的优化有随机梯度下降(SGD)和Adam。你可以使用torch.optim库来选择合适的优化。 4. 训练模型:在训练阶段,你需要迭代训练数据集,计算损失并更新模型参数。通常,一个训练循环包括前向传播(计算模型的输出)、计算损失、反向传播(计算梯度)和优化的步骤。你可以使用PyTorch提供的自动求导功能来计算梯度。 5. 模型评估:在训练完成后,你可以使用测试集来评估模型的性能。你可以计算模型在测试集上的准确率、精确率、召回率或F1分数等指标来评估模型的性能。 下面是一个简单的示例代码,用于演示如何使用PyTorch解决二分问题: ```python import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader # 步骤1:准备数据 train_dataset = ... test_dataset = ... train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=32) # 步骤2:构建模型 model = nn.Sequential( nn.Linear(input_size, hidden_size), nn.ReLU(), nn.Linear(hidden_size, output_size), nn.Sigmoid() ) # 步骤3:定义损失函数和优化 criterion = nn.BCELoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # 步骤4:训练模型 for epoch in range(num_epochs): for inputs, labels in train_loader: optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() # 步骤5:模型评估 model.eval() with torch.no_grad(): correct = 0 total = 0 for inputs, labels in test_loader: outputs = model(inputs) predicted = (outputs > 0.5).float() total += labels.size(0) correct += (predicted == labels).sum().item() accuracy = correct / total print('Test Accuracy: {:.2f}%'.format(accuracy * 100)) ``` 请注意,这只是一个简单的示例代码,你需要根据你的具体问题进行适当的调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值