Tips | 如何用二元分类器解决一个多分类任务?

栏目: IT技术 · 发布时间: 4年前

内容简介:本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.二元分问题会是我们生活中比较常见的一类问题,比如邮件可以分为垃圾邮件和非垃圾邮件、一个人患病或者不患病,但除此之外也会遇到一些多元分类问题,比如天气可以分为晴、阴、雨、雪等等。我们通过算法构建的分类器就以分为二元分类器和多元分类器,前者可以区分两个类别标签,后者则可以区分两个以上的类别标签。对于算法而言,像SVM、逻辑回归等是严格的二元分类算法,而像朴素贝叶斯、随机森林这类算法则可以直接处理多元分类问题。但利用二元分类器处理

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

二元分问题会是我们生活中比较常见的一类问题,比如邮件可以分为垃圾邮件和非垃圾邮件、一个人患病或者不患病,但除此之外也会遇到一些多元分类问题,比如天气可以分为晴、阴、雨、雪等等。

我们通过算法构建的分类器就以分为二元分类器和多元分类器,前者可以区分两个类别标签,后者则可以区分两个以上的类别标签。对于算法而言,像SVM、逻辑回归等是严格的二元分类算法,而像朴素贝叶斯、随机森林这类算法则可以直接处理多元分类问题。但利用二元分类器处理多分类问题是可行的,下面将以逻辑回归结合鸢尾花数据集为例介绍。

OvA、OvO策略

利用二元分类器解决多分类问题可以分为两种策略:

one-versus-all(OvA)策略,也可以称one-versus-rest(OvR),简称一对多。

one-versus-one(OvO)策略,简称一对一,应该有人用OvO当过文字表情吧。

用过鸢尾花数据集的伙伴应该知道这份数据集的类别标签共有三类,分别是山鸢尾(setosa)、变色鸢尾(versicolor)和维吉尼亚鸢尾(virginica),因为有三个类别嘛,所以就构造三个二元分类器,假设为山-分类器、变-分类器和维-分类器。训练时将某个类别的样本归为一类,其余类别的样本归为另一类,这样对于某个未知类别的样本,三个分类器都会有一个决策分数(概率),然后取最高决策分数的一个类别作为该样本的类别,这种方式就属于一对多法。

而一对一的做法是构建多个任意两类样本间的二元分类器,原理类似于组队,比如上述三个标签变量可以组成山和变、山和维、变和维,如果类别为n的话,需要的分类器个数为$\frac{n(n-1)}{2}$。最后也是取决策分数最高的一个类别作为某个未知类别的样本最终分类。

从上面介绍中也很容易可得出两者的优缺点:

OvA缺点:因为是一个类别对多个类别(1:N的关系),所以在训练时可能会更偏向多类别的一方。

OvA优点:假设有n个类别,只需要构建n个分类器。

OvO缺点:在标签类别很多的情况下,需要构建很多个二元分类器,不论构建还是训练的过程都比较麻烦

OvO优点:每个分类器只需要在包含两个类别的部分数据上训练,无需在整个数据集上。

这两种策略的基本思想都是通过构建多个二元分类器来解决多分类问题。大多数二元分类算法比较适用OvA策略,当然并不是全部,并且还需要根据数据集的特点而定。下面利用逻辑回归在鸢尾花数据集上建模,因为数据集比较简单,我们又是只讲这种方法,所以省略掉了分析之类的操作。

手推实现OvA策略

我个人会习惯将数据集转化为容易观察的DataFrame格式:

import pandas as pd
from sklearn.datasets import load_iris
feature_names = load_iris().feature_names
dataset_data = pd.DataFrame(load_iris().data,columns=feature_names)
dataset_target = pd.DataFrame(load_iris().target,columns=['target'])
data = pd.concat([dataset_data,dataset_target],axis = 1)

数据集共有150个样本、四个特征和一个类别标签:

我们采用一对多(OvA策略)结合逻辑回归解决这个多分类问题,先介绍一下手推的方式,建模过程与二分类是一样的,只不过我们需要注意一下OvA策略的思想。

首先需要划分数据集,取七份作为训练集,剩余三份为测试集,基础部分就不贴代码啦,文末会给出完整代码获取方式。OvA策略是有多少个类别就构建多少个分类器,所以需要知道标签变量所有类别,可以利用unique索引,然后利用字典格式存储所有的分类器。

#获取标签变量的类别
unique_targets = data['target'].unique()
'''
array([0, 1, 2])
'''
# 采用OvA策略,三个类别对应三个模型,用字典格式存储
models = {}

每一个分类器都会把一个类别归为一类,剩余的类别归为另一类,所以这里暂定每次循环和target相同的为一类,标签设为1,剩余的两类标签设为0。为了代码的简洁度,这里利用了管道流将每个分类器和标准化处理封装起来。

y_train_copy = y_train.copy()
for target in unique_targets:
    #管道流封装
    models[target] = make_pipeline(StandardScaler(),LogisticRegression())
    y_train_list = y_train_copy.tolist()
    # 每次都要修改训练集的标签,将当前类别的标签设为1,其它类别设为0
    for i in range(len(y_train_list)):
        if y_train_list[i] == target:
            y_train_list[i] = 1
        else:
            y_train_list[i] = 0
    y_train = np.array(y_train_list)
    
    models[target].fit(X_train,y_train)

创建相应的分类器之后,下面需要做的就是在测试集上应用,三个分类器最终会得到三个标签的预测概率。

test_probs = pd.DataFrame(columns=unique_targets)
for target in unique_targets:
    #[:,1]返回的是属于1的概率,[:,0]是属于0的概率
    test_probs[target] = models[target].predict_proba(X_test)[:,1]
print(test_probs)

可以得到的关于概率的DataFrame如下:

在pandas中有一个idxmax()方法可以索引出一个样本中值最大的列索引,在这里就是一个样本最终被划分的类别。

predicted_target = test_probs.idxmax(axis=1)
'''
0     0
1     0
2     1
3     0
4     2
5     1
.......
模型错误率为:6.67%
'''

最后可以通过和原标签比对计算出模型的准确率,至此就是如何利用二元分类器实现多元分类问题的手推方法。

sklearn调用

在sklearn中也有可以实现OvA和OVO策略的类,和手推方法相比会更加简单便捷,分别为OneVsOneClassifier或OneVsRestClassifier。

from sklearn.multiclass import OneVsOneClassifier,OneVsRestClassifier
OvO = OneVsOneClassifier(make_pipeline(StandardScaler(),LogisticRegression()))
OvO.fit(X_train,y_train)
ovo_predict = OvO.predict(X_test)

对于这类库的调用应该都比较熟悉,不在过多介绍,利用相应的方法可以查看类标签和分类器的个数,3个类别比较巧,OvA和OvO两个策略所需构建二元分类器的个数都为3个。

print('类别标签有:%s' % OvO.classes_)
print('分类器个数:%d' % len(OvO.estimators_))
'''
类别标签有:[0 1 2]
分类器个数:3
'''

其实在逻辑回归的multi_class参数中,就有ovr(OvA)这个策略可供选择,但是没有OvO策略。毕竟手推的方式会更容易帮助理解一个策略的思想,理解之后我们再调用类或者调参时才会知道究竟做的是什幺操作,综上就是关于如何利用二分类算法解决多元分类问题的概述。

参考链接:

[1]. https://blog.csdn.net/zm71498…


以上所述就是小编给大家介绍的《Tips | 如何用二元分类器解决一个多分类任务?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员面试金典(第5版)

程序员面试金典(第5版)

[美] Gayle Laakmann McDowell / 李琳骁、漆 犇 / 人民邮电出版社 / 2013-11 / 59.00

本书是原谷歌资深面试官的经验之作,层层紧扣程序员面试的每一个环节,全面而详尽地介绍了程序员应当如何应对面试,才能在面试中脱颖而出。第1~7 章主要涉及面试流程解析、面试官的幕后决策及可能提出的问题、面试前的准备工作、对面试结果的处理等内容;第8~9 章从数据结构、概念与算法、知识类问题和附加面试题4 个方面,为读者呈现了出自微软、苹果、谷歌等多家知名公司的150 道编程面试题,并针对每一道面试题目......一起来看看 《程序员面试金典(第5版)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具