From Correlation to Causation through stories and math

Image
Correlation and causation are two concepts that people often mixup in their minds. I must admit that I myself have been guilty about this, and it unlikely that I would ever entirely grow out of it as it is wired deeply into our psychology. Let me use this article to briefly emphasise what the concepts of correlation and causation means, some interesting stories that have emerged from people misunderstanding these concepts and an algorithm that attempts to find causal relationship using correlation information. Here is a story that I heard a professor of mine, Prof. Dr. Ernst-Jan Camiel Wit, tell us during a lecture. There was a school that was involved in a study to see if providing free mid-day meals to students, which they could choose to be subscribed to this or not. At the end of the study, both the students who subscribed to it and did not where tested for different health indicators. It was observed that the students who chose to have meals from the programme had poorer health

COVID-19 Disease Spreading Simulation

At the moment, the world is fighting COVID-19. There have been many scientists who made simulations to demonstrate how the disease would spread. There was one simulation which I liked. It was a video in which people were put up as a dot that moved around the canvas. I want to reproduce that in JavaScript and make it tunable.




 View this in a new tab: Click Here


First, let us create a canvas div, in which all the people would exist. I am feeling a bit lazy to create a separate stylesheet. I will keep all the styles within the HTML Tags.

<div id="canvas" style="position: absolute; width: 500px; height: 500px; background: #efefef"></div>
Next, let us define a class named Person. The person starts at a random coordinate and moves in a random direction.

const maxVel = 5;
class Person{
    constructor(){
        this.div = document.createElement("div");
        this.div.style.width = "4px";
        this.div.style.height = "4px";
        this.div.style.borderRadius = "50%";
        this.div.style.background = "#000000";
        this.div.style.position = "absolute";
     
        // Init position
        this.div.style.left = Math.random() * 500;
        this.div.style.top = Math.random() * 500;
     
        // Init velocity
        this.Velx = Math.random() * maxVel;
        this.Vely = Math.random() * maxVel;
     
        document.getElementById("canvas").appendChild(this.div);
     
        this.updatePosition(this);
    }
 
    updatePosition(that){
        setInterval(function(){
            that.div.style.left = that.div.offsetLeft + that.Velx;
            that.div.style.top = that.div.offsetTop + that.Vely;
         
            if((that.div.offsetLeft >= 500 && that.Velx > 0) || (that.div.offsetLeft <= 0 && that.Velx < 0))
                that.Velx = - that.Velx;
            if((that.div.offsetTop >= 500 && that.Vely > 0) || (that.div.offsetTop <= 0 && that.Vely < 0))
                that.Vely = - that.Vely;
        },50);
    }
}
Now, if we can simply create a few objects of the class Person and watch the animation.
for(var i = 0; i < 20; i++){
    new Person();
}



Now, let's bring in the disease factor. Let us make the following assumptions:
  • If a healthy person comes close to a sick person by a certain distance, the healthy person gets infected.
  • The person has a small probability of dying at every time step.
  • After a certain amount of time, the sick person gets cured.
  • Once cured, the person shall no longer get sick ever again as the person gained immunity.
I went ahead with implementing it. It would be hard to explain everything step by step, but just have a look at the final code.

The following is the final HTML part:
<div id="canvas" style="position: absolute; width: 500px; height: 500px; background: #efefef; z-index: 900"></div>
<div style="position:absolute;z-index: 999;">
    <div id="numHealthy" style="display:block;"></div>
    <div id="numSick" style="display:block;"></div>
    <div id="numCured" style="display:block;"></div>
    <div id="numDead" style="display:block;"></div>
</div>
And the JavaScript Part:
const numInitHealthyPeople = 30;
const numInitSickPeople = 2;
const maxVel = 5;
const curePeriod = 50;
const killProbability = 0.005;
const spreadRadius = 20;
const divHealthy = document.getElementById("numHealthy");
const divSick = document.getElementById("numSick");
const divCured = document.getElementById("numCured");
const divDead = document.getElementById("numDead");
class Person{
    static allPersons = [];
    constructor(isSick = false){
        this.div = document.createElement("div");
        this.div.style.width = "4px";
        this.div.style.height = "4px";
        this.div.style.borderRadius = "50%";
        this.div.style.background = "#000000";
        this.div.style.position = "absolute";
     
        // Init position
        this.div.style.left = Math.random() * 500;
        this.div.style.top = Math.random() * 500;
     
        // Init velocity
        this.Velx = Math.random() * maxVel;
        this.Vely = Math.random() * maxVel;
     
        document.getElementById("canvas").appendChild(this.div);
     
        if(isSick){
            this.getSick(this);
        }
        this.sickDuration = 0;
        this.isCured = false;
        this.isDead = false;
     
        this.update(this);
     
        Person.allPersons.push(this);
    }
 
    update(that){
        var updateVar = setInterval(function(){
            // Position and Velocity:
            that.div.style.left = that.div.offsetLeft + that.Velx;
            that.div.style.top = that.div.offsetTop + that.Vely;
         
            if((that.div.offsetLeft >= 500 && that.Velx > 0) || (that.div.offsetLeft <= 0 && that.Velx < 0))
                that.Velx = - that.Velx;
            if((that.div.offsetTop >= 500 && that.Vely > 0) || (that.div.offsetTop <= 0 && that.Vely < 0))
                that.Vely = - that.Vely;
         
            // Receive disease if sick people nearby
            if(!(that.isCured || that.isSick)){
                for(var i = 0; i < Person.allPersons.length; i++){
                    var person2 = Person.allPersons[i];
                    // if person is nearby
                    if(person2.isSick){
                        var dist = Math.sqrt(Math.pow(that.div.offsetLeft - person2.div.offsetLeft, 2) + Math.pow(that.div.offsetTop - person2.div.offsetTop, 2));
                        if(dist < spreadRadius){
                            that.getSick(that);
                            break;
                        }
                    }
                }
            }
         
            // Sickness
            if(that.isSick){
                that.sickDuration++;
                if(that.sickDuration > curePeriod){
                    that.getCured(that);
                } else {
                    // Kill with probability:
                    if(Math.random() < killProbability){
                        that.kill(that);
                        clearInterval(updateVar);
                    }
                }
            }
            // Statistics Display:
            divHealthy.innerText = "Healthy: " + numHealthyPeople;
            divSick.innerText = "Sick: " + numSickPeople;
            divCured.innerText = "Cured: " + numCuredPeople;
            divDead.innerText = "Dead: " + numDeadPeople;
         
        },100);
    }
 
    getCured(that){
        that.isSick = false;
        that.isCured = true;
        that.div.style.background = "#00ff00";
        numCuredPeople++;
        numSickPeople--;
    }
 
    getSick(that){
        that.isSick = true;
        that.div.style.background = "#ff0000";
        numSickPeople++;
        numHealthyPeople--;
    }
 
    kill(that){
        that.div.parentElement.removeChild(that.div);
        that.isDead = true;
        numDeadPeople++;
        numSickPeople--;
    }
}
var numHealthyPeople = numInitHealthyPeople + numInitSickPeople;
var numSickPeople = 0; // get sick is called in the constructor
var numCuredPeople = 0;
var numDeadPeople = 0;
for(var i = 0; i < numInitHealthyPeople; i++){
    new Person();
}
for(var i = 0; i < numInitSickPeople; i++){
    new Person(true);
}
You can open up this code in GitHub using the following link:

https://github.com/zenineasa/DiseaseSpreadSimulator

Comments

Popular posts from this blog

Started a blog under HexHoot

Bought a new domain - chickfort.com

First impression of Lugano - Mindblowing