COVID-19 Policy Prescriptions

Format: Jupyter notebook / written report.

Overview

In this homework, you will train a COVID-19 policy prescriptor using NEAT. The prescriptor generates a plan that defines which policies will be in effect over a period of time. The plan is evaluated on two criteria: (1) the predicted number of cases given the interventions prescribed and (2) the stringency of the interventions.

Success is about balance between stringency and cases. Your model will output a number of different proposals, which ideally habitate different regions on the Pareto frontier. A policy plan is better than another if it has the same or fewer predicted cases and is either the same or less stringent.

In this homework, you will use one that has been pretrained. The file examples/lstm/trained_model.h5 represents an LSTM predictor model. It can be invoked by predict.py, as you will see in the example. It can also be instantiated directly.

Steps

1. Download the code and dependencies

Download the code and switch to the assignment branch

The code is available on GitHub. The original repository is here, though a fork has been updated to work with the latest data here. You may download it with the following commands:
git clone https://github.com/SainaRez/covid-xprize-cs378ne.git
cd covid-xprize-cs378ne

Install the dependencies

conda create --name cs378ne_hw5 python=3.10.4
conda activate cs378ne_hw5
pip install -r requirements.txt

Set up the environment

In your working directory run the following to point your PYTHONPATH to the application code:
export PYTHONPATH=$PYTHONPATH:`pwd`

Now checkout the assignment branch
git checkout prescriptor-assignment

Also, copy the sample LSTM model into the appropriate directory:
mkdir -p examples/predictors/lstm/models && cp examples/predictors/lstm/tests/fixtures/trained_model_weights_for_tests.h5 examples/predictors/lstm/models/trained_model_weights.h5

2. Read the example

Change into the example code directory:
cd examples/prescriptors/neat/

Then, read the file train_prescriptor.py. It contains a sample model and training procedure using NEAT. You will need to run it to train and save the sample prescriptor model.

Try running the code with the following command:
python train_prescriptor.py

Examine the code to understand:

There is another file located prescribe.py. You can evaluate it with the following sample command:
python3 prescribe.py --start_date 2020-08-01 --end_date 2020-08-05 -ip none.txt -o test_prescriptions.csv

Read prescribe.py to understand how the output of the prescriptor model is formatted as a CSV file. Several prescriptors indexed by PrescriptionIndex are saved to the output CSV file, and in this example, they correspond to the model checkpoints saved at intervals throughout training. You may reuse this code in the next steps.

3. Change fitness for training into weighted sum formulation

We have a multi-goal problem setting that we need to consider both making daily cases small and making policy not too stringent. One simple approach is to combine two goals into one single objective function by using weighted sum and setting different weights for these two goals.

Your job is to implement weighted sum fitness function and play with different weight coefficient settings in train_prescriptor.py. A simple starting point is to use two constants, i.e. on multiplying the number of cases objectve and the other the stringency objective. Train on different coefficients to generate multiple proposals (you can just revise file train_prescriptor.py for simplicity). Save the model checkpoint file which will be used to generate the CSV files. You need to run the file prescribe.py to generate CSV file, but be sure to make model checkpoint file path consistent. You need to generate 10 different proposed prescriptors, e.g. 10, each with different coefficients. Then generate the the corresponding NPI schedules (CSV file) for later evaluation.

4. (Optional and bonus)

To follow up, you can also design other forms of the weights and fitness functions. Just try and play with it. Even more advanced, there are a few ways to optimize in a multi-objective setting, such as NSGA2 or MOEA/D. You are free to set the fitness function as multi-objective functions and play with it. Really good answer will get 10 more points.

5. Evaluate and visualize different prescriptors

The file prescriptor_robojudge.ipynb contains evaluation routines. Point an element of the prescription_files dictionary to the output CSV file of your prescription model. If you have completed the above steps, you should see an L-shaped curve representing the Pareto frontier. To get better grades, you should try to come up with sets of coefficients so that the L-shaped curve is as close to the axes and the origin, as possible, that is, such that the solutions minimize the tradeoffs between cases and stringency as well as possible. You may compare different results using this method (in case that you do step 4).

Report

Include the following sections in a separate written report.

Methods

Write up how you train with NEAT under diffferent weight settings. Be sure to answer the following questions:

Results

Include the plot of stringency vs. cases available at the bottom of prescriptor_robojudge.ipynb.