用有序类分类?

机器算法验证 回归 机器学习 分类 离散数据
2022-01-25 09:29:35

假设我想训练一个分类器,将一个人的图像分配为年轻中年老年

一种简单的方法是将类视为独立的类别并训练分类器。但显然这些类之间存在某种关系,我怎样才能利用它来变得更好?

我在想也许我可以做
1) 改变损失,比如说增加预测young as oldold as young的损失。
2)把它变成一个回归问题,年轻中年,和代表说0、1和2。

2个回答

我最近用一个处理六个序数类的卷积神经网络分类器来看看这个。我尝试了三种不同的方法:

方法一:标准独立分类

这就是您在问题中提到的基线,带有映射:

class 0 -> [1, 0, 0, 0, 0, 0]
class 1 -> [0, 1, 0, 0, 0, 0]
class 2 -> [0, 0, 1, 0, 0, 0]
class 3 -> [0, 0, 0, 1, 0, 0]
class 4 -> [0, 0, 0, 0, 1, 0]
class 5 -> [0, 0, 0, 0, 0, 1]

我们通常会使用 softmax 激活和分类交叉熵损失。

但是,这并没有像您所说的那样考虑类之间的关系,因此损失函数仅受您是否击中正确的类的影响,而不受您是否接近的影响。

方法二:序数目标函数

这是Cheng 等人发表的一种方法。(2008 年) ,这里这里的 StackExchange 也提到过现在的映射是:

class 0 -> [0, 0, 0, 0, 0]
class 1 -> [1, 0, 0, 0, 0]
class 2 -> [1, 1, 0, 0, 0]
class 3 -> [1, 1, 1, 0, 0]
class 4 -> [1, 1, 1, 1, 0]
class 5 -> [1, 1, 1, 1, 1]

这与 sigmoid 激活和二元交叉熵损失一起使用。这个目标函数意味着你越接近正确的类,损失就越小。

您可以通过找到的第一个索引来从该分类器的输出预测一个类。然后给你预测的类。{yk}kyk<0.5k

方法三:将分类转化为回归

这与您的第二个想法相同。这里的映射是:

class 0 -> [0]
class 1 -> [1]
class 2 -> [2]
class 3 -> [3]
class 4 -> [4]
class 5 -> [5]

我对此使用了线性激活和均方误差损失。像以前的方法一样,这也给你带来的损失越少,你错过的越少。

当基于这个的输出预测一个类时,你可以简单地将输出四舍五入到最接近的整数。

一些示例结果

我用相同的数据集评估了不同的方法。在类不平衡和类平衡版本中,指标是精确准确度(击中正确的类)和相邻准确度(击中正确的类或其邻居之一)。下面显示的每个度量值都是三次运行的平均值。

对于方法 1 / 方法 2 / 方法 3,指标给出:

  • 不平衡精度:0.582 / 0.606 / 0.564
  • 平衡精度:0.460 / 0.499 / 0.524
  • 不平衡相邻精度:0.827 / 0.835 / 0.855
  • 平衡相邻精度:0.827 / 0.832 / 0.859

因此,对于我的特定数据集和网络设置,回归方法通常做得最好,而具有独立类的标准方法通常做得最差。我不知道这些结果在其他情况下的推广效果如何,但是调整任何序数分类器以能够使用所有三种方法以便您自己测试应该不难。

1)改变损失,比如说增加预测年轻和年老或年老一样年轻的损失。

听起来是一个合理的方法。

2)把它变成一个回归问题,年轻、中年和老年分别表示为0、1和2。

这取决于您使用的回归学习器,但这可能不是一个好主意(例如,树和派生词可能对它是安全的)。你确定年轻人和中年之间的“距离”(无论是什么意思)与中年和老年人之间的“距离”相同吗?


当您学习名义变量时,我建议您将此问题视为分类。更具体地说,如您所知,类之间存在潜在关系,即序数分类。

您可以尝试 Frank & Hall [1] 提出的策略,将个响应变量编码为二元问题。所以你试着去了解老和不老、年轻和不年轻的区别,这些实际上给了你关于这三个类别的信息。这是一个非常简单的启发式方法,可以击败幼稚的多类方法,并且不会改变学习者的下划线工作。NN1


[1] Frank, E. 和 Hall, M.(2001 年 9 月)。一种简单的序数分类方法。在欧洲机器学习会议上(第 145-156 页)。施普林格柏林海德堡。