.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/multioutput/plot_classifier_chain_yeast.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_multioutput_plot_classifier_chain_yeast.py: ================================================== 使用分类器链进行多标签分类 ================================================== 本示例展示了如何使用 :class:`~sklearn.multioutput.ClassifierChain` 来解决多标签分类问题。 解决此类任务的最简单策略是对每个标签(即目标变量的每一列)独立训练一个二元分类器。在预测时,二元分类器的集合用于组装多任务预测。 这种策略无法建模不同任务之间的关系。:class:`~sklearn.multioutput.ClassifierChain` 是一个实现了更高级策略的元估计器(即一个包含内部估计器的估计器)。二元分类器的集合被用作一个链,其中链中一个分类器的预测被用作训练下一个新标签分类器的特征。因此,这些额外的特征允许每个链利用标签之间的相关性。 链的 :ref:`Jaccard 相似度 ` 分数往往高于独立基础模型的分数。 .. GENERATED FROM PYTHON SOURCE LINES 13-17 .. code-block:: Python # 作者:scikit-learn 开发者 # SPDX-License-Identifier: BSD-3-Clause .. GENERATED FROM PYTHON SOURCE LINES 18-21 加载数据集 ----------------- 在这个例子中,我们使用 `yeast `_ 数据集,该数据集包含 2,417 个数据点,每个数据点有 103 个特征和 14 个可能的标签。每个数据点至少有一个标签。作为基线,我们首先为14个标签中的每一个训练一个逻辑回归分类器。为了评估这些分类器的性能,我们在一个保留的测试集上进行预测,并计算每个样本的 Jaccard 相似度。 .. GENERATED FROM PYTHON SOURCE LINES 21-34 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from sklearn.datasets import fetch_openml from sklearn.model_selection import train_test_split # 从 https://www.openml.org/d/40597 加载一个多标签数据集 X, Y = fetch_openml("yeast", version=4, return_X_y=True) Y = Y == "TRUE" X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0) .. GENERATED FROM PYTHON SOURCE LINES 35-43 拟合模型 ---------- 我们拟合了由 :class:`~sklearn.multiclass.OneVsRestClassifier` 包装的 :class:`~sklearn.linear_model.LogisticRegression` 模型和多个 :class:`~sklearn.multioutput.ClassifierChain` 组成的集成模型。 LogisticRegression 被 OneVsRestClassifier 包装 ************************************************** 由于默认情况下 :class:`~sklearn.linear_model.LogisticRegression` 无法处理具有多个目标的数据,我们需要使用 :class:`~sklearn.multiclass.OneVsRestClassifier` 。 在拟合模型后,我们计算 Jaccard 相似度。 .. GENERATED FROM PYTHON SOURCE LINES 43-54 .. code-block:: Python from sklearn.linear_model import LogisticRegression from sklearn.metrics import jaccard_score from sklearn.multiclass import OneVsRestClassifier base_lr = LogisticRegression() ovr = OneVsRestClassifier(base_lr) ovr.fit(X_train, Y_train) Y_pred_ovr = ovr.predict(X_test) ovr_jaccard_score = jaccard_score(Y_test, Y_pred_ovr, average="samples") .. GENERATED FROM PYTHON SOURCE LINES 55-58 二元分类器链 *********************** 由于每条链中的模型是随机排列的,因此链之间的性能差异显著。可以假设存在一个最佳的类顺序,可以产生最佳性能。然而,我们事先并不知道这个顺序。相反,我们可以通过对链的二元预测进行平均并应用0.5的阈值来构建分类器链的投票集成。集成的Jaccard相似度得分高于独立模型,并且往往超过集成中每条链的得分(尽管这在随机排列的链中并不保证)。 .. GENERATED FROM PYTHON SOURCE LINES 58-77 .. code-block:: Python from sklearn.multioutput import ClassifierChain chains = [ClassifierChain(base_lr, order="random", random_state=i) for i in range(10)] for chain in chains: chain.fit(X_train, Y_train) Y_pred_chains = np.array([chain.predict_proba(X_test) for chain in chains]) chain_jaccard_scores = [ jaccard_score(Y_test, Y_pred_chain >= 0.5, average="samples") for Y_pred_chain in Y_pred_chains ] Y_pred_ensemble = Y_pred_chains.mean(axis=0) ensemble_jaccard_score = jaccard_score( Y_test, Y_pred_ensemble >= 0.5, average="samples" ) .. GENERATED FROM PYTHON SOURCE LINES 78-81 绘制结果 ------------ 绘制独立模型、每个链和集成的Jaccard相似性得分(请注意,此图的纵轴并不是从0开始)。 .. GENERATED FROM PYTHON SOURCE LINES 81-113 .. code-block:: Python model_scores = [ovr_jaccard_score] + chain_jaccard_scores + [ensemble_jaccard_score] model_names = ( "Independent", "Chain 1", "Chain 2", "Chain 3", "Chain 4", "Chain 5", "Chain 6", "Chain 7", "Chain 8", "Chain 9", "Chain 10", "Ensemble", ) x_pos = np.arange(len(model_names)) fig, ax = plt.subplots(figsize=(7, 4)) ax.grid(True) ax.set_title("Classifier Chain Ensemble Performance Comparison") ax.set_xticks(x_pos) ax.set_xticklabels(model_names, rotation="vertical") ax.set_ylabel("Jaccard Similarity Score") ax.set_ylim([min(model_scores) * 0.9, max(model_scores) * 1.1]) colors = ["r"] + ["b"] * len(chain_jaccard_scores) + ["g"] ax.bar(x_pos, model_scores, alpha=0.5, color=colors) plt.tight_layout() plt.show() .. image-sg:: /auto_examples/multioutput/images/sphx_glr_plot_classifier_chain_yeast_001.png :alt: Classifier Chain Ensemble Performance Comparison :srcset: /auto_examples/multioutput/images/sphx_glr_plot_classifier_chain_yeast_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 114-121 结果解释 ---------------------- 从该图中可以得出三个主要结论: - 由 :class:`~sklearn.multiclass.OneVsRestClassifier` 包装的独立模型的表现比分类器链的集成和某些单独的链要差。这是因为逻辑回归没有建模标签之间的关系。 - :class:`~sklearn.multioutput.ClassifierChain` 利用了标签之间的相关性,但由于标签排序的随机性,它的结果可能比独立模型更差。 - 链的集成表现更好,因为它不仅捕捉了标签之间的关系,而且不会对它们的正确顺序做出强假设。 .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.952 seconds) .. _sphx_glr_download_auto_examples_multioutput_plot_classifier_chain_yeast.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/scikit-learn/scikit-learn/main?urlpath=lab/tree/notebooks/auto_examples/multioutput/plot_classifier_chain_yeast.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_classifier_chain_yeast.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_classifier_chain_yeast.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_classifier_chain_yeast.zip ` .. include:: plot_classifier_chain_yeast.recommendations .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_