【Scikit-Learn 中文文档】多类和多标签算法 - 监督学习 - 用户指南 | ApacheCN

中文文档: http://sklearn.apachecn.org/cn/stable/modules/multiclass.html

英文文档: http://sklearn.apachecn.org/en/stable/modules/multiclass.html

官方文档: http://scikit-learn.org/stable/

GitHub: https://github.com/apachecn/scikit-learn-doc-zh(觉得不错麻烦给个 Star,我们一直在努力)

贡献者: https://github.com/apachecn/scikit-learn-doc-zh#贡献者

关于我们: http://www.apachecn.org/organization/209.html

1.12. 多类和多标签算法

Warning

All classifiers in scikit-learn do multiclass classification out-of-the-box. You don’t need to use thesklearn.multiclass module unless you want to experiment with different multiclass strategies.

sklearn.multiclass 模块采用了 元评估器 ,通过把``多类`` 和 多标签 分类问题分解为 二元分类问题去解决。这同样适用于多目标回归问题。

  • Multiclass classification 多类分类 意味着一个分类任务需要对多于两个类的数据进行分类。比如,对一系列的橘子,

苹果或者梨的图片进行分类。多类分类假设每一个样本有且仅有一个标签:一个水果可以被归类为苹果,也可以 是梨,但不能同时被归类为两类。

  • Multilabel classification 多标签分类 给每一个样本分配一系列标签。这可以被认为是预测不

相互排斥的数据点的属性,例如与文档类型相关的主题。一个文本可以归类为任意类别,例如可以同时为政治、金融、 教育相关或者不属于以上任何类别。

  • Multioutput regression 多输出分类 为每个样本分配一组目标值。这可以认为是预测每一个样本的多个属性,

比如说一个具体地点的风的方向和大小。

  • Multioutput-multiclass classification and multi-task classification **多输出-多类分类和

多任务分类** 意味着单个的评估器要解决多个联合的分类任务。这是只考虑二分类的 multi-label classification

和 multi-class classification 任务的推广。 此类问题输出的格式是一个二维数组或者一个稀疏矩阵。

每个输出变量的标签集合可以是各不相同的。比如说,一个样本可以将“梨”作为一个输出变量的值,这个输出变 量在一个含有“梨”、“苹果”等水果种类的有限集合中取可能的值;将“蓝色”或者“绿色”作为第二个输出变量的值, 这个输出变量在一个含有“绿色”、“红色”、“蓝色”等颜色种类的有限集合中取可能的值…

这意味着任何处理 multi-output multiclass or multi-task classification 任务的分类器,在特殊的 情况下支持 multi-label classification 任务。Multi-task classification 与具有不同模型公式 的 multi-output classification 相似。详细情况请查阅相关的分类器的文档。

所有的 scikit-learn 分类器都能处理 multiclass classification 任务, 但是 sklearn.multiclass 提供的元评估器允许改变在处理超过两类数据时的方式,因为这会对分类器的性能产生影响 (无论是在泛化误差或者所需要的计算资源方面)

下面是按照 scikit-learn 策略分组的分类器的总结,如果你使用其中的一个,则不需要此类中的元评估器,除非你想要自定义的多分类方式。

Warning

At present, no metric in sklearn.metrics supports the multioutput-multiclass classification task.

1.12.1. 多标签分类格式

在 multilabel learning 中,二元分类任务的合集表示为二进制数组:每一个样本是大小为 (n_samples, n_classes) 的二维数组中的一行二进制值,比如非0元素,表示为对应标签的 子集。 一个数组 np.array([[1, 0, 0], [0, 1, 1], [0, 0, 0]]) 表示第一个样本属于第 0 个标签,第二个样本属于第一个和第二个标签,第三个样本不属于任何标签。

通过一系列的标签来产生多标签数据可能更为直观。 MultiLabelBinarizer 转换器可以用来在标签接口和格式指示器接口之间进行转换。

>>>

>>> from sklearn.preprocessing import MultiLabelBinarizer
>>> y = [[2, 3, 4], [2], [0, 1, 3], [0, 1, 2, 3, 4], [0, 1, 2]]
>>> MultiLabelBinarizer().fit_transform(y)
array([[0, 0, 1, 1, 1],
       [0, 0, 1, 0, 0],
       [1, 1, 0, 1, 0],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 0, 0]])

1.12.2. 1对其余

这个方法也被称为 1对多, 在 OneVsRestClassifier 模块中执行。 这个方法在于每一个类都将用一个分类器进行拟合。 对于每一个分类器,该类将会和其他所有的类有所区别。除了它的计算效率之外 (只需要 n_classes 个分类器), 这种方法的优点是它具有可解释性。 因为每一个类都可以通过有且仅有一个分类器来代表,所以通过检查一个类相关的分类器就可以获得该类的信息。这是最常用的方法,也是一个合理的默认选择。

1.12.2.1. 多类学习

下面是一个使用 OvR 的一个例子:

>>>

>>> from sklearn import datasets
>>> from sklearn.multiclass import OneVsRestClassifier
>>> from sklearn.svm import LinearSVC
>>> iris = datasets.load_iris()
>>> X, y = iris.data, iris.target
>>> OneVsRestClassifier(LinearSVC(random_state=0)).fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

1.12.2.2. 多标签学习

OneVsRestClassifier 1对其余分类器 也支持 multilabel classification. 要使用该功能,给分类器提供一个指示矩阵,比如 [i,j] 表示第i个样本中的第j个标签。

示例:

1.12.3. 1对1

OneVsOneClassifier 1对1分类器 将会为每一对类别构造出一个分类器,在预测阶段,收到最多投票的类别将会被挑选出来。 当存在结时(两个类具有同样的票数的时候), 1对1分类器会选择总分类置信度最高的类,其中总分类置信度是由下层的二元分类器 计算出的成对置信等级累加而成。

因为这需要训练出 n_classes * (n_classes - 1) / 2 个分类器, 由于复杂度为 O(n_classes^2),这个方法通常比 one-vs-the-rest 慢。然而,这个方法也有优点,比如说是在没有很好的缩放 n_samples 数据的核方法中。 这是由于每个单独的学习问题只涉及一小部分数据,而 one-vs-the-rest 将会使用 n_classes 次完整的数据。

1.12.3.1. 多类别学习

Below is an example of multiclass learning using OvO:

>>>

>>> from sklearn import datasets
>>> from sklearn.multiclass import OneVsOneClassifier
>>> from sklearn.svm import LinearSVC
>>> iris = datasets.load_iris()
>>> X, y = iris.data, iris.target
>>> OneVsOneClassifier(LinearSVC(random_state=0)).fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

参考文献:

  • “Pattern Recognition and Machine Learning. Springer”, Christopher M. Bishop, page 183, (First Edition)

1.12.4. 误差校正输出代码

基于Output-code的方法不同于 one-vs-the-rest 和 one-vs-one。使用这些方法,每一个类将会被映射到欧几里得空间,每一个维度上的值只能为0或者1。另一种解释它的方法是,每一个类被表示为二进制 码(一个 由0 和 1 组成的数组)。保存 location (位置)/ 每一个类的编码的矩阵被称为 code book。编码的大小是前面提到的欧几里得空间的纬度。直观上来说,每一个类应该使用一个唯一的编码,同时,好的 code book 应该能够优化分类的精度。 在实现上,我们使用随机产生的 code book,正如在 [3] 提倡的方式,即使更加详尽的方法可能会在未来被加入其中。

在训练时,code book 每一位的二分类器将会被训练。在预测时,分类器将映射到类空间中选中的点的附近。

在 OutputCodeClassifiercode_size 属性允许用户设置将会用到的分类器的数量。 它是类别总数的百分比。

在 0 或 1 之中的一个数字会比 one-vs-the-rest 使用更少的分类器。理论上 log2(n_classes) / n_classes 足以明确表示每个类。然而在实际情况中,这也许会导致不太好的精确度,因为 log2(n_classes) 小于 n_classes.

比 1 大的数字比 one-vs-the-rest 需要更多的分类器。在这种情况下,一些分类器在理论上会纠正其他分类器的错误,因此命名为 “error-correcting” 。然而在实际上这通常不会发生,因为许多分类器的错误通常意义上来说是相关的。error-correcting output codes 和 bagging 有一个相似的作用效果。

1.12.4.1. 多类别学习

Below is an example of multiclass learning using Output-Codes:

>>>

>>> from sklearn import datasets
>>> from sklearn.multiclass import OutputCodeClassifier
>>> from sklearn.svm import LinearSVC
>>> iris = datasets.load_iris()
>>> X, y = iris.data, iris.target
>>> clf = OutputCodeClassifier(LinearSVC(random_state=0),
...                            code_size=2, random_state=0)
>>> clf.fit(X, y).predict(X)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1,
       1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

参考文献:

  • “Solving multiclass learning problems via error-correcting output codes”, Dietterich T., Bakiri G., Journal of Artificial Intelligence Research 2, 1995.

[3]

“The error coding method and PICTs”, James G., Hastie T., Journal of Computational and Graphical statistics 7, 1998.

  • “The Elements of Statistical Learning”, Hastie T., Tibshirani R., Friedman J., page 606 (second-edition) 2008.

1.12.5. 多输出回归

多输出回归支持 MultiOutputRegressor 可以被添加到任何回归器中。这个策略包括对每个目标拟合一个回归器。因为每一个目标可以被一个回归器精确地表示,通过检查对应的回归器,可以获取关于目标的信息。 因为 MultiOutputRegressor 对于每一个目标可以训练出一个回归器,所以它无法利用目标之间的相关度信息。

以下是 multioutput regression(多输出回归)的示例:

>>>

>>> from sklearn.datasets import make_regression
>>> from sklearn.multioutput import MultiOutputRegressor
>>> from sklearn.ensemble import GradientBoostingRegressor
>>> X, y = make_regression(n_samples=10, n_targets=3, random_state=1)
>>> MultiOutputRegressor(GradientBoostingRegressor(random_state=0)).fit(X, y).predict(X)
array([[-154.75474165, -147.03498585,  -50.03812219],
       [   7.12165031,    5.12914884,  -81.46081961],
       [-187.8948621 , -100.44373091,   13.88978285],
       [-141.62745778,   95.02891072, -191.48204257],
       [  97.03260883,  165.34867495,  139.52003279],
       [ 123.92529176,   21.25719016,   -7.84253   ],
       [-122.25193977,  -85.16443186, -107.12274212],
       [ -30.170388  ,  -94.80956739,   12.16979946],
       [ 140.72667194,  176.50941682,  -17.50447799],
       [ 149.37967282,  -81.15699552,   -5.72850319]])

1.12.6. 多输出分类

Multioutput classification 支持能够被添加到任何带有 MultiOutputClassifier 标志的分类器中. 这种方法为每一个目标训练一个分类器。 这就允许产生多目标变量分类器。这种类的目的是扩展评估器用于评估一系列目标函数 (f1,f2,f3…,fn) ,这些函数在一个单独的预测矩阵上进行训练以此来预测一系列的响应 (y1,y2,y3…,yn)。

下面是多输出分类的一个例子:

>>>

>>> from sklearn.datasets import make_classification
>>> from sklearn.multioutput import MultiOutputClassifier
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.utils import shuffle
>>> import numpy as np
>>> X, y1 = make_classification(n_samples=10, n_features=100, n_informative=30, n_classes=3, random_state=1)
>>> y2 = shuffle(y1, random_state=1)
>>> y3 = shuffle(y1, random_state=2)
>>> Y = np.vstack((y1, y2, y3)).T
>>> n_samples, n_features = X.shape # 10,100
>>> n_outputs = Y.shape[1] # 3
>>> n_classes = 3
>>> forest = RandomForestClassifier(n_estimators=100, random_state=1)
>>> multi_target_forest = MultiOutputClassifier(forest, n_jobs=-1)
>>> multi_target_forest.fit(X, Y).predict(X)
array([[2, 2, 0],
       [1, 2, 1],
       [2, 1, 0],
       [0, 0, 2],
       [0, 2, 1],
       [0, 0, 2],
       [1, 1, 0],
       [1, 1, 1],
       [0, 0, 2],
       [2, 0, 0]])

1.12.7. 链式分类器

Classifier chains (查看 ClassifierChain) 是一种集合多个二分类器为一个单独的多标签模型的方法,这种方法能够发掘目标之间的相关性信息。

对于有 N 个类的多标签分类问题,为 N 个二元分类器分配 0 到 N-1 之间的一个整数。这些整数定义了模型在 chain 中的顺序。将每个分类器拟合可用的训练数据与真实的类别标签,标签数字相对较小。

当进行预测时,真正的标签将无法使用。相反,每一个模型的预测结果将会传递给链上的下一个模型作为特征来进行使用。

很明显,链的顺序是十分重要的。链上的第一个模型没有关于其他标签的信息,而链上的最后一个模型将会具有所有其他标签的信息。 在一般情况下,我们并不知道链上模型最优的顺序,因此通常会使用许多随机的顺序,将他们的预测求平均。

参考文献:

Jesse Read, Bernhard Pfahringer, Geoff Holmes, Eibe Frank, “Classifier Chains for Multi-label Classification”, 2009.

中文文档: http://sklearn.apachecn.org/cn/stable/modules/multiclass.html

英文文档: http://sklearn.apachecn.org/en/stable/modules/multiclass.html

官方文档: http://scikit-learn.org/stable/

GitHub: https://github.com/apachecn/scikit-learn-doc-zh(觉得不错麻烦给个 Star,我们一直在努力)

贡献者: https://github.com/apachecn/scikit-learn-doc-zh#贡献者

关于我们: http://www.apachecn.org/organization/209.html

有兴趣的们也可以和我们一起来维护,持续更新中 。。。

机器学习交流群: 629470233

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云时之间

机器学习重要算法-PCA主成分分析

大家好,很高兴可以和大家一起来继续学习机器学习,这几天时间,我着重研究了下主成分分析法,不过因为其数学推理实在有些过于繁琐和复杂,我也没太搞得太清楚,如果在文章...

5239
来自专栏进击的程序猿

线性回归背后的数学

本文是YouTube上视频How to Do Linear Regression the Right Way笔记

872
来自专栏CDA数据分析师

R语言的三种聚类方法

? 原文链接:https://my.oschina.net/u/1047640/blog/202714#OSC_h4_2 摘要: 层次聚类 kmeans db...

2018
来自专栏Brian

数据挖掘

---- 概述 最近一直在学习数据挖掘和机器学习,无论是是服务端开发人员还是web开发人员,个人觉得最起码都要都一些最基本的数据挖掘和机器学习知识。废话少说,我...

2785
来自专栏机器学习算法原理与实践

scikit-learn随机森林调参小结

    在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结。本文就从实践的角度对RF做一个总结...

1455
来自专栏灯塔大数据

每周学点大数据 | No.16平面图直径

No.16期 平面图直径 小可:好的,关于图的基本内容我听懂了。 Mr. 王:很好,图能够对很多现实问题进行数学抽象,方便通过计算机的手段进行抽象。而平面图指...

3074
来自专栏专知

【Python实战】无监督学习—聚类、层次聚类、t-SNE,DBSCAN

【导读】本文主要介绍了无监督学习在Python上的实践,围绕着无监督学习,讲述了当前主流的无监督聚类方法:数据准备,聚类,K-Means Python实现,层次...

1483
来自专栏PPV课数据科学社区

【V课堂】R语言十八讲(十三)—聚类模型

聚类分析是一种原理简单、应用广泛的数据挖掘技术。顾名思义,聚类分析即是把若干事物按照某种标准归为几个类别,其中较为相近的聚为一类,不那么相近的聚于不同类。聚类分...

3277
来自专栏数据处理

推导svm约束条件为等式求极值下面看看不等式约束,求极值,可行域变大了推导svmSVM—线性不可分—核函数

1384
来自专栏数据科学与人工智能

【算法】相似度计算方法原理及实现

小编邀请您,先思考: 1 相似度如何计算? 2 相似度有什么应用? 温馨提示:加入圈子或者商务合作,请加微信:luqin360 在数据分析和数据挖掘以及搜索引擎...

3486

扫码关注云+社区