brainsteam.co.uk/brainsteam/content/posts/legacy/2016-05-29-cognitive-qualit...

810 lines
23 KiB
Markdown
Raw Permalink Normal View History

2020-12-28 11:39:11 +00:00
---
author: James
2023-07-09 11:34:44 +01:00
date: 2016-05-29 09:41:26+00:00
2020-12-28 11:39:11 +00:00
featured_image: /wp-content/uploads/2016/05/Oma--825x510.png
medium_post:
2023-07-09 11:34:44 +01:00
- O:11:"Medium_Post":11:{s:16:"author_image_url";s:69:"https://cdn-images-1.medium.com/fit/c/200/200/0*naYvMn9xdbL5qlkJ.jpeg";s:10:"author_url";s:30:"https://medium.com/@jamesravey";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"1f1de4b3132e";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:96:"https://medium.com/@jamesravey/cognitive-quality-assurance-pt-2-performance-metrics-1f1de4b3132e";}
post_meta:
- date
2024-10-28 20:59:46 +00:00
preview: /social/718fe025946e97b071a5693a04337eca62b1226ef44519e946f5350cca569cf9.png
2020-12-28 11:39:11 +00:00
tags:
2023-07-09 11:34:44 +01:00
- quality assurance
- machine learning
- watson
- work
title: 'Cognitive Quality Assurance Pt 2: Performance Metrics'
type: posts
url: /2016/05/29/cognitive-quality-assurance-pt-2-performance-metrics/
2020-12-28 11:39:11 +00:00
---
***EDIT: Hello readers, these articles are now 4 years old and many of the Watson services and APIs have moved or been changed. The concepts discussed in these articles are still relevant but I am working on 2nd editions of them.***
[Last time][1] we discussed some good practices for collecting data and then splitting it into test and train in order to create a ground truth for your machine learning system. We then talked about calculating accuracy using test and blind data sets.
In this post we will talk about some more metrics you can do on your machine learning system including **Precision**, **Recall**, **F-measure** and **confusion matrices.** These metrics give you a much deeper level of insight into how your system is performing and provide hints at how you could improve performance too!
## A recap – Accuracy calculation
This is the most simple calculation but perhaps the least interesting. We are just looking at the percentage of times the classifier got it right versus the percentage of times it failed. Simply:
1. sum up the number of results (count the rows),
2. sum up the number of rows where the predicted label and the actual label match.
3. Calculate percentage accuracy: correct / total * 100.
This tells you how good the classifier is in general across all classes. It does not help you in understanding how that result is made up.
## Going above and beyond accuracy: why is it important?
<img loading="lazy" class="alignleft" src="https://i1.wp.com/openclipart.org/image/2400px/svg_to_png/13234/Anonymous-target-with-arrow.png?resize=268%2C250&#038;ssl=1" alt="target with arrow by Anonymous" width="268" height="250" data-recalc-dims="1" />Imagine that you are a hospital and it is critically important to be able to predict different types of cancer and how urgently they should be treated. Your classifier is 73% accurate overall but that does not tell you anything about it&#8217;s ability to predict any one type of cancer. What if the 27% of the answers it got wrong were the cancers that need urgent treatment? We wouldn&#8217;t know!
This is exactly why we need to use measurements like precision, recall and f-measure as well as confusion matrices in order to understand what is really going on inside the classifier and which particular classes (if any) it is really struggling with.
## Precision, Recall and F-measure and confusion matrices (Grandma&#8217;s Memory Game)
<img loading="lazy" class="alignright" src="https://i2.wp.com/openclipart.org/image/2400px/svg_to_png/213139/Oma-.png?resize=264%2C391&#038;ssl=1" alt="Grandma's face by frankes" width="264" height="391" data-recalc-dims="1" />Precision, Recall and F-measure are incredibly useful for getting a deeper understanding of which classes the classifier is struggling with. They can be a little bit tricky to get your head around so lets use a metaphor about Grandma&#8217;s memory.
Imagine Grandma has 24 grandchildren. As you can understand it is particularly difficult to remember their names. Thankfully, her 6 children, the grandchildren&#8217;s parents all had 4 kids and named them after themselves. Her son Steve has 3 sons: Steve I, Steve II, Steve III and so on.
This makes things much easier for Grandma, she now only has to remember 6 names: Brian, Steve, Eliza, Diana, Nick and Reggie. The children do not like being called the wrong name so it is vitally important that she correctly classifies the child into the right name group when she sees them at the family reunion every Christmas.
I will now describe Precision, Recall, F-Measure and confusion matrices in terms of Grandma&#8217;s predicament.
### Some Terminology
Before we get on to precision and recall, I need to introduce the concepts of true positive, false positive, true negative and false negative. Every time Grandma gets an answer wrong or right, we can talk about it in terms of these labels and this will also help us get to grips with precision and recall later.
These phrases are in terms of each class &#8211; you have TP, FP, FN, TN for each class. In this case we can have TP,FP,FN,TN with respect to Brian, with respect to Steve, with respect to Eliza and so on.
This table shows how these four labels apply to the class &#8220;Brian&#8221; &#8211; you can create a table will
<table border="0" cellspacing="0">
<colgroup width="197"></colgroup> <colgroup span="2" width="85"></colgroup> <tr>
<td align="left" height="17">
</td>
<td align="left">
Brian
</td>
<td align="left">
Not Brian
</td>
</tr>
<tr>
<td align="left" height="17">
Grandma says “Brian”
</td>
<td align="left">
True Positive
</td>
<td align="left">
False Positive
</td>
</tr>
<tr>
<td align="left" height="17">
Grandma says <not brian>
</td>
<td align="left">
False Negative
</td>
<td align="left">
True Negative
</td>
</tr>
</table>
* If Grandma calls a Brian, Brian then we have a true positive (with respect to the Brian class) &#8211; the answer is true in both senses- Brian&#8217;s name is indeed Brian AND Grandma said Brian &#8211; go Grandma!
* If Grandma calls a Brian, Steve then we have a false negative (with respect to the Brian class). Brian&#8217;s name is Brian and Grandma said Steve. This is also a false positive with respect to the Steve Class.
* If Grandma calls a Steve, Brian then we have a false positive (with respect to the Brian class). Steve&#8217;s name is Steve, Grandma wrongly said Brian (i.e. identified positively).
* If Grandma calls an Eliza, Eliza, or Steve, or Diana, or Nick &#8211; the result is the same &#8211; we have a true negative (with respect to the Brian class). Eliza,Eliza would obviously be a true positive with respect to the Eliza class but because we are only interested in Brian and what is or isn&#8217;t Brian at this point, we are not measuring this.
When you are recording results, it is helpful to store them in terms of each of these labels where applicable. For example:
Steve,Steve (TP Steve, TN everything else)
Brian,Steve (FN Brian, FP Steve)
### Precision and Recall
Grandma is in the kitchen, pouring herself a Christmas Sherry when three Brians and 2 Steves come in to top up their eggnogs.
Grandma correctly classifies 2 Brians but slips up and calls one of them Eliza. She only gets 1 of the Steve&#8217; and calls the other Brian.
In terms of TP,FP,TN,FN we can say the following (true negative is the least interesting for us):
<table border="0" cellspacing="0">
<colgroup width="197"></colgroup> <colgroup span="3" width="85"></colgroup> <tr>
<td align="left" height="17">
</td>
<td align="left">
TP
</td>
<td align="left">
FP
</td>
<td align="left">
FN
</td>
</tr>
<tr>
<td align="left" height="17">
Brian
</td>
<td align="right">
2
</td>
<td align="right">
1
</td>
<td align="right">
1
</td>
</tr>
<tr>
<td align="left" height="17">
Eliza
</td>
<td align="right">
</td>
<td align="right">
1
</td>
<td align="right">
</td>
</tr>
<tr>
<td align="left" height="17">
Steve
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
1
</td>
</tr>
</table>
* She has correctly identified 2 people who are truly called Brian as Brian (TP)
* She has falsely named someone Eliza when their name is not Eliza (FP)
* She has falsely named someone whose name is truly Steve something else (FN)
**True Positive, False Positive, True Negative and False negative are crucial to understand before you look at precision and recall so make sure you have fully understood this section before you move on.**
#### Precision
Precision, like our TP/FP labels, is expressed in terms of each class or name. It is the proportion of true positive name guesses divided by true positive + false positive guesses.
Put another way, precision is how many times Grandma correctly guessed Brian versus how many times she called other people (like Steve) Brian.
For Grandma to be precise, she needs to be very good at correctly guessing Brians **and also** never call anyone else (Elizas and Steves) Brian.
_**Important: If Grandma came to the conclusion that 70% of her grandchildren were named Brian and decided to just randomly say &#8220;Brian&#8221; most of the time, she could still achieve a high overall accuracy. However, her Precision &#8211; with respect to Brian would be poor because of all the Steves and Elizas she was mis-labelling. This is why precision is important.**_
<table border="0" cellspacing="0">
<colgroup width="197"></colgroup> <colgroup span="4" width="85"></colgroup> <tr>
<td align="left" height="17">
</td>
<td align="left">
TP
</td>
<td align="left">
FP
</td>
<td align="left">
FN
</td>
<td align="left">
Precision
</td>
</tr>
<tr>
<td align="left" height="17">
Brian
</td>
<td align="right">
2
</td>
<td align="right">
1
</td>
<td align="right">
1
</td>
<td align="right">
66%
</td>
</tr>
<tr>
<td align="left" height="17">
Eliza
</td>
<td align="right">
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
N/A
</td>
</tr>
<tr>
<td align="left" height="17">
Steve
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
1
</td>
<td align="right">
100%
</td>
</tr>
</table>
The results from this case are displayed above. As you can see, Grandma uses Brian to incorrectly label Steve so precision is only 66%. Despite only getting one of the Steves correct, Grandma has 100% precision for Steve simply by never using the name incorrectly. We can&#8217;t calculate for Eliza because there were no true positive guesses for that name ( 0 / 1 is still zero ).
So what about false negatives? Surely it&#8217;s important to note how often Grandma is inaccurately calling  Brian by other names? We&#8217;ll look at that now&#8230;
#### Recall
Continuing the theme, Recall is also expressed in terms of each class. It is the proportion of true positive name guesses divided by true positive + false negative guesses.
Another way to look at it is given a population of Brians, how many does Grandma correctly identify and how many does she give another name (i.e. Eliza or Steve)?
This tells us how &#8220;confusing&#8221; Brian is as a class. If Recall is high then its likely that Brians all have a very distinctive feature that distinguishes them as Brians (maybe they all have the same nose). If Recall is low, maybe Brians are very varied in appearance and perhaps look a lot like Elizas or Steves (this presents a problem of its own, check out confusion matrices below for more on this).
<table border="0" cellspacing="0">
<colgroup width="197"></colgroup> <colgroup span="4" width="85"></colgroup> <tr>
<td align="left" height="17">
</td>
<td align="left">
TP
</td>
<td align="left">
FP
</td>
<td align="left">
FN
</td>
<td align="left">
Recall
</td>
</tr>
<tr>
<td align="left" height="17">
Brian
</td>
<td align="right">
2
</td>
<td align="right">
1
</td>
<td align="right">
1
</td>
<td align="right">
66.6%
</td>
</tr>
<tr>
<td align="left" height="17">
Eliza
</td>
<td align="right">
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
N/A
</td>
</tr>
<tr>
<td align="left" height="17">
Steve
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
1
</td>
<td align="right">
50%
</td>
</tr>
</table>
You can see that recall for Brian remains the same (of the 3 Brians Grandma named, she only guessed incorrectly for one). Recall for Steve is 50% because Grandma guessed correctly for 1 and incorrectly for the other Steve. Again Eliza can&#8217;t be calculated because we end up trying to divide zero by zero.
**F-Measure**
F-measure effectively a measurement of how accurate the classifier is per class once you factor in both precision and recall. This gives you a wholistic view of your classifier&#8217;s performance on a particular class.
In terms of Grandma, f-measure give us an aggregate metric of how good Grandma is at dealing with Brians in terms of both precision AND accuracy.
It is very simple to calculate if you already have precision and recall:
![F_1 = 2 \cdot \frac{\mathrm{precision} \cdot \mathrm{recall}}{\mathrm{precision} + \mathrm{recall}}][2]
Here are the F-Measure results for Brian, Steve and Eliza from above.
<table border="0" cellspacing="0">
<colgroup width="197"></colgroup> <colgroup span="6" width="85"></colgroup> <tr>
<td align="left" height="17">
</td>
<td align="left">
TP
</td>
<td align="left">
FP
</td>
<td align="left">
FN
</td>
<td align="left">
Precision
</td>
<td align="left">
Recall
</td>
<td align="left">
F-measure
</td>
</tr>
<tr>
<td align="left" height="17">
Brian
</td>
<td align="right">
2
</td>
<td align="right">
1
</td>
<td align="right">
1
</td>
<td align="right">
66.6%
</td>
<td align="right">
66.6%
</td>
<td align="right">
66.6%
</td>
</tr>
<tr>
<td align="left" height="17">
Eliza
</td>
<td align="right">
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
N/A
</td>
<td align="right">
N/A
</td>
<td align="right">
N/A
</td>
</tr>
<tr>
<td align="left" height="17">
Steve
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
1
</td>
<td align="right">
1
</td>
<td align="right">
0.5
</td>
<td align="right">
0.6666666667
</td>
</tr>
</table>
As you can see &#8211; the F-measure is the average ([harmonic mean][3]) of the two values &#8211; this can often give you a good overview of both precision and recall and is dramatically affected by one of the contributing measurements being poor.
### Confusion Matrices
When a class has a particularly low Recall or Precision, the next question should be why? Often you can improve a classifier&#8217;s performance by modifying  the data or (if you have control of the classifier) which features you are training on.
For example, what if we find out that Brians look a lot like Elizas? We could add a new feature (Grandma could start using their voice pitch to determine their gender and their gender to inform her name choice) or we could update the data (maybe we could make all Brians wear a blue jumper and all Elizas wear a green jumper).
Before we go down that road, we need to understand where there is confusion between classes  and where Grandma is doing well. This is where a confusion matrix helps.
A Confusion Matrix allows us to see which classes are being correctly predicted and which classes Grandma is struggling to predict and getting most confused about. It also crucially gives us insight into which classes Grandma is confusing as above. Here is an example of a confusion Matrix for Grandma&#8217;s family.
<table border="0" cellspacing="0">
<colgroup width="179"></colgroup> <colgroup span="7" width="85"></colgroup> <tr>
<td align="left" height="17">
</td>
<td align="left">
</td>
<td colspan="6" align="center" valign="middle">
<b>Predictions</b>
</td>
</tr>
<tr>
<td align="left" height="17">
</td>
<td align="left">
</td>
<td align="left">
Steve
</td>
<td align="left">
Brian
</td>
<td align="left">
Eliza
</td>
<td align="left">
Diana
</td>
<td align="left">
Nick
</td>
<td align="left">
Reggie
</td>
</tr>
<tr>
<td rowspan="6" align="center" valign="middle" height="102">
<b>Actual </b></p>
<p>
<b>Class</b></td>
<td align="left">
Steve
</td>
<td align="right">
<strong>4</strong>
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
</td></tr>
<tr>
<td align="left">
Brian
</td>
<td align="right">
1
</td>
<td align="right">
<strong>3</strong>
</td>
<td align="right">
</td>
<td align="right">
</td>
<td align="right">
1
</td>
<td align="right">
1
</td>
</tr>
<tr>
<td align="left">
Eliza
</td>
<td align="right">
</td>
<td align="right">
</td>
<td align="right">
<strong>5</strong>
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
</td>
</tr>
<tr>
<td align="left">
Diana
</td>
<td align="right">
</td>
<td align="right">
</td>
<td align="right">
5
</td>
<td align="right">
<strong>1</strong>
</td>
<td align="right">
</td>
<td align="right">
</td>
</tr>
<tr>
<td align="left">
Nick
</td>
<td align="right">
1
</td>
<td align="right">
</td>
<td align="right">
</td>
<td align="right">
</td>
<td align="right">
<strong>5</strong>
</td>
<td align="right">
</td>
</tr>
<tr>
<td align="left">
Reggie
</td>
<td align="right">
</td>
<td align="right">
</td>
<td align="right">
</td>
<td align="right">
</td>
<td align="right">
</td>
<td align="right">
<strong>6</strong>
</td>
</tr></tbody> </table>
<p>
Ok so lets have a closer look at the above.
</p>
<p>
Reading across the rows left to right these are the actual examples of each class &#8211; in this case there are 6 children with each name so if you sum over the row you will find that they each add up to 6.
</p>
<p>
Reading down the columns top-to-bottom you will find the predictions &#8211; i.e. what Grandma thought each child&#8217;s name was.  You will find that these columns may add up to more than or less than 6 because Grandma may overfit for one particular name. In this case she seems to think that all her female Grandchildren are called Eliza (she predicted 5/6 Elizas are called Eliza and 5/6 Dianas are also called Eliza).
</p>
<p>
Reading diagonally where I&#8217;ve shaded things in bold gives you the number of correctly predicted examples. In this case Reggie was 100% accurately predicted with 6/6 children called &#8220;Reggie&#8221; actually being predicted &#8220;Reggie&#8221;. Diana is the poorest performer with only 1/6 children being correctly identified. This can be explained as above with Grandma over-generalising and calling all female relatives &#8220;Eliza&#8221;.
</p>
<p>
<figure id="attachment_118" aria-describedby="caption-attachment-118" class="wp-caption alignright"><img loading="lazy" class="size-medium wp-image-118" src="https://i2.wp.com/brainsteam.co.uk/wp-content/uploads/2016/05/FEN-Ponytail-800px.png?resize=259%2C300&#038;ssl=1" alt="Steve sings for a Rush tribute band - his Geddy Lee is impeccable." width="259" height="300" srcset="https://i2.wp.com/brainsteam.co.uk/wp-content/uploads/2016/05/FEN-Ponytail-800px.png?resize=259%2C300&ssl=1 259w, https://i2.wp.com/brainsteam.co.uk/wp-content/uploads/2016/05/FEN-Ponytail-800px.png?w=690&ssl=1 690w" sizes="(max-width: 259px) 100vw, 259px" data-recalc-dims="1" /><figcaption id="caption-attachment-118" class="wp-caption-text">Steve sings for a Rush tribute band &#8211; his Geddy Lee is impeccable.</figcaption></figure>
</p>
<p>
Grandma seems to have gender nailed except in the case of one of the Steves (who in fairness does have a Pony Tail and can sing very high).  She is best at predicting Reggies and struggles with Brians (perhaps Brians have the most diverse appearance and look a lot like their respective male cousins). She is also pretty good at Nicks and Steves.
</p>
<p>
Grandma is terrible at female grandchildrens&#8217; names. If this was a machine learning problem we would need to find a way to make it easier to identify the difference between Dianas and Elizas through some kind of further feature extraction or weighting or through the gathering of additional training data.
</p>
<h2>
Conclusion
</h2>
<p>
Machine learning is definitely no walk in the park. There are a lot of intricacies involved in assessing the effectiveness of a classifier. Accuracy is a great start if until now you&#8217;ve been praying to the gods and carrying four-leaf-clovers around with you to improve your cognitive system performance.
</p>
<p>
However, Precision, Recall, F-Measure and Confusion Matrices really give you the insight you need into which classes your system is struggling with and which classes confuse it the most.
</p>
<h4>
A Note for Document Retrieval (Watson Retrieve & Rank) Users
</h4>
<p>
This example is probably directly relevant to those building classification systems (i.e. extracting intent from questions or revealing whether an image contains a particular company&#8217;s logo). However all of this stuff works directly for document retrieval use cases too. Consider true positive to be when the first document returned from the query is the correct answer and false negative is when the first document returned is the wrong answer.
</p>
<p>
There are also variants on this that consider the top 5 retrieved answer (Precision@N) that tell you whether your system can predict the correct answer in the top 1,3,5 or 10 answers by simply identifying &#8220;True Positive&#8221; as the document turning up in the top N answers returned by the query.
</p>
<h3>
Finally&#8230;
</h3>
<p>
Overall I hope this tutorial has helped you to understand the ins and outs of machine learning evaluation.
</p>
<p>
Next time we look at cross-validation techniques and how to assess small corpii where carving out a 30% chunk of the documents would seriously impact the learning. Stay tuned for more!
</p>
[1]: https://brainsteam.co.uk/2016/03/29/cognitive-quality-assurance-an-introduction/
[2]: https://upload.wikimedia.org/math/9/9/1/991d55cc29b4867c88c6c22d438265f9.png
[3]: https://en.wikipedia.org/wiki/Harmonic_mean#Harmonic_mean_of_two_numbers