Advertisement
Guest User

Untitled

a guest
Apr 4th, 2020
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.32 KB | None | 0 0
  1. # covid-estimates.py Given a set of points, uses several functions to estaimate
  2. # the progression of the virus.  From the CSV, we can generate P0 (Base value of
  3. # logistic curve) r (Growth rate)
  4.  
  5.  
  6. # We need some form of estimate of how far we are, so this program uses a binary
  7. # search to find the least-norm estimat
  8.  
  9. # The "estiamte" in this case is a ratio between 0 and 1, with 1 being
  10. # "asymptotic number of cases" (K in the logistic function)
  11.  
  12. import pandas # Read in CSV.
  13. import numpy as np
  14. import matplotlib.pyplot as plt
  15. import math
  16.  
  17. def get_growth_rate(data):
  18.     # get latest and earliest data
  19.     ind_first = 0
  20.     ind_last = len(data) - 1
  21.  
  22.     n_days = (ind_last - ind_first)
  23.     ratio = (data.loc[ind_last, "nCases"]) / (data.loc[ind_first, "nCases"])
  24.  
  25.     # Prone to numerical roundoff error. Possible improvement would be to use
  26.     # the last ten days.
  27.     return pow(ratio, 1/n_days)
  28.  
  29. def get_init_population(data):
  30.     return data.loc[0, "nCases"]
  31.  
  32. def logistic(P0, r, K, t):
  33.     return (K) / (1 + ((K - P0)/ P0) * math.pow(math.e, -1 * r * (t)))
  34.  
  35. # Generates a time-series of a logistic growth for n_days.
  36. # First, it solves for K, the carrying capacity, and it subsequently
  37. # plugs it into the logistic equation given the growth rate r, initial
  38. # population.
  39. def generate_logistic_fn(P0, r, progression_rate, latest_nCases, n_days):
  40.     K = latest_nCases / progression_rate
  41.     return np.asarray(list(map(lambda t: logistic(P0, r, K, t),
  42.                                range(n_days))))
  43.  
  44. # Assumes data and approximation are both np arrays
  45. def get_error(data, approximation):
  46.     return np.linalg.norm( data - approximation )
  47.  
  48. # Iterate until you get a low norm.
  49. def approximate_progression_ratio(data, P0, r, n_days, latest):
  50.     end = 1.0
  51.     start = 0.0
  52.     midpt = (start + end / 2)
  53.     error = get_error(
  54.         data, generate_logistic_fn(P0, r, midpt, latest, n_days)
  55.     )
  56.     # Go for 10 iterations.
  57.     for i in range(10):
  58.         midpt = (start + end) / 2
  59.         left = (start + midpt) /2
  60.         right = (end + midpt) / 2
  61.  
  62.         # Check against left and right. See which one has the lower error
  63.         left_err = get_error(
  64.             data, generate_logistic_fn(P0, r, left, latest, n_days)
  65.         )
  66.         right_err = get_error(
  67.             data, generate_logistic_fn(P0, r, right, latest, n_days)
  68.         )
  69.         print(f"Left Error: {left_err}")
  70.         if(left_err < right_err):
  71.             end = midpt
  72.             error = left_err
  73.         else:
  74.             start = midpt
  75.             error = right_err
  76.  
  77.         print(generate_logistic_fn(P0, r, left, latest, n_days))
  78.         print(f"Error: {error}")
  79.         print(f"Start, End: ({start}, {end})")
  80.    
  81.     return (start + end) / 2
  82.        
  83.    
  84. data = pandas.read_csv("./COVID19-Data-Apr04.csv")
  85. growth_rate = math.log(get_growth_rate(data) )
  86. P0 = get_init_population(data)
  87.  
  88. cases = data["nCases"].to_numpy()
  89. latest = cases[len(cases) - 1]
  90. n_days = len(cases)
  91.  
  92. approximate_progression = approximate_progression_ratio(cases, P0, growth_rate, n_days, latest)
  93.  
  94. print(generate_logistic_fn(P0, growth_rate, approximate_progression, latest,n_days))
  95. approx_1 = generate_logistic_fn(P0, growth_rate, approximate_progression, latest,n_days *4)
  96. plt.plot(approx_1)
  97. plt.scatter(range(n_days), cases)
  98. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement