在我们解决多类线性可分问题的时候,常会遇到单标签二分类问题、单标签多分类问题、多标签算法问题,下面分别讨论。而前面讲的线性分类模型,原则上只能解决二分类问题,但通过一些技巧就可以解决多分类问题。
1 简介
1.1 单标签二分类问题
单标签二分类这种问题是我们最常见的算法问题,主要是指标签(label)的取值只有两种,并且算法中只有一个需要预测的label
;直白来讲就是每个实例的可能类别只有两种(A or B);此时的分类算法其实是在构建一个分类线将数据划分为两个类别。常见的算法:Logistic
、SVM
、KNN
、决策树等。
1.2 单标签多分类问题
单标签多分类问题其实是指待预测的label
只有一个,但是label
的取值可能有多种情况;直白来讲就是每个实例的可能类别有
K
K
K 种(
t
1
,
t
2
,
⋯
,
t
k
,
k
≥
3
t_1, t_2, \cdots, t_k, k≥3
t1,t2,⋯,tk,k≥3);常见算法:Softmax
、KNN
、决策树等;
在实际的工作中,如果是一个多分类的问题,我们可以将这个待求解的问题转换为二分类算法的延伸,即将多分类任务拆分为若干个二分类任务求解,具体的策略如下:
- One-Versus-One(OvO):一对一
- One-Versus-All / One-Versus-the-Rest(OvA/OvR): 一对多
- Error Correcting Output codes(纠错码机制):多对多(MvM)
1.3 多标签算法问题
Multi-Label Machine Learning
(MLL算法)是指预测模型中存在多个
y
y
y 值,具体分为两类不同情况:
- 多个待预测的 y y y 值;
- 在分类模型中, 一个样例可能存在多个不固定的类别。
根据多标签业务问题的复杂性,可以将问题分为两大类:
- 待预测值之间存在相互的依赖关系;
- 待预测值之间是不存在依赖关系的。
对于这类问题的解决方案可以分为两大类:
- 转换策略(Problem Transformation Methods);
- 算法适应(Algorithm Adaptation)。
详细介绍,请阅读:多标签分类算法原理及代码、多分类及多标签分类算法
2 多分类问题
2.1 OvO
OvO
(一对一,One vs One):假如数据
D
D
D 中有
N
N
N 个类别,将
N
N
N 个类别进行两两配对,会得到
N
(
N
−
1
)
/
2
N(N-1)/2
N(N−1)/2 个二分类器。在预测中,将测试样本输入这
N
(
N
−
1
)
/
2
N(N-1)/2
N(N−1)/2 个二分类器中得到相应个数的预测结果,然后再将被预测结果数最多的(Voting)作为最终分类结果。
下面举个例子,当有4个类别的时候,首先把类别两两组合(6种组合)。组合完之后,其中一个类别作为正类,另一个作为负类(这个正负只是相对而言,目的是转化为二分类)。然后对每个二分类器进行训练。可以得到6个二分类器。然后把测试样本在6个二分类器上面进行预测。从结果上可以看到,类别1被预测的最多,故测试样本属于类别1。
2.2 OvR
OvR
(一对其余,One vs Rest): 将一个类别作为正例,其余所有类别作为反例,这样
N
N
N 个类别可以产生
N
N
N 个二分类器,将测试样本输入这些二分类器中中得到
N
N
N 个预测结果,如果仅有一个分类器预测为正类,则将对应的预测结果作为最终预测结果。如果有多个分类器预测为正类,则选择置信度最大的类别作为最终分类结果。
下面举个例子,当有4个类别的时候,每次把其中一个类别作为正类别,其余作为负类别,共有4种组合,对于这4中组合进行分类器的训练,我们可以得到4个分类器。对于测试样本,放进4个分类器进行预测,仅有一个分类器预测为正类,于是取这个分类器的结果作为预测结果,分类器2预测的结果是类别2,于是这个样本便属于类别2。
其实,有人会有疑问,那么预测为负类的分类器就不用管了吗?是的,因为预测为负类的时候有多种可能,无法确定,只有预测为正类的时候才能唯一确定属于哪一类。比如对于分类器3,分类结果是负类,但是负类有类别1,类别2,类别4三种,到底属于哪一种?
2.3 OvO与OvR的对比
OvR
只需训练
N
N
N 个分类器,而OvO
需训练
N
(
N
−
1
)
/
2
N(N - 1)/2
N(N−1)/2 个分类器, 因此,OvO
的存储开销和测试时间开销通常比OvR
更大。但在训练时,OvR
的每个分类器均使用全部训练样例,而OvO
的每个分类器仅用到两个类的样例,因此,在类别很多时,OvO
的训练时间开销通常比OvR
更小。至于预测性能,则取决于具体的数据分布,在多数情形下两者差不多。
综上:
OvO
的优点是,在大数据集和和类别较多的情况下,训练时间要比OvR
少。缺点是,分类器个数多。OvR
的优点是,分类器个数少,存储开销和测试时间比OvO
少。缺点是,类别很多时,训练时间长。
补充:
有的地方也会提到一种改进的“一对其余”方式,假设一个多分类问题的类别为
{
1
,
2
,
⋯
,
𝐶
}
\{1, 2,\cdots, 𝐶\}
{1,2,⋯,C},则共需要
C
C
C 个判别函数
f
c
(
x
;
w
c
)
=
w
c
T
x
+
b
c
c
∈
{
1
,
⋯
,
C
}
(1)
f_c(\pmb{x}; \pmb{w}_c)=\pmb{w}_c^T\pmb{x}+b_c \qquad c\in\{1,\cdots,C\}\tag{1}
fc(xxx;wwwc)=wwwcTxxx+bcc∈{1,⋯,C}(1)
对于样本
x
\pmb{x}
xxx,如果存在一个类别
c
c
c,相对于所有的其他类别
c
^
(
c
^
≠
c
)
\hat{c}(\hat{c}\not=c)
c^(c^=c)有
f
c
(
x
;
w
c
)
>
f
c
^
(
x
;
w
c
^
)
f_c(\pmb{x}; \pmb{w}_c)>f_{\hat{c}}(\pmb{x}; \pmb{w}_{\hat{c}})
fc(xxx;wwwc)>fc^(xxx;wwwc^),那么
x
\pmb{x}
xxx 属于类别
𝑐
𝑐
c。“argmax”方式的预测函数定义为
y
=
a
r
g
m
a
x
c
=
1
C
f
c
(
x
;
w
c
)
(2)
y = \overset{C}{\underset{c=1}{argmax}} f_c(\pmb{x}; \pmb{w}_c)\tag{2}
y=c=1argmaxCfc(xxx;wwwc)(2)
“一对其余”方式和“一对一”方式都存在一个缺陷:特征空间中会存在一些难以确定类别的区域,而“argmax”方式很好地解决了这个问题。下图给出了用这三种方式进行多分类的示例,其中红色直线表示判别函数
𝑓
(
⋅
)
=
0
𝑓(⋅) = 0
f(⋅)=0 的直线,不同颜色的区域表示预测的三个类别的区域(
w
1
、
w
2
、
w
3
w_1、w_2、w_3
w1、w2、w3)和难以确定类别的区域(‘?’)。在“argmax”方式中,相邻两类
𝑖
𝑖
i 和
𝑗
𝑗
j 的决策边界实际上是由
𝑓
𝑖
(
𝒙
;
𝒘
𝑖
)
−
𝑓
𝑗
(
𝒙
;
𝒘
𝑗
)
=
0
𝑓_𝑖(𝒙; 𝒘_𝑖) −𝑓_𝑗 (𝒙; 𝒘_𝑗 ) = 0
fi(x;wi)−fj(x;wj)=0 决定,其法向量为
𝒘
𝑖
−
𝒘
𝑗
𝒘_𝑖 − 𝒘_𝑗
wi−wj。
2.4 MvM
MvM
是每次将若干个类作为正类,若干个其他类作为反类。显然,OvO
和OvR
是MvM
的特例。MvM
的正、反类构造必须有特殊的设计,不能随意选取。这里介绍一种最常用的MvM
技术"纠错输出码" (Error Correcting Output Codes,简称 ECOC)
ECOC
是将编码的思想引入类别拆分,并尽可能在解码过程中具有容错性。ECOC
工作过程主要分为两步:
-
编码:对N个类别做M次划分,每次划分将一部分类别划为正类,一部分划为反类,从而形成一个二分类训练集。这样一共产生M个训练集,可训练出M个分类器。
-
解码:M 个分类器分别对测试样本进行预测,这些预测标记组成一个编码。将这个预测编码与每个类别各自的编码进行比较,返回其中距离最小的类别作为最终预测结果。
类别划分通过"编码矩阵"指定。编码矩阵有多种形式,常见的主要有二元码和三元码。前者将每个类别分别指定为正类和反类,后者在正、反类之外,还可指定"停用类"。图3.5给出了一个示意图,在图 3.5(a) 中,分类器 f 2 f_2 f2 将 C l C_l Cl 类和 C 3 C_3 C3 类的样例作为正例, C 2 C_2 C2 类和 C 4 C_4 C4 类的样例作为反例;在图3.5(b)中,分类器 f 4 f_4 f4 将 C 1 C_1 C1 类和 C 4 C_4 C4 类的样例作为正例, C 3 C_3 C3 类的样例作为反例。在解码阶段,各分类器的预测结果联合起来形成了测试示例的编码,该编码与各类所对应的编码进行比较,将距离最小的编码所对应的类别作为预测结果。
例如在图 3.5(a) 中,若基于欧式距离,预测结果将是
C
3
C_3
C3。也就是一个测试样本,经过分类器
f
1
,
f
2
,
f
3
,
f
4
,
f
5
f_1,f_2,f_3,f_4,f_5
f1,f2,f3,f4,f5分别预测成了(-1,-1,+1,-1,+1),与
C
1
C_1
C1 相比较,海明距离为0+1+1+1+0=3,欧式距离为,对
C
2
,
C
3
,
C
4
C_2,C_3,C_4
C2,C3,C4 都进行比较即可。
2.5 Python实现
利用sklearn
的鸢尾花数据集验证一下,该数据集有 4 个特征属性,3 种分类{‘setosa’, ‘versicolor’, ‘virginica’}
,下面利用 OvR
、OvO
和MvM
三种策略进行多分类的学习及预测:
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.multiclass import OneVsRestClassifier
from sklearn.multiclass import OneVsOneClassifier
from sklearn.multiclass import OutputCodeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 加载数据
data_iris = datasets.load_iris()
x, y = data_iris.data, data_iris.target
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.3,random_state = 0)
# 使用multiclass的OvO多分类策略,分类器使用LogisticRegression
model = OneVsOneClassifier(LogisticRegression(C=1.0, tol=1e-6))
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
print(accuracy_score(y_test, y_pred))
# 准确率为:0.9777777777777777
# 使用multiclass的OvR多分类策略,分类器使用LogisticRegression
model = OneVsRestClassifier(LogisticRegression(C=1.0, tol=1e-6))
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
print(accuracy_score(y_test, y_pred))
# 准确率为:0.9555555555555556
# 使用multiclass的ECOC多分类策略,分类器使用LogisticRegression
# 模型对象创建
# code_size: 指定最终使用多少个子模型,实际的子模型的数量=int(code_size*label_number)
# code_size设置为1,等价于ovr子模型个数;
# 设置为0~1, 那相当于使用比较少的数据划分,效果比ovr差;
# 设置为大于1的值,那么相当于存在部分模型冗余的情况
model = OutputCodeClassifier(LogisticRegression(C=1.0, tol=1e-6), code_size=30, random_state=0)
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
print(accuracy_score(y_test, y_pred))
# 准确率为:0.9555555555555556
注意:OvR
、OvO
和MvM
不是逻辑回归专有的,也可以运用与SVM
等只能解决二分类问题的模型上。
3 Softmax 回归
softmax
回归其实是逻辑回归的一种变形,逻辑回归模型输出的是两种类别的概率,softmax
回归输出的
K
K
K 种类别的概率。模型公式如下:
h
θ
(
x
i
)
=
[
p
(
y
i
=
1
∣
x
i
;
θ
)
p
(
y
i
=
2
∣
x
i
;
θ
)
⋮
p
(
y
i
=
k
∣
x
i
;
θ
)
]
=
1
∑
j
=
1
k
e
θ
j
T
x
i
[
e
θ
1
T
x
i
e
θ
2
T
x
i
⋮
e
θ
k
T
x
i
]
(3)
h_{\boldsymbol{\theta}}\left(\boldsymbol{x}_i\right)=\left[\begin{array}{c}{p\left(y_i=1 | \boldsymbol{x}_i ; \boldsymbol{\theta}\right)} \\ {p\left(y_i=2 | \boldsymbol{x}_i ; \boldsymbol{\theta}\right)} \\ {\vdots} \\ {p\left(y_i=k | \boldsymbol{x}_i ; \boldsymbol{\theta}\right)}\end{array}\right]=\frac{1}{\sum_{j=1}^{k} e^{\boldsymbol{\theta}_{j}^{T} \boldsymbol{x}_i}}\left[\begin{array}{c}{e^{\boldsymbol{\theta}_{1}^{T} \boldsymbol{x}_i}} \\ {e^{\boldsymbol{\theta}_{2}^{T} \boldsymbol{x}_i}} \\ {\vdots} \\ {e^{\boldsymbol{\theta}_{k}^{T} \boldsymbol{x}_i}}\end{array}\right]\tag{3}
hθ(xi)=⎣⎢⎢⎢⎡p(yi=1∣xi;θ)p(yi=2∣xi;θ)⋮p(yi=k∣xi;θ)⎦⎥⎥⎥⎤=∑j=1keθjTxi1⎣⎢⎢⎢⎢⎡eθ1Txieθ2Txi⋮eθkTxi⎦⎥⎥⎥⎥⎤(3)
参数
θ
\pmb{\theta}
θθθ 是一个矩阵,矩阵的每一行可以看做是一个类别所对应分类器的参数,总共有
K
K
K 行,输出的
K
K
K 个数就表示该类别的概率,总和为1。这样,softmax
回归模型对于一个测试样本,可以得到多个类别对应的概率值,模型选取概率最高的类别作为最终判定结果。详细介绍:Softmax 回归原理与实现
在sklearn
中使用softmax
回归还是调用linear.model.LogisticRegression
,设置一下multi_class
参数即可,内部即会使用softmax
函数计算出每个类别的概率。
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 加载数据
data_iris = datasets.load_iris()
x, y = data_iris.data, data_iris.target
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 0)
# 采用softmax回归进行分类
model = LogisticRegression(C=1.0, tol=1e-6, multi_class='multinomial', solver='newton-cg')
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
print(accuracy_score(y_test, y_pred))
# 准确率为:0.9777777777777777
# 输出每个测试样例的类别预测概率
print (model.predict_proba(x_test))
多个二分类器策略和softmax
回归的区别
softmax
回归中对一个测试样本得到的属于各类别的概率和一定为1,而多个二分类器策略中,不管是OvO
、OvR
还是MvM
策略,一个样本在多个二分类器上得到的概率和不一定为 1。因此当分类之间是互斥的情况下(e.g 数字手写识别、动物识别),通常采用softmax
回归;而目标类别不是互斥时(e.g 华语音乐、流行音乐、重金属音乐等)则采用多个二分类器策略进行预测。
参考
- 多分类及多标签分类算法:https://www.cnblogs.com/us-wjz/articles/11410118.html
- 机器学习中的多分类任务详解:https://blog.csdn.net/anshuai_aw1/article/details/82973039
- 逻辑回归的多分类:https://www.infoq.cn/article/NoPHBaCaxPwOkYgrsBEv
- 二分类、多分类与多标签问题的区别:https://juejin.cn/post/6844903630479294477