When we get sick, we tend to think of the illness as bunch of random symptoms, but viruses don’t behave randomly. They attack the body’s systems in specific, mathematical patterns. To understand how COVID-19 manifests, data scientists use a technique called Market Basket Analysis, a technique used initially to figure what items are bought together. By analyzing thousands of these baskets, hidden connections in the virus’s behavior are brought to light.

Before running the Apriori algorithm, it is important to analyze the frequencies (Support) of individual symptoms. Fatigue was the dominant complaint, affecting nearly 42% of patients, closely followed by headaches (37%) and body aches (36%). On the other end of the spectrum, severe symptoms like shortness of breath only affected about 8% of individuals. But looking at symptoms in isolation only tells half the story. The real breakthrough comes when we ask which symptoms travel together

itemFrequencyPlot(covid_transactions, topN = 12, type = "relative", col = "darkgreen", main = "Top 10 Most Frequent Items")

Apriori Algorithm and Threshold

After running the Apriori algorithm with the chosen thresholds (supp = 0.05, conf = 0.5), I applied a strict criteria to find the most interesting rules: I looked for combinations that yielded a Lift greater than 2.0 or a Confidence greater than 70%.

Minimum Support = 0.05 (5%): If we set the support threshold too high (e.g., 15%), the algorithm will completely ignore highly specific indicator symptoms like Loss of smell/taste. If we set it too low (e.g., 1%), the model will be overwhelmed by rare, coincidental symptoms . 5% is the perfect balance that captures specific clinical combinations without generating spurious rules.

Minimum Confidence = 0.50 (50%): We only want to look at rules where the there is at least a 50/50 chance that the symptom is also present. This ensures clinical relevance.

inspect(head(rules_sorted, 7))
##     lhs                        rhs                   support confidence coverage     lift count
## [1] {loss_smell_taste,                                                                         
##      aching_body}           => {high_temp_or_chills}   0.056  0.6511628    0.086 2.429712    28
## [2] {loss_smell_taste,                                                                         
##      fatigue}               => {high_temp_or_chills}   0.066  0.6000000    0.110 2.238806    33
## [3] {new_continuous_cough,                                                                     
##      loss_smell_taste}      => {high_temp_or_chills}   0.050  0.5681818    0.088 2.120081    25
## [4] {fatigue,                                                                                  
##      aching_body,                                                                              
##      headache}              => {high_temp_or_chills}   0.056  0.5600000    0.100 2.089552    28
## [5] {loss_smell_taste}      => {high_temp_or_chills}   0.092  0.5542169    0.166 2.067973    46
## [6] {new_continuous_cough,                                                                     
##      fatigue,                                                                                  
##      headache}              => {high_temp_or_chills}   0.054  0.5400000    0.100 2.014925    27
## [7] {fatigue,                                                                                  
##      aching_body}           => {high_temp_or_chills}   0.098  0.5384615    0.182 2.009185    49

Association Rules

Here are the two most interesting rules discovered.

Rule 1: {Loss of smell/taste, Aching body} \(\Rightarrow\) {High temp or chills}

Support (5.6%): 5.6% of all patients in the entire dataset experienced all three of these symptoms together.

Confidence (65.1%): If a patient reports a loss of smell/taste and an aching body, there is a 65.1% probability they also have a high temperature or chills.

Lift (2.43): This is the key metric. A lift of 2.43 means that a patient with smell loss and body aches is 2.43 times more likely to have a fever compared to the average patient. This indicates a deeply interconnected viral cluster rather than a coincidence.

Rule 2: {Fatigue, Aching body} \(\Rightarrow\) {High temp or chills}

Support (9.8%): A very solid 9.8% of the dataset shows this exact trio of symptoms, making it a highly prevalent pattern.

Confidence (53.8%): If a patient is experiencing both fatigue and an aching body, there is a greater than 50% chance they are also running a fever.

Lift (2.01): A lift of 2.01 means that a patient with fatigue and body aches is twice as likely to have a high temperature compared to a random patient in the baseline population.

Graph-Based Visualization

This graph-based visualization is often easier for people to understand quickly how one symptom leads to another:

The text labels are the individual symptoms

The arrows pointing into the dot are the antecedents

The arrows pointing out of a dot are the consequents

The dots themselves represent the actual rules. 10 dots in the graph indicate 10 different rules.

For example:”Loss of smell/taste” and Aching body with arrows pointing into a dark, medium-sized dot. From that dot, an arrow points out to High temp or chills. We would read this as: “When a patient has a loss of smell/taste and an aching body, they are highly likely to also have a high temperature. This is a moderately common pattern (medium dot) and the connection is extremely strong (dark color).”

plot(head(rules_sorted, 10), method = "graph")

Conclusion: Why this matters?

Why do these mathematical rules matter outside of a spreadsheet? Because in the real world, predictive data saves time and resources.

If medical professionals know these exact statistical connections they can predict patient deterioration before it happens. If a patient goes to emergency complaining of no taste and body aches, the professionals know a fever is highly probable and can advise the patient accordingly, staying one step ahead of the virus.