Evaluation Metrics for Binary Classification

an illustration on evaluation metrics for binary classification models

So far, we have discussed the task of classification analysis along with a few version of logistic regression. We have also talked a bit about evaluating a classification task with accuracy score. However, classification is a bit more complicated than regression in that accuracy sometimes cannot completely reflect whether a model is good or bad. For such reason, I will spend this post discussing more evaluation metrics for classification. As usual, we start simple with evaluating models in binary problems.

Data in demonstration

I will use a modified version of the maternal health risk data set which is available on the UCI machine learning repository. I did a bit changes so that we have a binary classification problem that shows the disadvantage of accuracy score. The complete notebook is available in my GitHub.

A first look into the data is as below. We have Age, SystolicBP, DiastolicBP, BS, BodyTemp, and HeartRate of the mothers at labor, and AtRisk as the binary target indicating whether they were at risk of maternal mortality (1) or not (0). All columns are numeric.

Next, we perform a train-test split and examine the histograms. Overall, there are some skewness but nothing too serious. Because we are not optimizing any models in this post, let us just perform a scaling on all features for preprocessing. After this point, we have the data ready for modeling.

Logistic model

To simplify the discussion on evaluation metrics, I am just gonna use a L2-regularized logistic regression. Though, let us still finetune it to avoid a very bad model. The progress here is pretty standard – create a parameter grid, a model, a grid search which is then fitted. Next, we extract the best logistic model with the best_estimator_ property from the grid search, and make predictions for the training and testing data as trainY_pred and testY_pred. For the training data, we use cross_val_predict to avoid overfitted results. You may also notice that I create a trainY_0. This is an array of 0 , a dummy prediction that assumes everything to belong to class 0.

Evaluation metrics for binary classification

At this point, we are ready to discuss some evaluation metrics for binary classification. I will import all the metrics first for convenience.

Accuracy score

Let us review the accuracy score. The CV accuracy in the training data is 85.45% and testing data 82.76%, not bad right? Maybe, but also, maybe not.

The problem with accuracy is that, in this data, the proportion of classes in the target is unbalanced. More specifically, the rate of one class in the target is much higher/lower than that of the other. In this training data, 73.24% has class 0. This means, I can predict that all patients belong to class 0 and get that 73.24% accuracy without any models. This is evidenced in the test below.

Is accuracy still a good measurement to evaluate our model? We went through all the troubles to get only about 12% better accuracy than a random guess. That certainly does not sound very good. So, let dig a bit deeper into the predictions and the true values with the confusion table.

Confusion table

In binary classification, we usually refer to the class of interest in the target as positive, and the other class negative. In this case, we can consider AtRisk values of 1 as positive, and 0 negative. A confusion table (also called confusion matrix) provides these following four numbers:
1. True Positive (TP): number of rows of which actual values are positive and also get predicted as positive
2. True Negative (TN): number of rows of which actual values are negative and also get predicted as negative
3. False Positive (FP): number of rows of which actual values are negative but get predicted as positive
4. False Negative (FN): number of rows of which actual values are positive but get predicted as negative

In SKLearn, we use the confusion_matrix() function to obtain these numbers like the example below. The location for each category is as on the right side (only in SKLearn, other tools may order them differently). Overall, in the training data, 569 rows are correctly predicted as negative, 124 rows are correctly predicted as positive, 25 misclassified from negative to positive, and 93 positive to negative.

True NegativeFalse Positive
False NegativeTrue Positive

How about the confusion table of the dummy prediction? As everything gets predicted as 0, we have 594 TN, 217 FN, 0 TP, and 0 FP. Now, we start seeing some issues with this type of predictions. Specifically, there are 0 rows detected as positive which is the class of interests. Next, let us discuss two measurements that really signify this problem.

Precision and Recall

These are the two measurements focusing on evaluate the prediction quality for the positive class. Precision measures the rate of rows predicted as positive are indeed positive, and Recall the rate of positive rows are predicted as positive. Their formulas are as follows.

precision = \dfrac{TP}{TP + FP}

recall= \dfrac{TP}{TP + FN}

In SKLearn, we use precision_score() and recall_score() to obtain these two measurements. The precision and recall of our L2 logistic model in the training data are 0.832 and 0.571, respectively. The dummy prediction, however, gets a big warning about precision not defined (since its denominator TP+FP is 0) and a 0 recall. Now, we see a very big difference between having and not having a model. However, examining two metrics could be inconvenient at times. So, let us talk about a last measurement, the F1 score.

F1 score

F1 score is a combination of precision and recall. It ranges from 0 to 1, the closer to 1, the better a model, vice versa, the closer to 0, the worse a model. Its formula is as follows.

F1 = \dfrac{2\times precision \times recall}{precision + recall}

In SKLearn, we use f1_score() to obtain this measurement. Below are the some examples. The F1 scores of our model in the training data is 0.678 and testing data 0.607. In contrast, the dummy prediction gets a 0 F1 in the training data, correctly reflecting that it does nothing useful.

So why don’t we just use F1 instead of accuracy all the times? Well, you certainly can. It is really up to your preferences. However, accuracy is not that useless. For one thing, it is a lot easier to understand than F1 score. An accuracy of 90% means that your model assigned the correct class to 90% of the instances. On the other hand, a F1 of 0.9 is more difficult to interpret other than you have a very good model. Furthermore, in data that is more balanced, accuracy is totally okay to use.

Conclusion

In this post, we have discussed several evaluation metrics for binary classification models. There are still a lot more, but these are fairly common that you are more likely to see when browsing around. We will probably explore more metrics in the future, but for now, accuracy and F1 are plenty to use. So, I will conclude this post here. See you next time!