Métrica Precision-Recall para la Clasificación Desequilibrada

Machine LearningMachine LearningBeginner
Practicar Ahora

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

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Este tutorial ofrece una guía paso a paso sobre cómo utilizar la métrica Precision-Recall para evaluar la calidad de la salida del clasificador. La curva Precision-Recall es una medida útil del éxito de la predicción cuando las clases están muy desequilibradas. En la recuperación de información, la precisión es una medida de la relevancia de los resultados, mientras que la recuperación es una medida de cuántos resultados verdaderamente relevantes se devuelven.

Consejos sobre la VM

Una vez finalizada la inicialización de la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.

A veces, es posible que tenga que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.

Si tiene problemas durante el aprendizaje, no dude en preguntar a Labby. Deje sus comentarios después de la sesión y lo resolveremos rápidamente para usted.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) 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/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étrica Precision-Recall para la Clasificación Desequilibrada"}} sklearn/preprocessing -.-> lab-49249{{"Métrica Precision-Recall para la Clasificación Desequilibrada"}} sklearn/pipeline -.-> lab-49249{{"Métrica Precision-Recall para la Clasificación Desequilibrada"}} sklearn/model_selection -.-> lab-49249{{"Métrica Precision-Recall para la Clasificación Desequilibrada"}} sklearn/metrics -.-> lab-49249{{"Métrica Precision-Recall para la Clasificación Desequilibrada"}} sklearn/multiclass -.-> lab-49249{{"Métrica Precision-Recall para la Clasificación Desequilibrada"}} sklearn/datasets -.-> lab-49249{{"Métrica Precision-Recall para la Clasificación Desequilibrada"}} ml/sklearn -.-> lab-49249{{"Métrica Precision-Recall para la Clasificación Desequilibrada"}} end

Conjunto de datos y modelo

Utilizaremos el conjunto de datos iris y un clasificador Linear SVC para diferenciar dos tipos de iris. Primero, importaremos las bibliotecas necesarias y cargaremos el conjunto de datos.

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)

Luego, agregaremos características ruidosas al conjunto de datos y lo dividiremos en conjuntos de entrenamiento y prueba.

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
)

Finalmente, escalaremos los datos utilizando un StandardScaler y ajustaremos un clasificador Linear SVC a los datos de entrenamiento.

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

Trazar la curva Precision-Recall

Para trazar la curva Precision-Recall, utilizaremos la clase PrecisionRecallDisplay de la biblioteca sklearn.metrics. Podemos utilizar el método from_estimator o from_predictions para calcular la curva. El método from_estimator calcula las predicciones para nosotros antes de trazar la curva, mientras que el método from_predictions requiere que nosotros proporcionemos las puntuaciones predichas.

from sklearn.metrics import PrecisionRecallDisplay

## Utilizando el método from_estimator
display = PrecisionRecallDisplay.from_estimator(
    classifier, X_test, y_test, name="LinearSVC", plot_chance_level=True
)
_ = display.ax_.set_title("2-class Precision-Recall curve")

## Utilizando el método 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("2-class Precision-Recall curve")

Trazar la curva Precision-Recall para la clasificación multi-etiqueta

La curva Precision-Recall no admite el caso de clasificación multi-etiqueta. Sin embargo, se puede decidir cómo manejar este caso. Crearemos un conjunto de datos multi-etiqueta, ajustaremos y predeciremos utilizando OneVsRestClassifier y luego trazaremos la curva Precision-Recall.

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

## Crear datos multi-etiqueta
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
)

## Ajustar y predecir utilizando 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)

## Calcular precisión y recuperación para cada clase
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])

## Calcular precisión y recuperación micro-promediadas
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")

## Trazar la curva Precision-Recall micro-promediada
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-promediado sobre todas las clases")

## Trazar la curva Precision-Recall para cada clase y curvas 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="Precisión-recuperación micro-promedio", 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"Precisión-recuperación para la clase {i}", color=color)

handles, labels = display.ax_.get_legend_handles_labels()
handles.extend([l])
labels.extend(["curvas iso-f1"])
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("Extensión de la curva Precision-Recall a multi-clase")
plt.show()

Resumen

Este tutorial ofreció una guía paso a paso sobre cómo utilizar la métrica Precision-Recall para evaluar la calidad de la salida del clasificador. Aprendimos cómo trazar la curva Precision-Recall para la clasificación binaria utilizando la clase PrecisionRecallDisplay de la biblioteca sklearn.metrics. También aprendimos cómo trazar la curva Precision-Recall para la clasificación multi-etiqueta utilizando OneVsRestClassifier y cómo calcular la precisión y la recuperación para cada clase.