Métrique Précision-Rappel pour la classification déséquilibrée

Machine LearningMachine LearningBeginner
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Ce tutoriel fournit un guide étape par étape sur la manière d'utiliser la métrique Précision-Rappel pour évaluer la qualité de la sortie du classifieur. La courbe Précision-Rappel est une mesure utile du succès de la prédiction lorsque les classes sont très déséquilibrées. En récupération d'informations, la précision est une mesure de la pertinence des résultats, tandis que le rappel est une mesure du nombre de résultats réellement pertinents qui sont renvoyés.

Conseils sur la machine virtuelle

Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Carnet de notes pour accéder au carnet Jupyter pour la pratique.

Parfois, vous devrez peut-être attendre quelques secondes pour que le carnet Jupyter ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations du carnet Jupyter.

Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez votre feedback après la session, et nous résoudrons rapidement le problème pour vous.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/CoreModelsandAlgorithmsGroup(["Core Models and Algorithms"]) sklearn(("Sklearn")) -.-> sklearn/DataPreprocessingandFeatureEngineeringGroup(["Data Preprocessing and Feature Engineering"]) sklearn(("Sklearn")) -.-> sklearn/ModelSelectionandEvaluationGroup(["Model Selection and Evaluation"]) sklearn(("Sklearn")) -.-> sklearn/AdvancedDataAnalysisandDimensionalityReductionGroup(["Advanced Data Analysis and Dimensionality Reduction"]) sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/svm("Support Vector Machines") sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/preprocessing("Preprocessing and Normalization") sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/pipeline("Pipeline") sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/model_selection("Model Selection") sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/metrics("Metrics") sklearn/AdvancedDataAnalysisandDimensionalityReductionGroup -.-> sklearn/multiclass("Multiclass Classification") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/datasets("Datasets") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/svm -.-> lab-49249{{"Métrique Précision-Rappel pour la classification déséquilibrée"}} sklearn/preprocessing -.-> lab-49249{{"Métrique Précision-Rappel pour la classification déséquilibrée"}} sklearn/pipeline -.-> lab-49249{{"Métrique Précision-Rappel pour la classification déséquilibrée"}} sklearn/model_selection -.-> lab-49249{{"Métrique Précision-Rappel pour la classification déséquilibrée"}} sklearn/metrics -.-> lab-49249{{"Métrique Précision-Rappel pour la classification déséquilibrée"}} sklearn/multiclass -.-> lab-49249{{"Métrique Précision-Rappel pour la classification déséquilibrée"}} sklearn/datasets -.-> lab-49249{{"Métrique Précision-Rappel pour la classification déséquilibrée"}} ml/sklearn -.-> lab-49249{{"Métrique Précision-Rappel pour la classification déséquilibrée"}} end

Dataset et modèle

Nous utiliserons le jeu de données iris et un classifieur Linear SVC pour différencier deux types d'iris. Tout d'abord, nous importerons les bibliothèques nécessaires et chargerons le jeu de données.

import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC

X, y = load_iris(return_X_y=True)

Ensuite, nous ajouterons des caractéristiques bruitées au jeu de données et le diviserons en ensembles d'entraînement et de test.

random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.concatenate([X, random_state.randn(n_samples, 200 * n_features)], axis=1)

X_train, X_test, y_train, y_test = train_test_split(
    X[y < 2], y[y < 2], test_size=0.5, random_state=random_state
)

Enfin, nous mettrons à l'échelle les données à l'aide d'un StandardScaler et ajusterons un classifieur Linear SVC aux données d'entraînement.

classifier = make_pipeline(
    StandardScaler(), LinearSVC(random_state=random_state, dual="auto")
)
classifier.fit(X_train, y_train)

Tracer la courbe Précision-Rappel

Pour tracer la courbe Précision-Rappel, nous utiliserons la classe PrecisionRecallDisplay du module sklearn.metrics. Nous pouvons utiliser soit la méthode from_estimator soit la méthode from_predictions pour calculer la courbe. La méthode from_estimator calcule les prédictions pour nous avant de tracer la courbe, tandis que la méthode from_predictions nous demande de fournir les scores prédits.

from sklearn.metrics import PrecisionRecallDisplay

## Utilisation de la méthode from_estimator
display = PrecisionRecallDisplay.from_estimator(
    classifier, X_test, y_test, name="LinearSVC", plot_chance_level=True
)
_ = display.ax_.set_title("Courbe Précision-Rappel à 2 classes")

## Utilisation de la méthode from_predictions
y_score = classifier.decision_function(X_test)

display = PrecisionRecallDisplay.from_predictions(
    y_test, y_score, name="LinearSVC", plot_chance_level=True
)
_ = display.ax_.set_title("Courbe Précision-Rappel à 2 classes")

Tracer la courbe Précision-Rappel pour la classification multi-étiquette

La courbe Précision-Rappel ne prend pas en charge le cadre multi-étiquette. Cependant, on peut décider comment traiter ce cas. Nous allons créer un jeu de données multi-étiquette, ajuster et prédire à l'aide de OneVsRestClassifier puis tracer la courbe Précision-Rappel.

from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import average_precision_score

## Créer des données multi-étiquette
Y = label_binarize(y, classes=[0, 1, 2])
n_classes = Y.shape[1]
X_train, X_test, Y_train, Y_test = train_test_split(
    X, Y, test_size=0.5, random_state=random_state
)

## Ajuster et prédire à l'aide de OneVsRestClassifier
classifier = OneVsRestClassifier(
    make_pipeline(StandardScaler(), LinearSVC(random_state=random_state, dual="auto"))
)
classifier.fit(X_train, Y_train)
y_score = classifier.decision_function(X_test)

## Calculer la précision et le rappel pour chaque classe
precision = dict()
recall = dict()
average_precision = dict()
for i in range(n_classes):
    precision[i], recall[i], _ = precision_recall_curve(Y_test[:, i], y_score[:, i])
    average_precision[i] = average_precision_score(Y_test[:, i], y_score[:, i])

## Calculer la précision et le rappel micro-averagés
precision["micro"], recall["micro"], _ = precision_recall_curve(Y_test.ravel(), y_score.ravel())
average_precision["micro"] = average_precision_score(Y_test, y_score, average="micro")

## Tracer la courbe Précision-Rappel micro-averagée
display = PrecisionRecallDisplay(
    recall=recall["micro"],
    precision=precision["micro"],
    average_precision=average_precision["micro"],
    prevalence_pos_label=Counter(Y_test.ravel())[1] / Y_test.size,
)
display.plot(plot_chance_level=True)
_ = display.ax_.set_title("Micro-averagée sur toutes les classes")

## Tracer la courbe Précision-Rappel pour chaque classe et les courbes iso-f1
colors = cycle(["navy", "turquoise", "darkorange", "cornflowerblue", "teal"])
_, ax = plt.subplots(figsize=(7, 8))
f_scores = np.linspace(0.2, 0.8, num=4)
lines, labels = [], []
for f_score in f_scores:
    x = np.linspace(0.01, 1)
    y = f_score * x / (2 * x - f_score)
    (l,) = plt.plot(x[y >= 0], y[y >= 0], color="gray", alpha=0.2)
    plt.annotate("f1={0:0.1f}".format(f_score), xy=(0.9, y[45] + 0.02))

display = PrecisionRecallDisplay(
    recall=recall["micro"],
    precision=precision["micro"],
    average_precision=average_precision["micro"],
)
display.plot(ax=ax, name="Micro-average precision-recall", color="gold")

for i, color in zip(range(n_classes), colors):
    display = PrecisionRecallDisplay(
        recall=recall[i],
        precision=precision[i],
        average_precision=average_precision[i],
    )
    display.plot(ax=ax, name=f"Precision-recall for class {i}", color=color)

handles, labels = display.ax_.get_legend_handles_labels()
handles.extend([l])
labels.extend(["iso-f1 curves"])
ax.set_xlim([0.0, 1.0])
ax.set_ylim([0.0, 1.05])
ax.legend(handles=handles, labels=labels, loc="best")
ax.set_title("Extension de la courbe Précision-Rappel à la multi-classe")
plt.show()

Sommaire

Ce tutoriel a fourni un guide étape par étape sur la manière d'utiliser la métrique Précision-Rappel pour évaluer la qualité de la sortie du classifieur. Nous avons appris comment tracer la courbe Précision-Rappel pour la classification binaire à l'aide de la classe PrecisionRecallDisplay du module sklearn.metrics. Nous avons également appris comment tracer la courbe Précision-Rappel pour la classification multi-étiquette à l'aide de OneVsRestClassifier et comment calculer la précision et le rappel pour chaque classe.