[PYTHON] If the accuracy of the PCR test is poor, why not repeat the test?

Introduction

Qiita also has some posts on the reliability of PCR testing for coronavirus.

I think all of these are correct, but in reality they are inspected multiple times. Then it doesn't matter if the PCR test isn't very sensitive or the specificity isn't perfect, isn't it? How much better can you get by testing multiple times? I had a question, so I looked it up.

Definition of terms again

The sensitivity and specificity of a test are often shown in papers.

On the other hand, it is important to discuss whether it is better or worse to perform a PCR test with COVID-19. When the test result is positive, it is the probability of actually having the virus ** positive precision ** [^ 1], The probability that the test result is not actually infected with the virus when the student is a graduate student ** Negative precision **.

[^ 1]: It is not "positive / predictive rate" but "positive / predictive rate".

As we will see, these values vary greatly depending on the prior probability.

If you write this like a contingency table, it will be as follows [^ 4].

true state
Affected Unaffected
Inspection
Inspection
Conclusion
Result
Positive $$ \begin{matrix} \ text {true positive} \\ \text{(true positive)} \\ \end{matrix} = a $$ $$ \begin{matrix} \ text {false positive} \\ \text{(false positive)} \\ \end{matrix} = b $$ $$ \begin{matrix} \ text {Positive predictive value} \\ \text{(positive precision)} \\ \end{matrix} = \frac{a}{a+b} $$
Negative $$ \begin{matrix} \ text {false negative} \\ \text{(false negative)} \\ \end{matrix} = c $$ $$ \begin{matrix} \ text {true negative} \\ \text{(true negative)} \\ \end{matrix} = d $$ $$ \begin{matrix} \ text {negative predictive value} \\ \text{(negative precision)} \\ \end{matrix} = \frac{d}{c+d} $$
$$ \begin{matrix} \ text {sensitivity} \\ \text{(sensitivity)} \\ \end{matrix} = \frac{a}{a+c} $$ $$ \begin{matrix} \ text {specificity} \\ \text{(specificity)} \\ \end{matrix} = \frac{d}{b+d} $$

[^ 4]: I can't qualify the table well. It's difficult for an amateur to change with Markdown.

Positive predictive value, negative predictive value

Sensitivity = $ \ frac {a} {a + c} $ and specificity = $ \ frac {d} {b + d} $ and prior probability = $ \ frac {a + Suppose you are given c} {a + b + c + d} $. Putting the total number of samples $ a + b + c + d = 1 $ and finding the positive predictive value and negative predictive value,

\text{positive precision} = \frac{ \text{sensitivity} \cdot \text{prior probability} }{ \text{sensitivity} \cdot \text{prior probability} + (1 - \text{specificity}) * (1 - \text{prior probability}) }
\text{negative precision} = \frac{ \text{specificity} \cdot (1 - \text{prior probability}) }{ (1 - \text{sensitivity}) \cdot \text{prior probability} + \text{specificity} \cdot (1 - \text{prior probability}) }

It becomes [^ 3].

[^ 3]: Why? This article , You just have to solve the simultaneous equations.

After that, this article Let's assume $ and calculate.

import matplotlib.pyplot as plt
import numpy as np

sensitivity = 0.70  #Sensitivity of one test. The probability that the test will be positive when you are affected.
specificity = 0.95  #Specificity of one test. The probability that the test will be negative when not affected.

def positive_precision(prior_probability, sensitivity, specificity):
    '''
    Args:
        prior_probability:Prior probability. Probability of being affected when there are no prerequisites.
        sensitivity:sensitivity. Probability of being positive when testing affected patients.
        specificity:Specificity. Probability of being negative when testing unaffected patients.
    Returns:
        positive_precision:Positive predictive value. Probability of actually being affected when the test result is positive.
    '''
    return sensitivity * prior_probability / (sensitivity * prior_probability + (1 - specificity) * (1 - prior_probability))

def negative_precision(prior_probability, sensitivity, specificity):
    '''
    Args:
        prior_probability:Prior probability. Probability of being affected when there are no prerequisites.
        sensitivity:sensitivity. Probability of being positive when testing affected patients.
        specificity:Specificity. Probability of being negative when testing unaffected patients.
    Returns:
        negative_precision:Negative predictive value. The probability that you are not actually affected when the test result is negative.
    '''
    return specificity * (1 - prior_probability) / ((1 - sensitivity) * prior_probability + specificity * (1 - prior_probability))

Here, the functions positive_precision () and negative_precision (), as the name implies, obtain the positive predictive value and the negative predictive value, respectively, from the prior probabilities, sensitivities, and specificities given by the arguments.

If you test n times and all n times are negative, you think it is negative

In other words, let's consider a case based on a pessimistic way of thinking that if you test several times and get a positive result even once, you will be positive. Let's plot the prior probability and the number of checks $ n $ on the graph.

def sensitivity_pessimistic(sensitivity, n):
    '''
    Args:
        sensitivity:Sensitivity of one test
        n:Number of inspections
    Returns:
Sensitivity of n times inspection:Sensitivity of test to be considered negative if all are negative after n tests
    '''
    return 1 - (1 - sensitivity) ** n

def specificity_pessimistic(specificity, n):
    '''
    Args:
        specificity:Specificity of one test
        n:Number of inspections
    Returns:
Specificity of n tests:Specificity of the test is considered negative if all are negative after n tests
    '''
    return specificity ** n

xs = [ np.exp(-0.05 * i) for i in range(0, 200)]
ys_list = []
legend_list = []
for n in [1, 3, 5]:
    ys_list.append([ positive_precision(x, sensitivity_pessimistic(sensitivity, n), specificity_pessimistic(specificity, n)) for x in xs ])
    legend_list.append('Inspection{}Positive predictive value at the time of implementation'.format(n))
for n in [1, 3, 5]:
    ys_list.append([ negative_precision(x, sensitivity_pessimistic(sensitivity, n), specificity_pessimistic(specificity, n)) for x in xs ])
    legend_list.append('Inspection{}Negative predictive value at the time of implementation'.format(n))
    
fig, ax = plt.subplots()
plt.xscale('log')

for ys in ys_list:
    ax.plot(xs, ys)
ax.legend(legend_list)
ax.set_xlabel('Prior probability of illness')
ax.set_title('Accuracy of multiple PCR tests(Negative if all negative after n tests)')
plt.show()

fig1.png

This pessimistic idea that "if you get a positive result even once, you are sick" may be close to the current way of thinking in society. This may seem good because it's on the safe side, but when the prior probabilities are low, it can end up treating a large number of people who aren't actually affected as affected. Hospitals and quarantine facilities can be flat and difficult.

For example, as of today (April 18, 2020), the number of confirmed infected people in Japan [^ 2] is more than 9,000, but there are 100,000 ($ 10 ^ 5) $ true infected people, which is 10 times this number. Suppose you are. Assuming that Japan's total population is 100 million ($ 10 ^ 8 ), the prior probabilities of randomly selected people are $ \ text {prior probability} = \ frac {true number of infected people} {total population} = \ frac {10 ^ 5} {10 ^ 8} = 10 ^ {-3} $$ And, as you can see from the graph above where the horizontal axis is $ 10 ^ {-3} $, it is no exaggeration to say that there is no point in inspecting the person who chose it as a crap. Is it too much to say?

[^ 2]: I don't know the definition, but it is the number announced by the local government, and it is probably the number of people who have ** positive ** even once in the PCR test.

In the case of a test that is considered positive if it is tested n times and all n times are positive

Next, what if you take a very optimistic way of thinking, shaking it in the opposite direction and thinking that if you get a negative even once, you think it is negative. Let's plot the graph by changing the prior probability and the number of inspections $ n $.

def sensitivity_optimistic(sensitivity, n):
    '''
    Args:
        sensitivity:Sensitivity of one test
        n:Number of inspections
    Returns:
Sensitivity of n times inspection:Sensitivity of a test that is considered positive when it is tested n times and all are positive n times
    '''
    return sensitivity ** n

def specificity_optimistic(specificity, n):
    '''
    Args:
        specificity:Specificity of one test
        n:Number of inspections
    Returns:
Specificity of n tests:Specificity of the test considered to be positive when it is tested n times and all are positive n times
    '''
    return 1 - (1 - specificity) ** n

xs = [ np.exp(-0.05 * i) for i in range(0, 200)]
ys_list = []
legend_list = []
for n in [1, 3, 5]:
    ys_list.append([ positive_precision(x, sensitivity_optimistic(sensitivity, n), specificity_optimistic(specificity, n)) for x in xs ])
    legend_list.append('Inspection{}Positive predictive value at the time of implementation'.format(n))
for n in [1, 3, 5]:
    ys_list.append([ negative_precision(x, sensitivity_optimistic(sensitivity, n), specificity_optimistic(specificity, n)) for x in xs ])
    legend_list.append('Inspection{}Negative predictive value at the time of implementation'.format(n))
    
fig, ax = plt.subplots()
plt.xscale('log')

for ys in ys_list:
    ax.plot(xs, ys)
ax.legend(legend_list)
ax.set_xlabel('Prior probability of illness')
ax.set_title('Accuracy of multiple PCR tests(Tested n times and positive if all are positive)')
plt.show()

fig2.png

In this way, by testing multiple times, we were able to greatly increase the probability of being positive, even if the prior probability is very low.

Needless to say, if you have a high fever or pneumonia, it makes a lot of sense to test because you have a higher chance of having COVID-19. .. This is because the positive rate and the negative rate are high regardless of which of the above two graphs is taken.

Summary

People who test positive for PCR even once are likely to be treated as infected, but I think that ordinary people are not immediately convicted because the prior probability is not so high. I will. In the actual clinical setting, it is likely that people who look at other symptoms (pneumonia, taste and smell abnormalities, etc.) to be tested (= people with a sufficiently high prior probability) are selected for testing.

Also, when you are discharged from the hospital, it seems that you are properly performing PCR tests multiple times, and if you are negative twice in a row, you are discharged.

I don't know.

I put the jupyter notebook on github. I'm sorry if I made a mistake.

Recommended Posts

If the accuracy of the PCR test is poor, why not repeat the test?
The update of conda is not finished.
FAQ: Why is the comparison of numbers inconsistent?
The value of pyTorch torch.var () is not distributed
What to do if the progress bar is not displayed in tqdm of python
Why is the first argument of [Python] Class self?
[Golang] "package exec is not in GOROOT" when executing the test
Test the version of the argparse module
Is the probability of precipitation correct?
Determine if the string is formatable
Determine if the library is installed.
Science "Is Saito the representative of Saito?"
Why is cross entropy used for the objective function of the classification problem?
I think the limit of knapsack is not the weight but the volume w_11/22update