Implementing logistic growth model with python

Posted by Akenatehm on Fri, 11 Feb 2022 02:38:51 +0100

1 logistic growth model

1.1 J-type growth and S-type growth

Exponential growth, J-shaped curve: exponential growth, that is, the growth is not restrained and explosive.

For example, one person can infect three people, three people can infect nine people, and nine people can infect 27 people, which keeps doubling. This is J-type growth, also known as exponential growth.

Some infectious diseases may show exponential growth in the initial stage.

However, in the actual growth process, the growth rate cannot be maintained all the time. With the increasing number of people, the growth rate will be gradually restrained. This is S-type growth.

The spread of general diseases is an S-type growth process, because there will be some resistance in the process of disease transmission.

1.2 logistic growth function

When a species moves into a new ecosystem, its number will change. Assuming that the initial number of the species is less than the maximum capacity of the environment, the number will increase. If the species has natural enemies, food, space and other resources in this ecosystem and is also insufficient (non ideal environment), the growth function meets the logistic equation, and the image is S-shaped. This equation is the best mathematical model to describe the law of population growth under the condition of limited resources. In the following contents, the principle, ecological significance and application of logistic equation will be introduced in detail. The differential formula of logistic model is: dx/dt=rx(1-x), in which r is the rate parameter.

  • K is the environmental capacity, that is, the limit that P(t) can reach when it grows to the end.
  • P0 is the initial capacity, which is the number at t=0.
  • r is the growth rate. The larger r is, the faster it will grow and approach the value of K. The smaller r is, the slower it will grow and approach the value of K.
    The formula is written in python in the form of function:
def logistic_increase_function(t,K,P0,r):
    # t:time   t0:initial time    P0:initial_value    K:capacity  r:increase_rate
    exp_value=np.exp(r*(t-t0))
    return (K*exp_value*P0)/(K+(exp_value-1)*P0)

The curve of logistic growth is also called s-shaped curve. The figure below shows the number of curves on the left and the growth rate on the right.

1.3 case code



#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
Fitting 2019-nCov Number of confirmed pneumonia infections
"""
import numpy as np
import matplotlib.pyplot as plt
import math
import pandas as pd
 
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def logistic_increase_function(t,K,P0,r):
    '''
    t ,list,Date series,[11,18,19,20 ,21, 22, 23, 24,  25,  26,  27]
    t0,int,Date first day
    r,float,r Is the growth rate, r The larger, the faster the growth, the faster the approach K value - Steeper;r The smaller, the slower the growth, the slower the approach K Value.
    P0 Is the initial capacity, which is t=0 Number of moments
    K,float,K Is the environmental capacity, that is, to grow to the end, P(t)The limit that can be reached,Generally 1
    
    '''
    t0=11  # first day
    r=0.6
    #   r = 0.55
    # t:time   t0:initial time    P0:initial_value    K:capacity  r:increase_rate
    exp_value=np.exp(r*(t-t0))
    return (K*exp_value*P0)/(K+(exp_value-1)*P0)
 
'''
1.11 41 cases per day
1.18 45 cases per day
1.19 62 cases per day
1.20 291 cases per day
1.21 440 cases per day
1.22 571 cases per day
1.23 830 cases per day
1.24 1287 cases per day
1.25 1975 cases in Japan
1.26 2744 cases per day
1.27 4515 cases per day
'''

#  Date and number of infected persons
t=[11,18,19,20 ,21, 22, 23, 24,  25,  26,  27]
t=np.array(t)
P=[41,45,62,291,440,571,830,1287,1975,2744,4515]
P=np.array(P)
 
# Estimation and fitting by least square method
popt, pcov = curve_fit(logistic_increase_function, t, P)
# popt - K,P0,r
# Finally, K=4.01665705e+10 people will be infected
# array([7.86278276e+03, 2.96673434e-01, 1.00000000e+00])

#Get the fitting coefficient in popt
print("K:capacity  P0:initial_value   r:increase_rate   t:time")
print(popt)


#Predicted P value after fitting
P_predict = logistic_increase_function(t,popt[0],popt[1],popt[2])


#Future forecast
future=[11,18,19,20 ,21, 22, 23, 24,  25,  26,  27,28,29,30,31,41,51,61,71,81,91,101]
future=np.array(future)
future_predict=logistic_increase_function(future,popt[0],popt[1],popt[2])


#Recent situation forecast
tomorrow=[28,29,30,32,33,35,37,40]
tomorrow=np.array(tomorrow)
tomorrow_predict=logistic_increase_function(tomorrow,popt[0],popt[1],popt[2])
 
#mapping
plot1 = plt.plot(t, P, 's',label="confimed infected people number")
plot2 = plt.plot(t, P_predict, 'r',label='predict infected people number')
plot3 = plt.plot(tomorrow, tomorrow_predict, 's',label='predict infected people number')
plt.xlabel('time')
plt.ylabel('confimed infected people number')
 
plt.legend(loc=0) #Specify the lower right corner of the position of legend
 
print(logistic_increase_function(np.array(28),popt[0],popt[1],popt[2]))
print(logistic_increase_function(np.array(29),popt[0],popt[1],popt[2]))
plt.show()
 
 
#Future forecast mapping
#plot2 = plt.plot(t, P_predict, 'r',label='polyfit values')
#plot3 = plt.plot(future, future_predict, 'r',label='polyfit values')
#plt.show()
 
 
print("Program done!")


'''
# Fitting age
'''
import numpy as np
import matplotlib.pyplot as plt

#Define x and y scatter coordinates
x = [10,20,30,40,50,60,70,80]
x = np.array(x)
print('x is :\n',x)
num = [174,236,305,334,349,351,342,323]
y = np.array(num)
print('y is :\n',y)
#Fitting with cubic polynomial
f1 = np.polyfit(x, y, 3)
print('f1 is :\n',f1)

p1 = np.poly1d(f1)
print('p1 is :\n',p1)

#You can also use yvals = NP polyval(f1, x)

yvals = p1(x)
print('yvals is :\n',yvals)


#mapping
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc=4) #Specify the position of the lower right corner of the legend
plt.title('polyfitting')
plt.show()



The least square method is used for fitting, and the least square method is used to fit the logistic growth function.

logistic_ increase_ The value of r in function (T, K, P0, r) can be adjusted:
After human intervention, the disease reduces the K value, so the r value can be increased to speed up the speed of reaching the K value
(r becomes larger and the curve becomes steeper)

r = 0.55

r=0.65

2 fitting polynomial function

reference resources: Three schemes of quasi merging arbitrary data and curves to obtain function expression in python.

2.1 polynomial fitting - polyfit fitting age

import numpy as np
import matplotlib.pyplot as plt
 
#Define x and y scatter coordinates
x = [10,20,30,40,50,60,70,80]
x = np.array(x)
print('x is :\n',x)
num = [174,236,305,334,349,351,342,323]
y = np.array(num)
print('y is :\n',y)
#Fitting with cubic polynomial
f1 = np.polyfit(x, y, 3)
print('f1 is :\n',f1)
 
p1 = np.poly1d(f1)
print('p1 is :\n',p1)
 
#You can also use yvals = NP polyval(f1, x)
yvals = p1(x)  #Fitting y value
print('yvals is :\n',yvals)
#mapping
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc=4) #Specify the lower right corner of the position of legend
plt.title('polyfitting')
plt.show()

2.2 polynomial fitting - curve_fit polynomial

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
 
#Custom function e exponential form
def func(x, a, b,c):
    return a*np.sqrt(x)*(b*np.square(x)+c)
 
#Define x and y scatter coordinates
x = [20,30,40,50,60,70]
x = np.array(x)
num = [453,482,503,508,498,479]
y = np.array(num)
 
#Nonlinear least square fitting
popt, pcov = curve_fit(func, x, y)
#Get the fitting coefficient in popt
print(popt)
a = popt[0] 
b = popt[1]
c = popt[2]
yvals = func(x,a,b,c) #y value fitting
print('popt:', popt)
print('coefficient a:', a)
print('coefficient b:', b)
print('coefficient c:', c)
print('coefficient pcov:', pcov)
print('coefficient yvals:', yvals)
#mapping
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc=4) #Specify the lower right corner of the position of legend
plt.title('curve_fit')
plt.show()

2.3 curve_fit fitting Gaussian distribution

#encoding=utf-8  
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import pandas as pd

#Custom function e exponential form
def func(x, a,u, sig):
    return  a*(np.exp(-(x - u) ** 2 /(2* sig **2))/(math.sqrt(2*math.pi)*sig))*(431+(4750/x))


#Define x and y scatter coordinates
x = [40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135]
x=np.array(x)
# x = np.array(range(20))
print('x is :\n',x)
num = [536,529,522,516,511,506,502,498,494,490,487,484,481,478,475,472,470,467,465,463]
y = np.array(num)
print('y is :\n',y)

popt, pcov = curve_fit(func, x, y,p0=[3.1,4.2,3.3])
#Get the fitting coefficient in popt
a = popt[0]
u = popt[1]
sig = popt[2]


yvals = func(x,a,u,sig) #Fitting y value
print(u'coefficient a:', a)
print(u'coefficient u:', u)
print(u'coefficient sig:', sig)

#mapping
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc=4) #Specify the lower right corner of the position of legend
plt.title('curve_fit')
plt.show()

Topics: Python