A Receiver Operating Characteristic, or ROC curve, visualizes a classifier's performance. Unlike accuracy, the ROC curve is insensitive to data sets with unbalanced class proportions; unlike precision and recall, the ROC curve illustrates the classifier's performance for all values of the discrimination threshold. ROC curves plot the classifier's recall against its fall-out. Fall-out, or the false positive rate, is the number of false positives divided by the total number of negatives. It is calculated using the following formula:
AUC is the area under the ROC curve; it reduces the ROC curve to a single value, which represents the expected performance of the classifier. The dashed line in the following figure is for a classifier that predicts classes randomly; it has an AUC of 0.5. The solid curve is for a classifier that outperforms random guessing:
Let's plot the ROC curve for our SMS spam classifier:
>>> import numpy as np >>> import pandas as pd >>> import matplotlib.pyplot as plt >>> from sklearn.feature_extraction.text import TfidfVectorizer >>> from sklearn.linear_model.logistic import LogisticRegression >>> from sklearn.cross_validation import train_test_split, cross_val_score >>> from sklearn.metrics import roc_curve, auc >>> df = pd.read_csv('data/sms.csv') >>> X_train_raw, X_test_raw, y_train, y_test = train_test_split(df['message'], df['label']) >>> vectorizer = TfidfVectorizer() >>> X_train = vectorizer.fit_transform(X_train_raw) >>> X_test = vectorizer.transform(X_test_raw) >>> classifier = LogisticRegression() >>> classifier.fit(X_train, y_train) >>> predictions = classifier.predict_proba(X_test) >>> false_positive_rate, recall, thresholds = roc_curve(y_test, predictions[:, 1]) >>> roc_auc = auc(false_positive_rate, recall) >>> plt.title('Receiver Operating Characteristic') >>> plt.plot(false_positive_rate, recall, 'b', label='AUC = %0.2f' % roc_auc) >>> plt.legend(loc='lower right') >>> plt.plot([0, 1], [0, 1], 'r--') >>> plt.xlim([0.0, 1.0]) >>> plt.ylim([0.0, 1.0]) >>> plt.ylabel('Recall') >>> plt.xlabel('Fall-out') >>> plt.show()
From the ROC AUC plot, it is apparent that our classifier outperforms random guessing; most of the plot area lies under its curve: