Estoy tratando de trazar una curva ROC para evaluar la precisión de un modelo de predicción que desarrollé en Python usando paquetes de regresión logística. He calculado la tasa de verdaderos positivos así como la tasa de falsos positivos; sin embargo, no puedo averiguar cómo trazarlos correctamente usando matplotlib
y calcular el valor AUC. ¿Cómo puedo hacer eso?
python
matplotlib
plot
statistics
roc
usuario3847447
fuente
fuente
all thresholds
, cómo se calculan?Esta es la forma más sencilla de trazar una curva ROC, dado un conjunto de etiquetas de verdad del terreno y probabilidades predichas. La mejor parte es que traza la curva ROC para TODAS las clases, por lo que también obtiene múltiples curvas de aspecto ordenado
import scikitplot as skplt import matplotlib.pyplot as plt y_true = # ground truth labels y_probas = # predicted probabilities generated by sklearn classifier skplt.metrics.plot_roc_curve(y_true, y_probas) plt.show()
Aquí hay una curva de muestra generada por plot_roc_curve. Usé el conjunto de datos de dígitos de muestra de scikit-learn, por lo que hay 10 clases. Observe que se traza una curva ROC para cada clase.
Descargo de responsabilidad: tenga en cuenta que esto usa la biblioteca scikit-plot , que construí.
fuente
y_true ,y_probas
?skplt.metrics.plot_roc_curve(y_true, y_probas)
:? Un gran gracias.No está del todo claro cuál es el problema aquí, pero si tiene una matriz
true_positive_rate
y una matrizfalse_positive_rate
, entonces trazar la curva ROC y obtener el AUC es tan simple como:import matplotlib.pyplot as plt import numpy as np x = # false_positive_rate y = # true_positive_rate # This is the ROC curve plt.plot(x,y) plt.show() # This is the AUC auc = np.trapz(y,x)
fuente
Curva AUC para clasificación binaria usando matplotlib
from sklearn import svm, datasets from sklearn import metrics from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.datasets import load_breast_cancer import matplotlib.pyplot as plt
Cargar conjunto de datos de cáncer de mama
Dividir el conjunto de datos
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.33, random_state=44)
Modelo
clf = LogisticRegression(penalty='l2', C=0.1) clf.fit(X_train, y_train) y_pred = clf.predict(X_test)
Exactitud
print("Accuracy", metrics.accuracy_score(y_test, y_pred))
Curva AUC
y_pred_proba = clf.predict_proba(X_test)[::,1] fpr, tpr, _ = metrics.roc_curve(y_test, y_pred_proba) auc = metrics.roc_auc_score(y_test, y_pred_proba) plt.plot(fpr,tpr,label="data 1, auc="+str(auc)) plt.legend(loc=4) plt.show()
fuente
Aquí está el código de Python para calcular la curva ROC (como un diagrama de dispersión):
import matplotlib.pyplot as plt import numpy as np score = np.array([0.9, 0.8, 0.7, 0.6, 0.55, 0.54, 0.53, 0.52, 0.51, 0.505, 0.4, 0.39, 0.38, 0.37, 0.36, 0.35, 0.34, 0.33, 0.30, 0.1]) y = np.array([1,1,0, 1, 1, 1, 0, 0, 1, 0, 1,0, 1, 0, 0, 0, 1 , 0, 1, 0]) # false positive rate fpr = [] # true positive rate tpr = [] # Iterate thresholds from 0.0, 0.01, ... 1.0 thresholds = np.arange(0.0, 1.01, .01) # get number of positive and negative examples in the dataset P = sum(y) N = len(y) - P # iterate through all thresholds and determine fraction of true positives # and false positives found at this threshold for thresh in thresholds: FP=0 TP=0 for i in range(len(score)): if (score[i] > thresh): if y[i] == 1: TP = TP + 1 if y[i] == 0: FP = FP + 1 fpr.append(FP/float(N)) tpr.append(TP/float(P)) plt.scatter(fpr, tpr) plt.show()
fuente
from sklearn import metrics import numpy as np import matplotlib.pyplot as plt y_true = # true labels y_probas = # predicted results fpr, tpr, thresholds = metrics.roc_curve(y_true, y_probas, pos_label=0) # Print ROC curve plt.plot(fpr,tpr) plt.show() # Print AUC auc = np.trapz(tpr,fpr) print('AUC:', auc)
fuente
y_true = # true labels, y_probas = # predicted results
?Las respuestas anteriores suponen que usted mismo calculó TP / Sens. Es una mala idea hacer esto manualmente, es fácil cometer errores con los cálculos, en lugar de usar una función de biblioteca para todo esto.
la función plot_roc en scikit_lean hace exactamente lo que necesitas: http://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html
La parte esencial del código es:
for i in range(n_classes): fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i]) roc_auc[i] = auc(fpr[i], tpr[i])
fuente
Basado en múltiples comentarios de stackoverflow, documentación de scikit-learn y algunos otros, hice un paquete de Python para trazar la curva ROC (y otra métrica) de una manera realmente simple.
Para instalar el paquete:
pip install plot-metric
(más información al final de la publicación)Para trazar una curva ROC (el ejemplo proviene de la documentación):
Clasificación binaria
Carguemos un conjunto de datos simple y hagamos un tren y un conjunto de prueba:
from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split X, y = make_classification(n_samples=1000, n_classes=2, weights=[1,1], random_state=1) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=2)
Entrene un clasificador y prediga el conjunto de pruebas:
from sklearn.ensemble import RandomForestClassifier clf = RandomForestClassifier(n_estimators=50, random_state=23) model = clf.fit(X_train, y_train) # Use predict_proba to predict probability of the class y_pred = clf.predict_proba(X_test)[:,1]
Ahora puede usar plot_metric para trazar la curva ROC:
from plot_metric.functions import BinaryClassification # Visualisation with plot_metric bc = BinaryClassification(y_test, y_pred, labels=["Class 1", "Class 2"]) # Figures plt.figure(figsize=(5,5)) bc.plot_roc_curve() plt.show()
Resultado:
Puede encontrar más ejemplos en github y la documentación del paquete:
fuente
También puede seguir el formulario de documentación oficial scikit:
https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html#sphx-glr-auto-examples-model-selection-plot-roc-py
fuente
He creado una función simple incluida en un paquete para la curva ROC. Acabo de comenzar a practicar el aprendizaje automático, así que por favor, avíseme también si este código tiene algún problema.
¡Eche un vistazo al archivo léame de github para obtener más detalles! :)
https://github.com/bc123456/ROC
from sklearn.metrics import confusion_matrix, accuracy_score, roc_auc_score, roc_curve import matplotlib.pyplot as plt import seaborn as sns import numpy as np def plot_ROC(y_train_true, y_train_prob, y_test_true, y_test_prob): ''' a funciton to plot the ROC curve for train labels and test labels. Use the best threshold found in train set to classify items in test set. ''' fpr_train, tpr_train, thresholds_train = roc_curve(y_train_true, y_train_prob, pos_label =True) sum_sensitivity_specificity_train = tpr_train + (1-fpr_train) best_threshold_id_train = np.argmax(sum_sensitivity_specificity_train) best_threshold = thresholds_train[best_threshold_id_train] best_fpr_train = fpr_train[best_threshold_id_train] best_tpr_train = tpr_train[best_threshold_id_train] y_train = y_train_prob > best_threshold cm_train = confusion_matrix(y_train_true, y_train) acc_train = accuracy_score(y_train_true, y_train) auc_train = roc_auc_score(y_train_true, y_train) print 'Train Accuracy: %s ' %acc_train print 'Train AUC: %s ' %auc_train print 'Train Confusion Matrix:' print cm_train fig = plt.figure(figsize=(10,5)) ax = fig.add_subplot(121) curve1 = ax.plot(fpr_train, tpr_train) curve2 = ax.plot([0, 1], [0, 1], color='navy', linestyle='--') dot = ax.plot(best_fpr_train, best_tpr_train, marker='o', color='black') ax.text(best_fpr_train, best_tpr_train, s = '(%.3f,%.3f)' %(best_fpr_train, best_tpr_train)) plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.0]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC curve (Train), AUC = %.4f'%auc_train) fpr_test, tpr_test, thresholds_test = roc_curve(y_test_true, y_test_prob, pos_label =True) y_test = y_test_prob > best_threshold cm_test = confusion_matrix(y_test_true, y_test) acc_test = accuracy_score(y_test_true, y_test) auc_test = roc_auc_score(y_test_true, y_test) print 'Test Accuracy: %s ' %acc_test print 'Test AUC: %s ' %auc_test print 'Test Confusion Matrix:' print cm_test tpr_score = float(cm_test[1][1])/(cm_test[1][1] + cm_test[1][0]) fpr_score = float(cm_test[0][1])/(cm_test[0][0]+ cm_test[0][1]) ax2 = fig.add_subplot(122) curve1 = ax2.plot(fpr_test, tpr_test) curve2 = ax2.plot([0, 1], [0, 1], color='navy', linestyle='--') dot = ax2.plot(fpr_score, tpr_score, marker='o', color='black') ax2.text(fpr_score, tpr_score, s = '(%.3f,%.3f)' %(fpr_score, tpr_score)) plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.0]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC curve (Test), AUC = %.4f'%auc_test) plt.savefig('ROC', dpi = 500) plt.show() return best_threshold
Un gráfico roc de muestra producido por este código
fuente
y_train_true, y_train_prob, y_test_true, y_test_prob
?y_train_true, y_test_true
debe estar disponible en un conjunto de datos etiquetado.y_train_prob, y_test_prob
son salidas de su red neuronal entrenada.Hay una biblioteca llamada metriculous que lo hará por usted:
Primero hagamos una simulación de algunos datos, esto generalmente vendría del conjunto de datos de prueba y del modelo (s):
import numpy as np def normalize(array2d: np.ndarray) -> np.ndarray: return array2d / array2d.sum(axis=1, keepdims=True) class_names = ["Cat", "Dog", "Pig"] num_classes = len(class_names) num_samples = 500 # Mock ground truth ground_truth = np.random.choice(range(num_classes), size=num_samples, p=[0.5, 0.4, 0.1]) # Mock model predictions perfect_model = np.eye(num_classes)[ground_truth] noisy_model = normalize( perfect_model + 2 * np.random.random((num_samples, num_classes)) ) random_model = normalize(np.random.random((num_samples, num_classes)))
Ahora podemos usar metriculous para generar una tabla con varias métricas y diagramas, incluidas las curvas ROC:
import metriculous metriculous.compare_classifiers( ground_truth=ground_truth, model_predictions=[perfect_model, noisy_model, random_model], model_names=["Perfect Model", "Noisy Model", "Random Model"], class_names=class_names, one_vs_all_figures=True, # This line is important to include ROC curves in the output ).save_html("model_comparison.html").display()
Las curvas ROC en la salida:
Los gráficos se pueden ampliar y arrastrar, y obtienes más detalles al pasar el mouse sobre el gráfico:
fuente